commit ff7c6a1531d9f16d27698d8c806e9cd7b54f6bbe Author: Wyatt Olson Date: Sat May 1 13:32:21 2010 -0600 Applied patch from Phil for hardcoded language fixes diff --git a/.hgignore b/.hgignore new file mode 100644 index 000000000..62f686c3d --- /dev/null +++ b/.hgignore @@ -0,0 +1,13 @@ +syntax: glob + +CMakeFiles +Makefile +cmake_install.cmake +CMakeCache.txt +rtgui/config.h +release +rtengine/librtengine.a +rtexif/librtexif.a +rtgui/rt +install_manifest.txt + diff --git a/AUTHORS.txt b/AUTHORS.txt new file mode 100644 index 000000000..6830e9047 --- /dev/null +++ b/AUTHORS.txt @@ -0,0 +1,9 @@ +Gabor Horvath + +Contributors (ideas, mockups, testing, forum activity, etc.): + +Patrik Brunner +Maciek Dworak +David M. Gyurko +Arturs Jekabsons +Karl Loncarek diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..a67151f21 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,122 @@ +cmake_minimum_required(VERSION 2.6) + +set (CMAKE_BUILD_TYPE Debug CACHE STRING "One of: None Debug Release RelWithDebInfo MinSizeRel.") + +if (APPLE) +# SET (CMAKE_OSX_ARCHITECTURES "i386;x86_64;" ) +# SET (CMAKE_TRY_COMPILE_OSX_ARCHITECTURES "i386;x86_64;" ) + SET (CMAKE_OSX_SYSROOT "/Developer/SDKs/MacOSX10.5.sdk") + SET (CMAKE_OSX_DEPLOYMENT_TARGET "10.5") +endif (APPLE) + +option (BUILD_SHARED "Build rawtherapee with shared libraries" OFF) +option (WITH_RAWZOR "Build with Rawzor support" OFF) + +# set install directories +if (NOT DEFINED DATADIR) + if (WIN32 OR APPLE) + set (DATADIR ${CMAKE_CURRENT_SOURCE_DIR}/release) + else (WIN32 OR APPLE) + set (DATADIR ${CMAKE_INSTALL_PREFIX}/share/rawtherapee) + endif (WIN32 OR APPLE) +endif (NOT DEFINED DATADIR) + +if (NOT DEFINED BINDIR) + if (WIN32 OR APPLE) + set (BINDIR ${CMAKE_CURRENT_SOURCE_DIR}/release) + else (WIN32 OR APPLE) + set (BINDIR ${CMAKE_INSTALL_PREFIX}/bin) + endif (WIN32 OR APPLE) +endif (NOT DEFINED BINDIR) + +if (NOT DEFINED LIBDIR) + if (WIN32 OR APPLE) + set (LIBDIR ${CMAKE_CURRENT_SOURCE_DIR}/release) + else (WIN32 OR APPLE) + set (LIBDIR ${CMAKE_INSTALL_PREFIX}/lib) + endif (WIN32 OR APPLE) +endif (NOT DEFINED LIBDIR) + +# check for libraries +find_package(PkgConfig) +pkg_check_modules (GTK REQUIRED gtk+-2.0>=2.12) +pkg_check_modules (GLIB2 REQUIRED glib-2.0>=2.16) +pkg_check_modules (GLIBMM REQUIRED glibmm-2.4>=2.16) +pkg_check_modules (GTKMM REQUIRED gtkmm-2.4>=2.12) +pkg_check_modules (GIO REQUIRED gio-2.0>=2.16) +pkg_check_modules (GIOMM REQUIRED giomm-2.4>=2.12) +pkg_check_modules (GTHREAD REQUIRED gthread-2.0>=2.16) +pkg_check_modules (GOBJECT REQUIRED gobject-2.0>=2.16) +pkg_check_modules (SIGC REQUIRED sigc++-2.0) +# NOTE: dependencies should be handled by pkg_check_modules and FIND_PACKAGE +# on windows too but I don't want to break current build chain +if (WIN32) + set (EXTRA_LIBDIR "${CMAKE_CURRENT_SOURCE_DIR}/lib") + set (EXTRA_INCDIR "${CMAKE_CURRENT_SOURCE_DIR}/winclude") + set (EXTRA_LIB "ws2_32") + set (IPTCDATA_LIBRARIES iptcdata) + set (LCMS_LIBRARIES liblcms.a) + set (JPEG_LIBRARIES libjpeg.a) + set (PNG_LIBRARIES libpng.a) + set (TIFF_LIBRARIES libtiff.a) + set (ZLIB_LIBRARIES libz.a) +else (WIN32) + pkg_check_modules (IPTCDATA REQUIRED libiptcdata) + pkg_check_modules (LCMS REQUIRED lcms) + find_package (JPEG REQUIRED) + find_package (PNG REQUIRED) + find_package (TIFF REQUIRED) + find_package (ZLIB REQUIRED) +endif (WIN32) + +# link rawzor +if (WITH_RAWZOR) + if (WIN32) + set (EXTRA_INCDIR ${EXTRA_INCDIR} "${CMAKE_CURRENT_SOURCE_DIR}/rawzor_win") + set (EXTRA_LIBDIR ${EXTRA_LIBDIR} "${CMAKE_CURRENT_SOURCE_DIR}/rawzor_win") + set (EXTRA_LIB ${EXTRA_LIB} "${CMAKE_CURRENT_SOURCE_DIR}/rawzor_win/rwz_sdk_s.a") + add_definitions (-DRAWZOR_SUPPORT) + install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/rawzor_win/rwz_sdk_s.dll DESTINATION ${BINDIR} + PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ) + elseif (APPLE) + set (EXTRA_INCDIR "${CMAKE_CURRENT_SOURCE_DIR}/rawzor_mac") + set (EXTRA_LIBDIR "${CMAKE_CURRENT_SOURCE_DIR}/rawzor_mac") + set (EXTRA_LIB "-lrwz_sdk_64") + add_definitions (-DRAWZOR_SUPPORT) + install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/rawzor_mac/librwz_sdk_64.dylib DESTINATION ${BINDIR} + PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ RENAME rwz_sdk_64.dylib) + if (BUILD_SHARED) + install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/rawzor_mac/librwz_sdk_64.dylib DESTINATION ${LIBDIR} + PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ RENAME rwz_sdk_64.dylib) + endif (BUILD_SHARED) + else (WIN32) + if (CMAKE_SIZEOF_VOID_P EQUAL 4) + set (EXTRA_INCDIR ${EXTRA_INCDIR} "${CMAKE_CURRENT_SOURCE_DIR}/rawzor_lin32") + set (EXTRA_LIBDIR ${EXTRA_LIBDIR} "${CMAKE_CURRENT_SOURCE_DIR}/rawzor_lin32") + set (EXTRA_LIB ${EXTRA_LIB} "-lrwz_sdk") + add_definitions (-DRAWZOR_SUPPORT) + install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/rawzor_lin32/librwz_sdk.so DESTINATION ${BINDIR} + PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ RENAME rwz_sdk.so) + if (BUILD_SHARED) + install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/rawzor_lin32/librwz_sdk.so DESTINATION ${LIBDIR} + PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ RENAME rwz_sdk.so) + endif (BUILD_SHARED) + elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) + set (EXTRA_INCDIR ${EXTRA_INCDIR} "${CMAKE_CURRENT_SOURCE_DIR}/rawzor_lin64") + set (EXTRA_LIBDIR ${EXTRA_LIBDIR} "${CMAKE_CURRENT_SOURCE_DIR}/rawzor_lin64") + set (EXTRA_LIB ${EXTRA_LIB} "-lrwz_sdk") + add_definitions (-DRAWZOR_SUPPORT) + install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/rawzor_lin64/librwz_sdk.so DESTINATION ${BINDIR} + PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ RENAME rwz_sdk.so) + if (BUILD_SHARED) + install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/rawzor_lin64/librwz_sdk.so DESTINATION ${LIBDIR} + PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ RENAME rwz_sdk.so) + endif (BUILD_SHARED) + endif (CMAKE_SIZEOF_VOID_P EQUAL 4) + endif (WIN32) +endif (WITH_RAWZOR) + +add_subdirectory (rtexif) +add_subdirectory (rtengine) +add_subdirectory (rtgui) +add_subdirectory (rtdata) diff --git a/COMPILE.txt b/COMPILE.txt new file mode 100644 index 000000000..a179f0f81 --- /dev/null +++ b/COMPILE.txt @@ -0,0 +1,57 @@ + +Windows +------- + +Requirements: +- MinGW + MSYS +- CMake +- GTK and GTKMM development environments + +Compile: +- Start MSYS +- Enter the root directory of the RawTherapee source tree +- Type: cmake -G "MSYS Makefiles" . +- Type: make install +- You find the compiled program in the release directory + +Linux +----- + +Requirements: +- CMake +- GTK and GTKMM development packages +- libtiff, libpng, libjpeg, lcms, libiptcdata development packages +- ...did I forget something? + +On Ubuntu/Debian the requirements can be installed by running: +sudo apt-get install build-essential cmake libgtk2.0-dev libgtkmm-2.4-dev libtiff-dev libpng-dev libjpeg-dev liblcms-dev libiptcdata-dev subversion + +Compile: +- Enter the root directory of the RawTherapee source tree +- Type: cmake . +- Type: make install +- You find the compiled program in the release directory (you can copy it +anywhere you want) + +...If you have problems with the compilation, identified the reason and fixed +the bug, please send me the updated build scripts (CMakeLists.txt files) to: +hgabor@rawtherapee.com + +OSX +--- + +Requirements: +- MacPorts + - Set /opt/local/etc/macports/variants.conf to include "+universal +no_x11 +quartz" (NOTE: as of this writing the Pango and Pango-devel ports are broken and will not build as Universal variants. Until this is fixed, leave the universal flag off.) + - Set /opt/local/etc/macports/macports.conf key 'universal_archs' to "i386 x86_64" + - Run "sudo port install cairomm pango-devel gtk2 cmake glibmm gtkmm lcms libiptcdata" to install all needed libraries +- XCode Development Tools (you only need a subset of these, but it is probably easier to just install all of them) + +Compile: +- Enter root directory of RawTherapee source tree +- Type: cmake . +- Type: make install +- Type: ./tools/osx/make-app-bundle +- You will find a RawTherapee.dmg file in release/ folder; this is the distribution release and can be run on any 10.5 or 10.6 Intel machine. + +For any bugs or patches to the OSX build, please contact Wyatt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 000000000..94a9ed024 --- /dev/null +++ b/LICENSE.txt @@ -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 +. diff --git a/clean.bat b/clean.bat new file mode 100755 index 000000000..2d6d5d5e7 --- /dev/null +++ b/clean.bat @@ -0,0 +1,17 @@ +del CMakeCache.txt +del install_manifest.txt +del ./CMakeFiles +del ./rtengine/CMakeFiles +rm -R ./rtexif/CMakeFiles +rm -R ./rtgui/CMakeFiles +rm ./cmake* +rm ./rtengine/cmake* +rm ./rtexif/cmake* +rm ./rtgui/cmake* +rm ./Makefile +rm ./rtengine/Makefile +rm ./rtexif/Makefile +rm ./rtgui/Makefile +rm ./rtengine/librtengine.so +rm ./rtgui/rth +rm ./rtexif/librtexif.a diff --git a/clean.sh b/clean.sh new file mode 100755 index 000000000..49630149f --- /dev/null +++ b/clean.sh @@ -0,0 +1,20 @@ +#!/bin/sh +rm CMakeCache.txt +rm install_manifest.txt +rm -R ./CMakeFiles +rm -R ./rtengine/CMakeFiles +rm -R ./rtexif/CMakeFiles +rm -R ./rtgui/CMakeFiles +rm -R ./rtdata/CMakeFiles +rm ./cmake* +rm ./rtengine/cmake* +rm ./rtexif/cmake* +rm ./rtgui/cmake* +rm ./rtdata/cmake* +rm ./Makefile +rm ./rtengine/Makefile +rm ./rtexif/Makefile +rm ./rtgui/Makefile +rm ./rtengine/librtengine.so +rm ./rtgui/rt +rm ./rtexif/librtexif.a diff --git a/doc/built/pdf/de/RT-Interner-Arbeitsablauf_2.4.pdf b/doc/built/pdf/de/RT-Interner-Arbeitsablauf_2.4.pdf new file mode 100644 index 000000000..e0856c8ba Binary files /dev/null and b/doc/built/pdf/de/RT-Interner-Arbeitsablauf_2.4.pdf differ diff --git a/doc/built/pdf/de/RawTherapeeHandbuch_2.4.pdf b/doc/built/pdf/de/RawTherapeeHandbuch_2.4.pdf new file mode 100644 index 000000000..9b0820010 Binary files /dev/null and b/doc/built/pdf/de/RawTherapeeHandbuch_2.4.pdf differ diff --git a/doc/built/pdf/en/RT-Internal-Workflow_2.4.pdf b/doc/built/pdf/en/RT-Internal-Workflow_2.4.pdf new file mode 100644 index 000000000..4614a1566 Binary files /dev/null and b/doc/built/pdf/en/RT-Internal-Workflow_2.4.pdf differ diff --git a/doc/built/pdf/en/RawTherapeeManual_2.4.pdf b/doc/built/pdf/en/RawTherapeeManual_2.4.pdf new file mode 100644 index 000000000..8639bd25c Binary files /dev/null and b/doc/built/pdf/en/RawTherapeeManual_2.4.pdf differ diff --git a/doc/built/pdf/fr/RAWTherapeeManuel_2.4_fr.pdf b/doc/built/pdf/fr/RAWTherapeeManuel_2.4_fr.pdf new file mode 100644 index 000000000..740518da3 Binary files /dev/null and b/doc/built/pdf/fr/RAWTherapeeManuel_2.4_fr.pdf differ diff --git a/doc/built/pdf/fr/RT-Flux de travail Interne_2.4_fr.pdf b/doc/built/pdf/fr/RT-Flux de travail Interne_2.4_fr.pdf new file mode 100644 index 000000000..fbc4c4219 Binary files /dev/null and b/doc/built/pdf/fr/RT-Flux de travail Interne_2.4_fr.pdf differ diff --git a/doc/built/pdf/it/RT-Internal-Workflow_2.4_it.pdf b/doc/built/pdf/it/RT-Internal-Workflow_2.4_it.pdf new file mode 100644 index 000000000..b0c05671e Binary files /dev/null and b/doc/built/pdf/it/RT-Internal-Workflow_2.4_it.pdf differ diff --git a/doc/built/pdf/it/RawTherapeeManual_2.4_it.pdf b/doc/built/pdf/it/RawTherapeeManual_2.4_it.pdf new file mode 100644 index 000000000..a8febe6b9 Binary files /dev/null and b/doc/built/pdf/it/RawTherapeeManual_2.4_it.pdf differ diff --git a/doc/built/pdf/ja/RawTherapeeManual_2.4_jp.pdf b/doc/built/pdf/ja/RawTherapeeManual_2.4_jp.pdf new file mode 100644 index 000000000..1a56dfec9 Binary files /dev/null and b/doc/built/pdf/ja/RawTherapeeManual_2.4_jp.pdf differ diff --git a/doc/built/pdf/nl/RawTherapeeManual_2.4.1_nl.pdf b/doc/built/pdf/nl/RawTherapeeManual_2.4.1_nl.pdf new file mode 100644 index 000000000..6619b3618 Binary files /dev/null and b/doc/built/pdf/nl/RawTherapeeManual_2.4.1_nl.pdf differ diff --git a/doc/source/odt/de/RT-Interner-Arbeitsablauf_2.4.odg b/doc/source/odt/de/RT-Interner-Arbeitsablauf_2.4.odg new file mode 100644 index 000000000..7fa3ab58a Binary files /dev/null and b/doc/source/odt/de/RT-Interner-Arbeitsablauf_2.4.odg differ diff --git a/doc/source/odt/de/RawTherapeeHandbuch_2.4.odt b/doc/source/odt/de/RawTherapeeHandbuch_2.4.odt new file mode 100644 index 000000000..ac1ce77f2 Binary files /dev/null and b/doc/source/odt/de/RawTherapeeHandbuch_2.4.odt differ diff --git a/doc/source/odt/fr/Manuel RAWTherapee_2.4_fr.odt b/doc/source/odt/fr/Manuel RAWTherapee_2.4_fr.odt new file mode 100644 index 000000000..fdd743b13 Binary files /dev/null and b/doc/source/odt/fr/Manuel RAWTherapee_2.4_fr.odt differ diff --git a/doc/source/odt/fr/RT-Flux de travail Interne_2.4_fr.odg b/doc/source/odt/fr/RT-Flux de travail Interne_2.4_fr.odg new file mode 100644 index 000000000..4ac7f2e8c Binary files /dev/null and b/doc/source/odt/fr/RT-Flux de travail Interne_2.4_fr.odg differ diff --git a/doc/source/odt/master/en/081021-RT-Internal-Workflow_2.4.odg b/doc/source/odt/master/en/081021-RT-Internal-Workflow_2.4.odg new file mode 100644 index 000000000..91b6212ad Binary files /dev/null and b/doc/source/odt/master/en/081021-RT-Internal-Workflow_2.4.odg differ diff --git a/doc/source/odt/master/en/090904-RawTherapeeManual_2.4.odt b/doc/source/odt/master/en/090904-RawTherapeeManual_2.4.odt new file mode 100644 index 000000000..96f88a0b3 Binary files /dev/null and b/doc/source/odt/master/en/090904-RawTherapeeManual_2.4.odt differ diff --git a/doc/source/odt/nl/RawTherapeeManual_2.4_1_Nederlands.odt b/doc/source/odt/nl/RawTherapeeManual_2.4_1_Nederlands.odt new file mode 100644 index 000000000..8f29841b4 Binary files /dev/null and b/doc/source/odt/nl/RawTherapeeManual_2.4_1_Nederlands.odt differ diff --git a/header b/header new file mode 100644 index 000000000..c887c8cb5 --- /dev/null +++ b/header @@ -0,0 +1,18 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ diff --git a/languagePack.nsi b/languagePack.nsi new file mode 100644 index 000000000..e9e6af5e6 --- /dev/null +++ b/languagePack.nsi @@ -0,0 +1,126 @@ +; RawTherapee Language Pack +; +; Installes just the language file in an existing RawTherapee installation. +; +;------------------------------------------------------------------------------ +; Name, Outputfile and Version information +;------------------------------------------------------------------------------ + +; **** start edit section: please adapt below options per language pack release **** +; The name of the installer +Name "RT 2.4.1 - language Pack" + +; The file to write +OutFile "RT241-langPack-20091018.exe" + +LoadLanguageFile "${NSISDIR}\Contrib\Language files\English.nlf" + + VIProductVersion "2.4.1.0" + VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "RawTherapee Language Pack" + VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "© Raw Therapee" + VIAddVersionKey /LANG=${LANG_ENGLISH} "FileDescription" "Language Pack RawTherapee 2.4.1" + VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "2.4.1-2009-10-18" + VIAddVersionKey /LANG=${LANG_ENGLISH} "Comments" "Compatible also for RT2.4 and RT2.3" +; VIAddVersionKey /LANG=${LANG_ENGLISH} "CompanyName" "Fake company" +; VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalTrademarks" "Test Application is a trademark of Fake company" + +; **** end edit section: no changes needed per release below **** + +;------------------------------------------------------------------------------ +; Installation Directory, Dialog box for +;------------------------------------------------------------------------------ + + +; The default installation directory +InstallDir "$PROGRAMFILES\Raw Therapee\languages" +DirText "The Language Pack has to be installed into the RawTherapee installation directory, into the language subdirectory." \ + "RawTherapee Installation Directory" \ + "" \ + "Please select the installation Directory of RawTherapee:" + +;PageEx directory +; DirVerify leave +; PageCallbacks "" "" dirLeave +;PageExEnd + +; Registry key to check for directory (so if you install again, it will +; overwrite the old one automatically) +InstallDirRegKey HKCU "Software\Raw Therapee" "" + +;------------------------------------------------------------------------------ +; Installation Rights (Vista only) +;------------------------------------------------------------------------------ + +; Request application privileges for Windows Vista +RequestExecutionLevel admin + + +;------------------------------------------------------------------------------ +; Pages: +;------------------------------------------------------------------------------ + +; Pages + +;Page components +Page directory +Page instfiles + +;UninstPage uninstConfirm +;UninstPage instfiles + +;------------------------------------------------------------------------------ +; Sections: stuff to be installed +;------------------------------------------------------------------------------ + +; The stuff to install +Section "RawTherapee Language Pack (required)" + + SectionIn RO + + ifFileExists $INSTDIR\languages\*.* 0 +3 + SetOutPath $INSTDIR\languages + Goto +2 + SetOutPath $INSTDIR + + ; Set output path to the installation directory. + ;SetOutPath $INSTDIR + + ; Put file there + File "release\languages\*" + + ; Write the installation path into the registry + ;WriteRegStr HKLM SOFTWARE\NSIS_Example2 "Install_Dir" "$INSTDIR" + + ; Write the uninstall keys for Windows + ;WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Example2" "DisplayName" "NSIS Example2" + ;WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Example2" "UninstallString" '"$INSTDIR\uninstall.exe"' + ;WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Example2" "NoModify" 1 + ;WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Example2" "NoRepair" 1 + ;WriteUninstaller "uninstall.exe" + +SectionEnd + +;------------------------------------------------------------------------------ +; Uninstaller: not needed here +;------------------------------------------------------------------------------ + +; Uninstaller + +;Section "Uninstall" + + ; Remove registry keys +; DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Example2" +; DeleteRegKey HKLM SOFTWARE\NSIS_Example2 + + ; Remove files and uninstaller +; Delete $INSTDIR\example2.nsi +; Delete $INSTDIR\uninstall.exe + + ; Remove shortcuts, if any +; Delete "$SMPROGRAMS\Example2\*.*" + + ; Remove directories used +; RMDir "$SMPROGRAMS\Example2" +; RMDir "$INSTDIR" + +;SectionEnd diff --git a/lib/libiptcdata.a b/lib/libiptcdata.a new file mode 100755 index 000000000..311687c60 Binary files /dev/null and b/lib/libiptcdata.a differ diff --git a/lib/libjpeg.a b/lib/libjpeg.a new file mode 100755 index 000000000..27431b938 Binary files /dev/null and b/lib/libjpeg.a differ diff --git a/lib/liblcms.a b/lib/liblcms.a new file mode 100755 index 000000000..2d44b534d Binary files /dev/null and b/lib/liblcms.a differ diff --git a/lib/libpng.a b/lib/libpng.a new file mode 100755 index 000000000..e73b93c15 Binary files /dev/null and b/lib/libpng.a differ diff --git a/lib/libtiff.a b/lib/libtiff.a new file mode 100755 index 000000000..e67da3391 Binary files /dev/null and b/lib/libtiff.a differ diff --git a/lib/libz.a b/lib/libz.a new file mode 100755 index 000000000..86f2f0513 Binary files /dev/null and b/lib/libz.a differ diff --git a/lib/readme.txt b/lib/readme.txt new file mode 100755 index 000000000..9a7bce67e --- /dev/null +++ b/lib/readme.txt @@ -0,0 +1,2 @@ +These files are precompiled libraries for windows. The corresponding +header files are in the winclude directory. diff --git a/rawzor_lin32/librwz_sdk.so b/rawzor_lin32/librwz_sdk.so new file mode 100755 index 000000000..c6dd8f6f0 Binary files /dev/null and b/rawzor_lin32/librwz_sdk.so differ diff --git a/rawzor_lin32/rwz_sdk.h b/rawzor_lin32/rwz_sdk.h new file mode 100755 index 000000000..ac5dbcf71 --- /dev/null +++ b/rawzor_lin32/rwz_sdk.h @@ -0,0 +1,81 @@ +//Copyright (c)2008 Sachin Garg. All Rights Reserved. +//http://www.rawzor.com/ sachingarg@rawzor.com + +#ifndef _rawzor_sdk_pub_h +#define _rawzor_sdk_pub_h + +#ifdef _MSC_VER + #ifdef __export + #define _declspec __declspec(dllexport) + #else + #define _declspec + #endif +#else + #ifdef __export + #define _declspec __attribute__ ((visibility("default"),cdecl)) + #else + #define _declspec __attribute__ ((cdecl)) + #endif + #define __cdecl +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Checks if the file loaded in 'data' is a valid rawzor compressed + file that this version of rawzor can decompress. If the file can + be decompressed returns 0, a positive error code on error. + Also gets size of uncompressed raw file. + + NOTE: You don't have to load the entire rwz file in memory just to check + that if its a valid rwz file. This function needs only first 50 bytes, + set rwz_size to size of memory buffer. + + 1 Not a rwz compressed file + 2 A rwz file that needs a newer version of rawzor SDK to decompress + (>2 means other errors) +*/ +_declspec int __cdecl m_rwz_check(char *rwz_data,int rwz_size, int *raw_size); + + +/* Decompress a rzw file to get the uncompressed raw image file. + Returns 0 on success, a positive error code on error. +*/ +_declspec int __cdecl m_rwz_decompress(char *rwz_data,int rwz_size,char *raw_data,int raw_size); + + +/* Decompress only the raw image's meta data. Recreates the original raw file + except the raw pixel data and the embedded thumbnail. Use this function to + get quick access to raw file's meta information when the application + doesn't needs access to pixel data or thumbnail. + + Returns 0 on success, a positive error code on error. +*/ +_declspec int __cdecl m_rwz_get_meta_only(char *rwz_data,int rwz_size,char *raw_data,int raw_size); + + +/* Decompress only the raw image's meta data and embedded thumbnail (if any). + Recreates the original raw file including the embedded thumbnail but except + the raw pixel data. Use this function to get quick access to raw file's + meta information or thumbnail when the application doesn't needs access to + raw pixel data. + + Returns 0 on success, a positive error code on error. +*/ +_declspec int __cdecl m_rwz_get_meta_and_thumbnail(char *rwz_data,int rwz_size,char *raw_data,int raw_size); + + +/* Returns the version of SDK core. Can be used for diagnostics or to + verify compatibility with SDK when manually parsing .rwz files. + + SDK cannot open .rwz files which need a newer version of SDK, this is + also checked by m_rwz_check above. +*/ +_declspec int __cdecl rwz_sdk_get_max_version(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rawzor_lin64/librwz_sdk.so b/rawzor_lin64/librwz_sdk.so new file mode 100755 index 000000000..9f07a845d Binary files /dev/null and b/rawzor_lin64/librwz_sdk.so differ diff --git a/rawzor_lin64/rwz_sdk.h b/rawzor_lin64/rwz_sdk.h new file mode 100755 index 000000000..ac5dbcf71 --- /dev/null +++ b/rawzor_lin64/rwz_sdk.h @@ -0,0 +1,81 @@ +//Copyright (c)2008 Sachin Garg. All Rights Reserved. +//http://www.rawzor.com/ sachingarg@rawzor.com + +#ifndef _rawzor_sdk_pub_h +#define _rawzor_sdk_pub_h + +#ifdef _MSC_VER + #ifdef __export + #define _declspec __declspec(dllexport) + #else + #define _declspec + #endif +#else + #ifdef __export + #define _declspec __attribute__ ((visibility("default"),cdecl)) + #else + #define _declspec __attribute__ ((cdecl)) + #endif + #define __cdecl +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Checks if the file loaded in 'data' is a valid rawzor compressed + file that this version of rawzor can decompress. If the file can + be decompressed returns 0, a positive error code on error. + Also gets size of uncompressed raw file. + + NOTE: You don't have to load the entire rwz file in memory just to check + that if its a valid rwz file. This function needs only first 50 bytes, + set rwz_size to size of memory buffer. + + 1 Not a rwz compressed file + 2 A rwz file that needs a newer version of rawzor SDK to decompress + (>2 means other errors) +*/ +_declspec int __cdecl m_rwz_check(char *rwz_data,int rwz_size, int *raw_size); + + +/* Decompress a rzw file to get the uncompressed raw image file. + Returns 0 on success, a positive error code on error. +*/ +_declspec int __cdecl m_rwz_decompress(char *rwz_data,int rwz_size,char *raw_data,int raw_size); + + +/* Decompress only the raw image's meta data. Recreates the original raw file + except the raw pixel data and the embedded thumbnail. Use this function to + get quick access to raw file's meta information when the application + doesn't needs access to pixel data or thumbnail. + + Returns 0 on success, a positive error code on error. +*/ +_declspec int __cdecl m_rwz_get_meta_only(char *rwz_data,int rwz_size,char *raw_data,int raw_size); + + +/* Decompress only the raw image's meta data and embedded thumbnail (if any). + Recreates the original raw file including the embedded thumbnail but except + the raw pixel data. Use this function to get quick access to raw file's + meta information or thumbnail when the application doesn't needs access to + raw pixel data. + + Returns 0 on success, a positive error code on error. +*/ +_declspec int __cdecl m_rwz_get_meta_and_thumbnail(char *rwz_data,int rwz_size,char *raw_data,int raw_size); + + +/* Returns the version of SDK core. Can be used for diagnostics or to + verify compatibility with SDK when manually parsing .rwz files. + + SDK cannot open .rwz files which need a newer version of SDK, this is + also checked by m_rwz_check above. +*/ +_declspec int __cdecl rwz_sdk_get_max_version(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rawzor_mac/librwz_sdk_64.dylib b/rawzor_mac/librwz_sdk_64.dylib new file mode 100755 index 000000000..cd1331686 Binary files /dev/null and b/rawzor_mac/librwz_sdk_64.dylib differ diff --git a/rawzor_mac/rwz_sdk.h b/rawzor_mac/rwz_sdk.h new file mode 100644 index 000000000..ac5dbcf71 --- /dev/null +++ b/rawzor_mac/rwz_sdk.h @@ -0,0 +1,81 @@ +//Copyright (c)2008 Sachin Garg. All Rights Reserved. +//http://www.rawzor.com/ sachingarg@rawzor.com + +#ifndef _rawzor_sdk_pub_h +#define _rawzor_sdk_pub_h + +#ifdef _MSC_VER + #ifdef __export + #define _declspec __declspec(dllexport) + #else + #define _declspec + #endif +#else + #ifdef __export + #define _declspec __attribute__ ((visibility("default"),cdecl)) + #else + #define _declspec __attribute__ ((cdecl)) + #endif + #define __cdecl +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Checks if the file loaded in 'data' is a valid rawzor compressed + file that this version of rawzor can decompress. If the file can + be decompressed returns 0, a positive error code on error. + Also gets size of uncompressed raw file. + + NOTE: You don't have to load the entire rwz file in memory just to check + that if its a valid rwz file. This function needs only first 50 bytes, + set rwz_size to size of memory buffer. + + 1 Not a rwz compressed file + 2 A rwz file that needs a newer version of rawzor SDK to decompress + (>2 means other errors) +*/ +_declspec int __cdecl m_rwz_check(char *rwz_data,int rwz_size, int *raw_size); + + +/* Decompress a rzw file to get the uncompressed raw image file. + Returns 0 on success, a positive error code on error. +*/ +_declspec int __cdecl m_rwz_decompress(char *rwz_data,int rwz_size,char *raw_data,int raw_size); + + +/* Decompress only the raw image's meta data. Recreates the original raw file + except the raw pixel data and the embedded thumbnail. Use this function to + get quick access to raw file's meta information when the application + doesn't needs access to pixel data or thumbnail. + + Returns 0 on success, a positive error code on error. +*/ +_declspec int __cdecl m_rwz_get_meta_only(char *rwz_data,int rwz_size,char *raw_data,int raw_size); + + +/* Decompress only the raw image's meta data and embedded thumbnail (if any). + Recreates the original raw file including the embedded thumbnail but except + the raw pixel data. Use this function to get quick access to raw file's + meta information or thumbnail when the application doesn't needs access to + raw pixel data. + + Returns 0 on success, a positive error code on error. +*/ +_declspec int __cdecl m_rwz_get_meta_and_thumbnail(char *rwz_data,int rwz_size,char *raw_data,int raw_size); + + +/* Returns the version of SDK core. Can be used for diagnostics or to + verify compatibility with SDK when manually parsing .rwz files. + + SDK cannot open .rwz files which need a newer version of SDK, this is + also checked by m_rwz_check above. +*/ +_declspec int __cdecl rwz_sdk_get_max_version(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rawzor_win/makeimp.bat b/rawzor_win/makeimp.bat new file mode 100755 index 000000000..b1b8c4e75 --- /dev/null +++ b/rawzor_win/makeimp.bat @@ -0,0 +1,2 @@ +pexports.exe rwz_sdk_s.dll >rwz_sdk_s.def +dlltool -D ./rwz_sdk_s.dll -d rwz_sdk_s.def -l rwz_sdk_s.a \ No newline at end of file diff --git a/rawzor_win/rwz_sdk.h b/rawzor_win/rwz_sdk.h new file mode 100755 index 000000000..ac5dbcf71 --- /dev/null +++ b/rawzor_win/rwz_sdk.h @@ -0,0 +1,81 @@ +//Copyright (c)2008 Sachin Garg. All Rights Reserved. +//http://www.rawzor.com/ sachingarg@rawzor.com + +#ifndef _rawzor_sdk_pub_h +#define _rawzor_sdk_pub_h + +#ifdef _MSC_VER + #ifdef __export + #define _declspec __declspec(dllexport) + #else + #define _declspec + #endif +#else + #ifdef __export + #define _declspec __attribute__ ((visibility("default"),cdecl)) + #else + #define _declspec __attribute__ ((cdecl)) + #endif + #define __cdecl +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Checks if the file loaded in 'data' is a valid rawzor compressed + file that this version of rawzor can decompress. If the file can + be decompressed returns 0, a positive error code on error. + Also gets size of uncompressed raw file. + + NOTE: You don't have to load the entire rwz file in memory just to check + that if its a valid rwz file. This function needs only first 50 bytes, + set rwz_size to size of memory buffer. + + 1 Not a rwz compressed file + 2 A rwz file that needs a newer version of rawzor SDK to decompress + (>2 means other errors) +*/ +_declspec int __cdecl m_rwz_check(char *rwz_data,int rwz_size, int *raw_size); + + +/* Decompress a rzw file to get the uncompressed raw image file. + Returns 0 on success, a positive error code on error. +*/ +_declspec int __cdecl m_rwz_decompress(char *rwz_data,int rwz_size,char *raw_data,int raw_size); + + +/* Decompress only the raw image's meta data. Recreates the original raw file + except the raw pixel data and the embedded thumbnail. Use this function to + get quick access to raw file's meta information when the application + doesn't needs access to pixel data or thumbnail. + + Returns 0 on success, a positive error code on error. +*/ +_declspec int __cdecl m_rwz_get_meta_only(char *rwz_data,int rwz_size,char *raw_data,int raw_size); + + +/* Decompress only the raw image's meta data and embedded thumbnail (if any). + Recreates the original raw file including the embedded thumbnail but except + the raw pixel data. Use this function to get quick access to raw file's + meta information or thumbnail when the application doesn't needs access to + raw pixel data. + + Returns 0 on success, a positive error code on error. +*/ +_declspec int __cdecl m_rwz_get_meta_and_thumbnail(char *rwz_data,int rwz_size,char *raw_data,int raw_size); + + +/* Returns the version of SDK core. Can be used for diagnostics or to + verify compatibility with SDK when manually parsing .rwz files. + + SDK cannot open .rwz files which need a newer version of SDK, this is + also checked by m_rwz_check above. +*/ +_declspec int __cdecl rwz_sdk_get_max_version(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rawzor_win/rwz_sdk_s.a b/rawzor_win/rwz_sdk_s.a new file mode 100755 index 000000000..30eb551d8 Binary files /dev/null and b/rawzor_win/rwz_sdk_s.a differ diff --git a/rawzor_win/rwz_sdk_s.def b/rawzor_win/rwz_sdk_s.def new file mode 100755 index 000000000..f2313db92 --- /dev/null +++ b/rawzor_win/rwz_sdk_s.def @@ -0,0 +1,7 @@ +LIBRARY rwz_sdk_s.dll +EXPORTS +m_rwz_check +m_rwz_decompress +m_rwz_get_meta_and_thumbnail +m_rwz_get_meta_only +rwz_sdk_get_max_version diff --git a/rawzor_win/rwz_sdk_s.dll b/rawzor_win/rwz_sdk_s.dll new file mode 100755 index 000000000..13c5d24f9 Binary files /dev/null and b/rawzor_win/rwz_sdk_s.dll differ diff --git a/rawzor_win/rwz_sdk_s.lib b/rawzor_win/rwz_sdk_s.lib new file mode 100755 index 000000000..6e5f96961 Binary files /dev/null and b/rawzor_win/rwz_sdk_s.lib differ diff --git a/rtdata/CMakeLists.txt b/rtdata/CMakeLists.txt new file mode 100644 index 000000000..023388934 --- /dev/null +++ b/rtdata/CMakeLists.txt @@ -0,0 +1,22 @@ + +file (GLOB IMAGEFILES "images/*.png") +file (GLOB PROFILEFILES "profiles/*.pp2") +file (GLOB LANGUAGEFILES "languages/*") +# THEMEDIR includes subfolders for image resources for some themes; doing the normal glob won't work. +set (THEMEDIR "themes") + +if (WIN32) + set(OPTIONSFILE "options/options.win") +elseif (APPLE) + set(OPTIONSFILE "options/options.osx") +else (WIN32) + set(OPTIONSFILE "options/options.lin") +endif (WIN32) + + +install (FILES ${IMAGEFILES} DESTINATION ${DATADIR}/images) +install (FILES ${LANGUAGEFILES} DESTINATION ${DATADIR}/languages) +install (FILES ${PROFILEFILES} DESTINATION ${DATADIR}/profiles) +install (DIRECTORY ${THEMEDIR} DESTINATION ${DATADIR}) +install (FILES ${OPTIONSFILE} DESTINATION ${DATADIR} PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ RENAME options) + diff --git a/rtdata/images/addtagl.png b/rtdata/images/addtagl.png new file mode 100644 index 000000000..b8520b7d8 Binary files /dev/null and b/rtdata/images/addtagl.png differ diff --git a/rtdata/images/addtags.png b/rtdata/images/addtags.png new file mode 100644 index 000000000..3241084e4 Binary files /dev/null and b/rtdata/images/addtags.png differ diff --git a/rtdata/images/cdrom.png b/rtdata/images/cdrom.png new file mode 100644 index 000000000..d27facd69 Binary files /dev/null and b/rtdata/images/cdrom.png differ diff --git a/rtdata/images/closedhand22.png b/rtdata/images/closedhand22.png new file mode 100644 index 000000000..d4b275d2d Binary files /dev/null and b/rtdata/images/closedhand22.png differ diff --git a/rtdata/images/crop16.png b/rtdata/images/crop16.png new file mode 100644 index 000000000..5184119c8 Binary files /dev/null and b/rtdata/images/crop16.png differ diff --git a/rtdata/images/crop22.png b/rtdata/images/crop22.png new file mode 100644 index 000000000..5e6af5f82 Binary files /dev/null and b/rtdata/images/crop22.png differ diff --git a/rtdata/images/deltagl.png b/rtdata/images/deltagl.png new file mode 100644 index 000000000..694043073 Binary files /dev/null and b/rtdata/images/deltagl.png differ diff --git a/rtdata/images/deltags.png b/rtdata/images/deltags.png new file mode 100644 index 000000000..4a6d480ed Binary files /dev/null and b/rtdata/images/deltags.png differ diff --git a/rtdata/images/deltags.pp2 b/rtdata/images/deltags.pp2 new file mode 100644 index 000000000..f9dbf95df --- /dev/null +++ b/rtdata/images/deltags.pp2 @@ -0,0 +1,124 @@ + +[Version] +Version=231 + +[Exposure] +Auto=false +Clip=0.002 +Compensation=0 +Brightness=0 +Contrast=0 +Black=0 +HighlightCompr=85 +ShadowCompr=85 +Curve= + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Black=0 +HighlightCompr=0 +ShadowCompr=0 +Curve= + +[Sharpening] +Enabled=true +Method=usm +Radius=1 +Amount=90 +Threshold=768 +OnlyEdges=false +EdgedetectionRadius=3 +EdgeTolerance=1000 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Color Boost] +ChannelA=0 +ChannelB=0 +AvoidColorClipping=false +SaturationLimiter=false +SaturationLimit=50 + +[White Balance] +Setting=Camera +Temperature=6504 +Green=1.0009615390996527 + +[Color Shift] +ChannelA=0 +ChannelB=0 + +[Luminance Denoising] +Enabled=false +Radius=1.8999999999999999 +EdgeTolerance=2000 + +[Chrominance Denoising] +Enabled=false +EdgeSensitive=false +Radius=1.8999999999999999 +EdgeTolerance=2000 + +[Shadows & Highlights] +Enabled=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=15 +Radius=40 + +[Crop] +Enabled=false +X=-1 +Y=-1 +W=15000 +H=15000 +FixedRatio=false +Ratio=3:2 +Orientation=Landscape +Guide=None + +[Coarse Transformation] +Rotate=0 +HorizontalFlip=false +VerticalFlip=false + +[Rotation] +Degree=0 +Fill=1 + +[Distortion] +Amount=0 + +[CACorrection] +Red=0 +Blue=0 + +[Vignetting Correction] +Amount=0 +Radius=50 + +[HLRecovery] +Enabled=false +Method=Luminance + +[Resize] +Scale=1 +Method=Bicubic + +[Color Management] +InputProfile= +ApplyGammaBeforeInputProfile=false +WorkingProfile=sRGB +OutputProfile=sRGB diff --git a/rtdata/images/down.png b/rtdata/images/down.png new file mode 100644 index 000000000..61be34066 Binary files /dev/null and b/rtdata/images/down.png differ diff --git a/rtdata/images/edited.png b/rtdata/images/edited.png new file mode 100644 index 000000000..bbc0dae98 Binary files /dev/null and b/rtdata/images/edited.png differ diff --git a/rtdata/images/fileopen.png b/rtdata/images/fileopen.png new file mode 100644 index 000000000..dad846ba0 Binary files /dev/null and b/rtdata/images/fileopen.png differ diff --git a/rtdata/images/filesave.png b/rtdata/images/filesave.png new file mode 100644 index 000000000..3eec2240c Binary files /dev/null and b/rtdata/images/filesave.png differ diff --git a/rtdata/images/filter.png b/rtdata/images/filter.png new file mode 100644 index 000000000..d21c939a9 Binary files /dev/null and b/rtdata/images/filter.png differ diff --git a/rtdata/images/flame22.png b/rtdata/images/flame22.png new file mode 100644 index 000000000..a1029fc86 Binary files /dev/null and b/rtdata/images/flame22.png differ diff --git a/rtdata/images/floppy.png b/rtdata/images/floppy.png new file mode 100644 index 000000000..a54bd6128 Binary files /dev/null and b/rtdata/images/floppy.png differ diff --git a/rtdata/images/folder.png b/rtdata/images/folder.png new file mode 100644 index 000000000..c00eb2c48 Binary files /dev/null and b/rtdata/images/folder.png differ diff --git a/rtdata/images/folder_open.png b/rtdata/images/folder_open.png new file mode 100644 index 000000000..d6e35020d Binary files /dev/null and b/rtdata/images/folder_open.png differ diff --git a/rtdata/images/folder_open_r.png b/rtdata/images/folder_open_r.png new file mode 100644 index 000000000..9e523b696 Binary files /dev/null and b/rtdata/images/folder_open_r.png differ diff --git a/rtdata/images/folder_orange.png b/rtdata/images/folder_orange.png new file mode 100644 index 000000000..db12f5cfb Binary files /dev/null and b/rtdata/images/folder_orange.png differ diff --git a/rtdata/images/folder_orange_open.png b/rtdata/images/folder_orange_open.png new file mode 100644 index 000000000..bc2086890 Binary files /dev/null and b/rtdata/images/folder_orange_open.png differ diff --git a/rtdata/images/folder_r.png b/rtdata/images/folder_r.png new file mode 100644 index 000000000..3f7d2a6aa Binary files /dev/null and b/rtdata/images/folder_r.png differ diff --git a/rtdata/images/gimp.png b/rtdata/images/gimp.png new file mode 100644 index 000000000..e57f56fe1 Binary files /dev/null and b/rtdata/images/gimp.png differ diff --git a/rtdata/images/grayrated.png b/rtdata/images/grayrated.png new file mode 100644 index 000000000..d3580ca82 Binary files /dev/null and b/rtdata/images/grayrated.png differ diff --git a/rtdata/images/green.png b/rtdata/images/green.png new file mode 100644 index 000000000..baad6202c Binary files /dev/null and b/rtdata/images/green.png differ diff --git a/rtdata/images/gtk-close.png b/rtdata/images/gtk-close.png new file mode 100644 index 000000000..52f58630f Binary files /dev/null and b/rtdata/images/gtk-close.png differ diff --git a/rtdata/images/gtk-undo-ltr-big.png b/rtdata/images/gtk-undo-ltr-big.png new file mode 100644 index 000000000..68545f6b1 Binary files /dev/null and b/rtdata/images/gtk-undo-ltr-big.png differ diff --git a/rtdata/images/gtk-undo-ltr.png b/rtdata/images/gtk-undo-ltr.png new file mode 100644 index 000000000..56cc85f52 Binary files /dev/null and b/rtdata/images/gtk-undo-ltr.png differ diff --git a/rtdata/images/gtk-zoom-100.png b/rtdata/images/gtk-zoom-100.png new file mode 100644 index 000000000..92dddd2ea Binary files /dev/null and b/rtdata/images/gtk-zoom-100.png differ diff --git a/rtdata/images/gtk-zoom-fit.png b/rtdata/images/gtk-zoom-fit.png new file mode 100644 index 000000000..adbf7f3a2 Binary files /dev/null and b/rtdata/images/gtk-zoom-fit.png differ diff --git a/rtdata/images/gtk-zoom-in.png b/rtdata/images/gtk-zoom-in.png new file mode 100644 index 000000000..6b1b94336 Binary files /dev/null and b/rtdata/images/gtk-zoom-in.png differ diff --git a/rtdata/images/gtk-zoom-out.png b/rtdata/images/gtk-zoom-out.png new file mode 100644 index 000000000..ddc1eb136 Binary files /dev/null and b/rtdata/images/gtk-zoom-out.png differ diff --git a/rtdata/images/hdd.png b/rtdata/images/hdd.png new file mode 100644 index 000000000..decc5f350 Binary files /dev/null and b/rtdata/images/hdd.png differ diff --git a/rtdata/images/head.png b/rtdata/images/head.png new file mode 100644 index 000000000..29b5b934a Binary files /dev/null and b/rtdata/images/head.png differ diff --git a/rtdata/images/horizontal.png b/rtdata/images/horizontal.png new file mode 100644 index 000000000..7f6512f6b Binary files /dev/null and b/rtdata/images/horizontal.png differ diff --git a/rtdata/images/horizontals.png b/rtdata/images/horizontals.png new file mode 100644 index 000000000..25aadb8b8 Binary files /dev/null and b/rtdata/images/horizontals.png differ diff --git a/rtdata/images/icon-gears.png b/rtdata/images/icon-gears.png new file mode 100644 index 000000000..0d39b4b3f Binary files /dev/null and b/rtdata/images/icon-gears.png differ diff --git a/rtdata/images/info.png b/rtdata/images/info.png new file mode 100644 index 000000000..22cd5420a Binary files /dev/null and b/rtdata/images/info.png differ diff --git a/rtdata/images/left.png b/rtdata/images/left.png new file mode 100644 index 000000000..0a6571ae0 Binary files /dev/null and b/rtdata/images/left.png differ diff --git a/rtdata/images/list-add.png b/rtdata/images/list-add.png new file mode 100644 index 000000000..1aa7f095c Binary files /dev/null and b/rtdata/images/list-add.png differ diff --git a/rtdata/images/list-add12.png b/rtdata/images/list-add12.png new file mode 100644 index 000000000..cdca72893 Binary files /dev/null and b/rtdata/images/list-add12.png differ diff --git a/rtdata/images/list-remove.png b/rtdata/images/list-remove.png new file mode 100644 index 000000000..00b654e8c Binary files /dev/null and b/rtdata/images/list-remove.png differ diff --git a/rtdata/images/list-remove12r.png b/rtdata/images/list-remove12r.png new file mode 100644 index 000000000..dc12f415d Binary files /dev/null and b/rtdata/images/list-remove12r.png differ diff --git a/rtdata/images/logoicon16.png b/rtdata/images/logoicon16.png new file mode 100644 index 000000000..91aa647bf Binary files /dev/null and b/rtdata/images/logoicon16.png differ diff --git a/rtdata/images/logoicon16b.png b/rtdata/images/logoicon16b.png new file mode 100644 index 000000000..2eb641222 Binary files /dev/null and b/rtdata/images/logoicon16b.png differ diff --git a/rtdata/images/logoicon32.png b/rtdata/images/logoicon32.png new file mode 100644 index 000000000..3639139da Binary files /dev/null and b/rtdata/images/logoicon32.png differ diff --git a/rtdata/images/network.png b/rtdata/images/network.png new file mode 100644 index 000000000..7fcdf8e46 Binary files /dev/null and b/rtdata/images/network.png differ diff --git a/rtdata/images/notrated.png b/rtdata/images/notrated.png new file mode 100644 index 000000000..cd6d36e28 Binary files /dev/null and b/rtdata/images/notrated.png differ diff --git a/rtdata/images/openhand.png b/rtdata/images/openhand.png new file mode 100644 index 000000000..9fb695def Binary files /dev/null and b/rtdata/images/openhand.png differ diff --git a/rtdata/images/openhand22.png b/rtdata/images/openhand22.png new file mode 100644 index 000000000..e87604e77 Binary files /dev/null and b/rtdata/images/openhand22.png differ diff --git a/rtdata/images/processing.png b/rtdata/images/processing.png new file mode 100644 index 000000000..33e8c4ed7 Binary files /dev/null and b/rtdata/images/processing.png differ diff --git a/rtdata/images/rated.png b/rtdata/images/rated.png new file mode 100644 index 000000000..07a8a95f1 Binary files /dev/null and b/rtdata/images/rated.png differ diff --git a/rtdata/images/red.png b/rtdata/images/red.png new file mode 100644 index 000000000..a95830d23 Binary files /dev/null and b/rtdata/images/red.png differ diff --git a/rtdata/images/resize.png b/rtdata/images/resize.png new file mode 100644 index 000000000..835344479 Binary files /dev/null and b/rtdata/images/resize.png differ diff --git a/rtdata/images/saved.png b/rtdata/images/saved.png new file mode 100644 index 000000000..556a93fb5 Binary files /dev/null and b/rtdata/images/saved.png differ diff --git a/rtdata/images/splash.png b/rtdata/images/splash.png new file mode 100644 index 000000000..3eeae46c8 Binary files /dev/null and b/rtdata/images/splash.png differ diff --git a/rtdata/images/stock-color-picker-gray-18.png b/rtdata/images/stock-color-picker-gray-18.png new file mode 100644 index 000000000..9236fa1c7 Binary files /dev/null and b/rtdata/images/stock-color-picker-gray-18.png differ diff --git a/rtdata/images/stock-flip-horizontal-16.png b/rtdata/images/stock-flip-horizontal-16.png new file mode 100644 index 000000000..249c125c2 Binary files /dev/null and b/rtdata/images/stock-flip-horizontal-16.png differ diff --git a/rtdata/images/stock-flip-vertical-16.png b/rtdata/images/stock-flip-vertical-16.png new file mode 100644 index 000000000..586a5547b Binary files /dev/null and b/rtdata/images/stock-flip-vertical-16.png differ diff --git a/rtdata/images/stock-resize-16.png b/rtdata/images/stock-resize-16.png new file mode 100644 index 000000000..4666f5680 Binary files /dev/null and b/rtdata/images/stock-resize-16.png differ diff --git a/rtdata/images/stock-rotate-270-16.png b/rtdata/images/stock-rotate-270-16.png new file mode 100644 index 000000000..cbe3ef8bf Binary files /dev/null and b/rtdata/images/stock-rotate-270-16.png differ diff --git a/rtdata/images/stock-rotate-90-16.png b/rtdata/images/stock-rotate-90-16.png new file mode 100644 index 000000000..cdac3bcd9 Binary files /dev/null and b/rtdata/images/stock-rotate-90-16.png differ diff --git a/rtdata/images/stock-tool-color-picker-22.png b/rtdata/images/stock-tool-color-picker-22.png new file mode 100644 index 000000000..f9d1943ea Binary files /dev/null and b/rtdata/images/stock-tool-color-picker-22.png differ diff --git a/rtdata/images/stock-tool-crop-16.png b/rtdata/images/stock-tool-crop-16.png new file mode 100644 index 000000000..da6afcf85 Binary files /dev/null and b/rtdata/images/stock-tool-crop-16.png differ diff --git a/rtdata/images/stock-tool-crop-22.png b/rtdata/images/stock-tool-crop-22.png new file mode 100644 index 000000000..cf23381b8 Binary files /dev/null and b/rtdata/images/stock-tool-crop-22.png differ diff --git a/rtdata/images/stock_clear_24.png b/rtdata/images/stock_clear_24.png new file mode 100644 index 000000000..96b6d57dd Binary files /dev/null and b/rtdata/images/stock_clear_24.png differ diff --git a/rtdata/images/stock_down_arrow_24.png b/rtdata/images/stock_down_arrow_24.png new file mode 100644 index 000000000..ce290ba8d Binary files /dev/null and b/rtdata/images/stock_down_arrow_24.png differ diff --git a/rtdata/images/stock_left_arrow_24.png b/rtdata/images/stock_left_arrow_24.png new file mode 100644 index 000000000..c60eb07c1 Binary files /dev/null and b/rtdata/images/stock_left_arrow_24.png differ diff --git a/rtdata/images/stock_right_arrow_24.png b/rtdata/images/stock_right_arrow_24.png new file mode 100644 index 000000000..1a2162688 Binary files /dev/null and b/rtdata/images/stock_right_arrow_24.png differ diff --git a/rtdata/images/stock_up_arrow_24.png b/rtdata/images/stock_up_arrow_24.png new file mode 100644 index 000000000..493e14966 Binary files /dev/null and b/rtdata/images/stock_up_arrow_24.png differ diff --git a/rtdata/images/straighten16.png b/rtdata/images/straighten16.png new file mode 100644 index 000000000..06ed43f2b Binary files /dev/null and b/rtdata/images/straighten16.png differ diff --git a/rtdata/images/straighten22.png b/rtdata/images/straighten22.png new file mode 100644 index 000000000..9b07b6234 Binary files /dev/null and b/rtdata/images/straighten22.png differ diff --git a/rtdata/images/tail.png b/rtdata/images/tail.png new file mode 100644 index 000000000..a40e93750 Binary files /dev/null and b/rtdata/images/tail.png differ diff --git a/rtdata/images/trash-show-empty.png b/rtdata/images/trash-show-empty.png new file mode 100644 index 000000000..c185c78e4 Binary files /dev/null and b/rtdata/images/trash-show-empty.png differ diff --git a/rtdata/images/trash-show-full.png b/rtdata/images/trash-show-full.png new file mode 100644 index 000000000..88f473a2b Binary files /dev/null and b/rtdata/images/trash-show-full.png differ diff --git a/rtdata/images/undelete.png b/rtdata/images/undelete.png new file mode 100644 index 000000000..17f7c62f0 Binary files /dev/null and b/rtdata/images/undelete.png differ diff --git a/rtdata/images/undo.png b/rtdata/images/undo.png new file mode 100644 index 000000000..d888b458c Binary files /dev/null and b/rtdata/images/undo.png differ diff --git a/rtdata/images/unrated.png b/rtdata/images/unrated.png new file mode 100644 index 000000000..9ed8d4926 Binary files /dev/null and b/rtdata/images/unrated.png differ diff --git a/rtdata/images/usbpendrive.png b/rtdata/images/usbpendrive.png new file mode 100644 index 000000000..78b856c58 Binary files /dev/null and b/rtdata/images/usbpendrive.png differ diff --git a/rtdata/images/vertical.png b/rtdata/images/vertical.png new file mode 100644 index 000000000..1870ddc90 Binary files /dev/null and b/rtdata/images/vertical.png differ diff --git a/rtdata/images/verticals.png b/rtdata/images/verticals.png new file mode 100644 index 000000000..ef945a0e4 Binary files /dev/null and b/rtdata/images/verticals.png differ diff --git a/rtdata/images/warnhl.png b/rtdata/images/warnhl.png new file mode 100644 index 000000000..5b907554e Binary files /dev/null and b/rtdata/images/warnhl.png differ diff --git a/rtdata/images/warnsh.png b/rtdata/images/warnsh.png new file mode 100644 index 000000000..30053a6bc Binary files /dev/null and b/rtdata/images/warnsh.png differ diff --git a/rtdata/images/wb22.png b/rtdata/images/wb22.png new file mode 100644 index 000000000..ad1097c1e Binary files /dev/null and b/rtdata/images/wb22.png differ diff --git a/rtdata/images/wbpicker16.png b/rtdata/images/wbpicker16.png new file mode 100644 index 000000000..7c4e1b14b Binary files /dev/null and b/rtdata/images/wbpicker16.png differ diff --git a/rtdata/images/wbpicker22.png b/rtdata/images/wbpicker22.png new file mode 100644 index 000000000..0fc37701b Binary files /dev/null and b/rtdata/images/wbpicker22.png differ diff --git a/rtdata/languages/Catala b/rtdata/languages/Catala new file mode 100644 index 000000000..35ac03118 --- /dev/null +++ b/rtdata/languages/Catala @@ -0,0 +1,702 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# Català +# 10.10.2009: JMG +# +ADJUSTER_RESET_TO_DEFAULT;Restaura predeterminats +CURVEEDITOR_FILEDLGFILTERANY;Tots els fitxers +CURVEEDITOR_FILEDLGFILTERCURVE;Fitxers de corba +CURVEEDITOR_LINEAR;Lineal +CURVEEDITOR_LOADDLGLABEL;Carrega corba... +CURVEEDITOR_SAVEDLGLABEL;Desa corba... +CURVEEDITOR_TOOLTIPLINEAR;Restaura corba lineal (recta) +CURVEEDITOR_TOOLTIPLOAD;Carrega corba de fitxer +CURVEEDITOR_TOOLTIPSAVE;Desa la corba actual +EXIFFILTER_APERTURE;Obertura +EXIFFILTER_CAMERA;Càmera +EXIFFILTER_DIALOGLABEL;Filtre Exif +EXIFFILTER_FOCALLEN;Distància focal +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objectiu +EXIFFILTER_SHUTTER;Temps d'exposició +EXIFPANEL_ADDEDIT;Afegir/Editar +EXIFPANEL_ADDEDITHINT;Afegir nou atribut o editar-lo +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Entrar valor +EXIFPANEL_ADDTAGDLG_SELECTTAG;Selecciona atribut +EXIFPANEL_ADDTAGDLG_TITLE;Afegir/Editar atribut +EXIFPANEL_KEEP;Guarda +EXIFPANEL_KEEPHINT;Conserva atributs seleccionats en escriure un nou fitxer +EXIFPANEL_REMOVE;Esborra +EXIFPANEL_REMOVEHINT;Esborra atributs seleccionats en escriure un nou fitxer +EXIFPANEL_RESETALLHINT;Reinicialitza atributs als valors originals +EXIFPANEL_RESETALL;Reinic. tot +EXIFPANEL_RESETHINT;Reinic. atributs seleccionats als valors originals +EXIFPANEL_RESET;Reinicialitza +EXIFPANEL_SUBDIRECTORY;Subdirectori +FILEBROWSER_APPLYPROFILE;Aplica perfil +FILEBROWSER_ARRANGEMENTHINT;Canvia entre alineació vertical/horitzontal de les minifotos +FILEBROWSER_CLEARPROFILE;Treu perfil +FILEBROWSER_COPYPROFILE;Copia perfil +FILEBROWSER_DELETEDLGLABEL;Confirmació d'esborrar fitxer +FILEBROWSER_DELETEDLGMSG;Segur que voleu esborrar els %1 fitxers? +FILEBROWSER_EMPTYTRASH;Buida paperera +FILEBROWSER_EMPTYTRASHHINT;Buida permanentment la paperera +FILEBROWSER_EXIFFILTERAPPLY;Aplica +FILEBROWSER_EXIFFILTERAPPLYHINT;Commuta on/off el filtre exif del gestor de fitxers +FILEBROWSER_EXIFFILTERLABEL;Filtre Exif +FILEBROWSER_EXIFFILTERSETTINGS;Ajustos +FILEBROWSER_EXIFFILTERSETTINGSHINT;Canvia ajustos del filtre Exif +FILEBROWSER_PARTIALPASTEPROFILE;Enganxa al perfil parcialment +FILEBROWSER_PASTEPROFILE;Enganxa perfil +FILEBROWSER_POPUPCANCELJOB;Cancel·la treball +FILEBROWSER_POPUPMOVEEND;Mou a la fi de la cua +FILEBROWSER_POPUPMOVEHEAD;Mou a l'inici de la cua +FILEBROWSER_POPUPOPEN;Obre +FILEBROWSER_POPUPPROCESS;Posa a la cua de processos +FILEBROWSER_POPUPRANK1;Rang 1 +FILEBROWSER_POPUPRANK2;Rang 2 +FILEBROWSER_POPUPRANK3;Rang 3 +FILEBROWSER_POPUPRANK4;Rang 4 +FILEBROWSER_POPUPRANK5;Rang 5 +FILEBROWSER_POPUPREMOVE;Esborra el fitxer +FILEBROWSER_POPUPRENAME;Reanomena +FILEBROWSER_POPUPSELECTALL;Selec. tot +FILEBROWSER_POPUPTRASH;Llença a la paperera +FILEBROWSER_POPUPUNRANK;Treu el rang +FILEBROWSER_POPUPUNTRASH;Recup. de la paperera +FILEBROWSER_PROCESSINGSETTINGS;Ajustos +FILEBROWSER_PROCESSINGSETTINGSHINT;Indica format de fitxer i directori de sortida +FILEBROWSER_RENAMEDLGLABEL;Reanomena fitxer +FILEBROWSER_RENAMEDLGMSG;Reanomena fitxer "%1" a: +FILEBROWSER_SHOWDIRHINT;Exposa totes les imatges del directori +FILEBROWSER_SHOWQUEUEHINT;Ensenya el contingut de la cua de procés +FILEBROWSER_SHOWRANK1HINT;Exposa imatges d' 1 estrella +FILEBROWSER_SHOWRANK2HINT;Exposa imatges de 2 estrelles +FILEBROWSER_SHOWRANK3HINT;Exposa imatges de 3 estrelles +FILEBROWSER_SHOWRANK4HINT;Exposa imatges de 4 estrelles +FILEBROWSER_SHOWRANK5HINT;Exposa imatges de 5 estrelles +FILEBROWSER_SHOWTRASHHINT;Veure què hi ha a la paperera +FILEBROWSER_SHOWUNRANKHINT;Mostra imatges sense rang +FILEBROWSER_STARTPROCESSINGHINT;Inicia processar/desar d'imatges de la cua +FILEBROWSER_STARTPROCESSING;Inicia procés +FILEBROWSER_STOPPROCESSING;Atura processament +FILEBROWSER_STOPPROCESSINGHINT;Atura processament d'imatges +FILEBROWSER_THUMBSIZE;Tamany minifoto +FILEBROWSER_ZOOMINHINT;Engrandir minifoto +FILEBROWSER_ZOOMOUTHINT;Reduïr minifoto +GENERAL_ABOUT;Respecte a +GENERAL_CANCEL;Cancel·la +GENERAL_DISABLED;Inactivat +GENERAL_DISABLE;Inactiva +GENERAL_ENABLE;Activa +GENERAL_ENABLED;Activat +GENERAL_LANDSCAPE;Horitzontal +GENERAL_LOAD;Carrega +GENERAL_NA;n/a +GENERAL_NO;No +GENERAL_OK;OK +GENERAL_PORTRAIT;Vertical +GENERAL_SAVE;Desa +GENERAL_YES;Sí +HISTOGRAM_LABEL;Histograma +HISTOGRAM_TOOLTIP_B;Ensenya/amaga l'histograma BLAU +HISTOGRAM_TOOLTIP_G;Ensenya/amaga l'histograma VERD +HISTOGRAM_TOOLTIP_L;Ensenya/amaga l'histograma de luminància CIELAB +HISTOGRAM_TOOLTIP_R;Ensenya/amaga l'histograma VERMELL +HISTORY_CHANGED;Canviat +HISTORY_CUSTOMCURVE;Corba particular +HISTORY_DELSNAPSHOT;Treu instant. +HISTORY_FROMCLIPBOARD;Del portapapers +HISTORY_LABEL;Història +HISTORY_MSG_10;Compressió de foscos +HISTORY_MSG_11;Corba de to +HISTORY_MSG_12;Exposició automàtica +HISTORY_MSG_13;Pèrdua per exposició +HISTORY_MSG_14;Luminància: Brillantor +HISTORY_MSG_15;Luminància: Contrast +HISTORY_MSG_16;Luminància: Negre +HISTORY_MSG_17;Luminància: Compressió de clars intensos +HISTORY_MSG_18;Luminància: Compressió de foscos +HISTORY_MSG_19;Corba de luminància +HISTORY_MSG_1;Imatge oberta +HISTORY_MSG_20;Enfocant +HISTORY_MSG_21;Enfocant: Radi +HISTORY_MSG_22;Enfocant: Quantitat +HISTORY_MSG_23;Enfocant: Llindar +HISTORY_MSG_24;Enfocar només vores +HISTORY_MSG_25;Enfocant: Radi detecció de vora +HISTORY_MSG_26;Enfocant: Tolerància vora +HISTORY_MSG_27;Enfocant: Control de halo +HISTORY_MSG_28;Control de halo: quantitat +HISTORY_MSG_29;Mètode d'enfocar +HISTORY_MSG_2;Perfil carregat +HISTORY_MSG_30;Deconvolució: Radi +HISTORY_MSG_31;Deconvolució: Quantitat +HISTORY_MSG_32;Deconvolució: Ablaniment +HISTORY_MSG_33;Deconvolució: Iteracions +HISTORY_MSG_34;Evitar pèrdua de color +HISTORY_MSG_35;Saturació: limitador +HISTORY_MSG_36;Saturació límit +HISTORY_MSG_37;Augment de color +HISTORY_MSG_38;Mètode de balanç de blancs +HISTORY_MSG_39;Temperatura de color +HISTORY_MSG_3;Perfil canviat +HISTORY_MSG_40;Tint de balanç de blancs +HISTORY_MSG_41;Canvi color "A" +HISTORY_MSG_42;Canvi color "B" +HISTORY_MSG_43;Dessorollant luminància +HISTORY_MSG_44;Lumin. dessoroll Radi +HISTORY_MSG_45;Lumin. dessoroll, tolerància vores +HISTORY_MSG_46;Dessorollant color +HISTORY_MSG_47;Dessoroll de color: Radi +HISTORY_MSG_48;Dessoroll de color: Tolerància vores +HISTORY_MSG_49;Dessoroll de color, sensib. de vores +HISTORY_MSG_4;Repassant la història +HISTORY_MSG_50;Eina de foscos/clars intensos +HISTORY_MSG_51;Augment de clars +HISTORY_MSG_52;Augment de foscos +HISTORY_MSG_53;Amplada de to de clars +HISTORY_MSG_54;Amplada de to de foscos +HISTORY_MSG_55;Contrast local +HISTORY_MSG_56;Radi foscos/clars intensos +HISTORY_MSG_57;Rotació tosca +HISTORY_MSG_58;Inversió horitzontal +HISTORY_MSG_59;Inversió vertical +HISTORY_MSG_5;Brillantor +HISTORY_MSG_60;Rotació +HISTORY_MSG_61;Rotació +HISTORY_MSG_62;Correcció distorsió de l'objectiu +HISTORY_MSG_63;Instantània seleccionada +HISTORY_MSG_64;Retalla foto +HISTORY_MSG_65;Correcció A.C. +HISTORY_MSG_66;Recuperació de clars intensos +HISTORY_MSG_67;Recup. de clars: quantitat +HISTORY_MSG_68;Recup. de clars: mètode +HISTORY_MSG_69;Espai de color de treball +HISTORY_MSG_6;Contrast +HISTORY_MSG_70;Espai de color de sortida +HISTORY_MSG_71;Espai de color d'entrada +HISTORY_MSG_72;Correcció del vorafosc +HISTORY_MSG_73;Barrejador de canals +HISTORY_MSG_74;Canviar l'escala +HISTORY_MSG_75;Mètode de canvi d'escala +HISTORY_MSG_76;Metadades Exif +HISTORY_MSG_77;Metadades IPTC +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;Negre +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;Compensació d'exposició +HISTORY_MSG_9;Compressió de clars intensos +HISTORY_NEWSNAPSHOT;Afegeix +HISTORY_NEWSNAPSHOTAS;Com... +HISTORY_NEWSSDIALOGLABEL;Etiqueta d'instantània: +HISTORY_NEWSSDIALOGTITLE;Afegir instant. +HISTORY_SETTO;Fixat a +HISTORY_SNAPSHOT;Instantània +HISTORY_SNAPSHOTS;Instantànies +ICMPANEL_FILEDLGFILTERANY;Tots els fitxers +ICMPANEL_FILEDLGFILTERICM;Fitxers de perfils ICC +ICMPANEL_GAMMABEFOREINPUT;El perfil aplica Gamma +ICMPANEL_INPUTCAMERA;Propi de la càmera +ICMPANEL_INPUTCUSTOM;Especial +ICMPANEL_INPUTDLGLABEL;Selecc. perfil ICC d'entrada... +ICMPANEL_INPUTEMBEDDED;Usar l'encastat si és possible +ICMPANEL_INPUTPROFILE;Perfil d'entrada +ICMPANEL_NOICM;No cap ICM: Sortida sRGB +ICMPANEL_OUTPUTDLGLABEL;Selecc. perfil ICC de sortida... +ICMPANEL_OUTPUTPROFILE;Perfil de sortida +ICMPANEL_SAVEREFERENCE;Desa com a imatge de ref. als perfils +ICMPANEL_WORKINGPROFILE;Perfil de treball +IMAGEAREA_DETAILVIEW;Vista de detall +IPTCPANEL_AUTHOR;Autor +IPTCPANEL_AUTHORHINT;Nom del creador de l'objecte, p.e. escriptor, fotògraf o artista gràfic (By-line). +IPTCPANEL_AUTHORSPOSITIONHINT;Títol del(s) creador(s) de l'objecte (By-line Title). +IPTCPANEL_AUTHORSPOSITION;Tractament o títol de l'autor +IPTCPANEL_CAPTIONHINT;Un text de descripció de les dades (Caption - Abstract). +IPTCPANEL_CAPTION;Text descriptiu +IPTCPANEL_CAPTIONWRITER;Autor de la descripció +IPTCPANEL_CAPTIONWRITERHINT;Nom de qui ha escrit, editat o corregit la imatge o la descripció (Writer - Editor). +IPTCPANEL_CATEGORY;Classificació +IPTCPANEL_CATEGORYHINT;Classificació de la imatge, segons el proveïdor (Category). +IPTCPANEL_CITY;Ciutat +IPTCPANEL_CITYHINT;Ciutat d'origen de la imatge (City). +IPTCPANEL_COPYHINT;Copiar dades actuals IPTC al portapapers +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COPYRIGHTHINT;Qualsevol notificació necessària sobre copyright (Copyright Notice). +IPTCPANEL_COUNTRYHINT;Nom del país o lloc on va ser creada la imatge (Country - Primary Location Name). +IPTCPANEL_COUNTRY;País +IPTCPANEL_CREDIT;Crèdit +IPTCPANEL_CREDITHINT;Identitat del proveïdor de la imatge, no necessàriament el propietari/creador (Credit). +IPTCPANEL_DATECREATED;Data de creació +IPTCPANEL_DATECREATEDHINT;Data en què va ser creat el contingut intel·lectual de la imatge; Format: AAAAMMDD (Date Created). +IPTCPANEL_EMBEDDED;Encastat +IPTCPANEL_EMBEDDEDHINT;Restaurar les dades IPTC encastades al fitxer d'imatge +IPTCPANEL_HEADLINE;Capçalera +IPTCPANEL_HEADLINEHINT;Una nota publicable que és una sinopsi dels continguts de la imatge (Headline). +IPTCPANEL_INSTRUCTIONSHINT;Altres instruccions editorials sobre l'ús de la imatge (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Instruccions +IPTCPANEL_KEYWORDSHINT;Paraules clau que faciliten la recerca de la imatge (Keywords). +IPTCPANEL_KEYWORDS;Paraules clau +IPTCPANEL_PASTEHINT;Enganxa les dades IPTC del portapapers +IPTCPANEL_PROVINCEHINT;Regió/Estat d'origen de la imatge (Province-State). +IPTCPANEL_PROVINCE;Regió +IPTCPANEL_RESETHINT;Reinici perfil per omissió +IPTCPANEL_RESET;Reinici +IPTCPANEL_SOURCE;Font +IPTCPANEL_SOURCEHINT;Propietari original del contingut intel·lectual de la imatge (Source). +IPTCPANEL_SUPPCATEGORIES;Classif. detallada +IPTCPANEL_SUPPCATEGORIESHINT;Precisió sobre el tema de la imatge (Supplemental Categories). +IPTCPANEL_TITLEHINT;Referència breu de la imatge (Object Name). +IPTCPANEL_TITLE;Títol +IPTCPANEL_TRANSREFERENCEHINT;Codi que indica el lloc de la transmissió original (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Refer. transmissió +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Preferències +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;Com... +MAIN_BUTTON_SAVE;Desa la imatge +MAIN_BUTTON_SENDTOEDITOR;Envia a l'editor +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Fitxer la existent +MAIN_MSG_CANNOTLOAD;No puc carregar la imatge +MAIN_MSG_CANNOTSAVE;Error desant el fitxer +MAIN_MSG_CANNOTSTARTEDITOR;No puc iniciar l'editor +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Poseu el path correcte en el diàleg "Preferències". +MAIN_MSG_EXITJOBSINQUEUEINFO;Les imatges no processades de la cua es perdran en sortir. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Segur que voleu sortir? Hi ha imatges no processades a la cua. +MAIN_MSG_JOBSINQUEUE;Treball(s) a la cua. +MAIN_MSG_QOVERWRITE;El voleu sobreescriure? +MAIN_TAB_BASIC;Bàsic +MAIN_TAB_COLOR;Color +MAIN_TAB_DETAIL;Detall +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Exposició +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadades +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Forma +MAIN_TOOLTIP_HIDEFP;Mostra/amaga panell inferior (directori i gestor de fitxers, tecla: F) +MAIN_TOOLTIP_HIDEHP;Mostra/amaga panell esquerre (incloent la història, tecla: H) +MAIN_TOOLTIP_INDCLIPPEDH;Indicador de pèrdues en clars +MAIN_TOOLTIP_INDCLIPPEDS;Indicador de pèrdues en foscos +MAIN_TOOLTIP_PREFERENCES;Fixa preferències +MAIN_TOOLTIP_QINFO;Info breu de la imatge +MAIN_TOOLTIP_SAVEAS;Desa la imatge en directori escollit +MAIN_TOOLTIP_SAVE;Desa la imatge al directori per defecte +PARTIALPASTE_BASICGROUP;Ajustos bàsics +PARTIALPASTE_CACORRECTION;Correcció A. C.(Aberració Cromàtica) +PARTIALPASTE_COARSETRANS;Rotació 90 graus/ inversió +PARTIALPASTE_COLORBOOST;Augment de color +PARTIALPASTE_COLORDENOISE;Dessorollar color +PARTIALPASTE_COLORGROUP;Ajustos de color +PARTIALPASTE_COLORMIXER;Barrejador de color +PARTIALPASTE_COLORSHIFT;Canvi de color +PARTIALPASTE_COMPOSITIONGROUP;Ajustos de composició +PARTIALPASTE_CROP;Retalla +PARTIALPASTE_DIALOGLABEL;Enganxa parcialment al perfil de procés +PARTIALPASTE_DISTORTION;Correcció de distorsió +PARTIALPASTE_EXIFCHANGES;Canvis a les dades Exif +PARTIALPASTE_EXPOSURE;Exposició +PARTIALPASTE_HLRECOVERY;Recup. de clars intensos +PARTIALPASTE_ICMSETTINGS;Ajustos ICM +PARTIALPASTE_IPTCINFO;Dades IPTC +PARTIALPASTE_LENSGROUP;Ajustos de l'objectiu +PARTIALPASTE_LUMACURVE;Corba de luminància +PARTIALPASTE_LUMADENOISE;Reducció de soroll de luminància +PARTIALPASTE_LUMINANCEGROUP;Ajustos de luminància +PARTIALPASTE_METAICMGROUP;Ajustos Metadades/ICM +PARTIALPASTE_RESIZE;Canviar tamany +PARTIALPASTE_ROTATION;Rotació +PARTIALPASTE_SHADOWSHIGHLIGHTS;Foscos/clars intensos +PARTIALPASTE_SHARPENING;Enfocant +PARTIALPASTE_VIGNETTING;Correcció del vorafosc +PARTIALPASTE_WHITEBALANCE;Balanç de blancs +PREFERENCES_APPLNEXTSTARTUP;Efectiu en reiniciar +PREFERENCES_BLINKCLIPPED;Parpelleig d'àrees perdudes +PREFERENCES_CACHECLEARALL;Esborrar tot +PREFERENCES_CACHECLEARPROFILES;Esborrar perfils +PREFERENCES_CACHECLEARTHUMBS;Esborra minifotos +PREFERENCES_CACHEFORMAT1;Propi (ràpid i millor qualitat) +PREFERENCES_CACHEFORMAT2;JPEG (ocupa menys espai al disc) +PREFERENCES_CACHEMAXENTRIES;Màxim nombre d'entrades a la mem. cau +PREFERENCES_CACHEOPTS;Opcions memòria cau +PREFERENCES_CACHESTRAT1;Preferir rapidesa a baix ús de memòria +PREFERENCES_CACHESTRAT2;Preferir baix ús de memòria a rapidesa +PREFERENCES_CACHESTRAT;Estratègia del cau +PREFERENCES_CACHETHUMBFORM;Format del cau en minifoto +PREFERENCES_CACHETHUMBHEIGHT;Màxima alçada de minifoto +PREFERENCES_CLEARDLG_LINE1;Esborrant el cau +PREFERENCES_CLEARDLG_LINE2;Això pot tardar alguns segons +PREFERENCES_CLEARDLG_TITLE;Espereu.. +PREFERENCES_CLIPPINGIND;Indicador de pèrdues +PREFERENCES_CMETRICINTENT;Intent colorimètric +PREFERENCES_DATEFORMAT;Format de data +PREFERENCES_DATEFORMATHINT;Podeu fer servir les següents cadenes formatades:\n%y : any\n%m : mes\n%d : dia\n\nPer exemple, el format de data hongarès és:\n%y/%m/%d +PREFERENCES_DEFAULTLANG;Idioma per omissió +PREFERENCES_DEFAULTTHEME;Tema per omissió +PREFERENCES_DEMOSAICINGALGO;Algoritme de demosaicing +PREFERENCES_DIRHOME;directori home +PREFERENCES_DIRLAST;Últim directori usat +PREFERENCES_DIROTHER;Un altre +PREFERENCES_DIRSELECTDLG;Selecc. directori d'inici... +PREFERENCES_DIRSOFTWARE;Instal·lació al directori +PREFERENCES_DMETHOD;Mètode +PREFERENCES_EDITORCMDLINE;Una altra línia de comandament +PREFERENCES_EXTERNALEDITOR;Editor extern +PREFERENCES_FALSECOLOR;Passos de supressió del fals color +PREFERENCES_FBROWSEROPTS;Opcions gestor d'arxius +PREFERENCES_FILEFORMAT;Format de fitxer +PREFERENCES_FORIMAGE;Per fitxers d'imatge +PREFERENCES_FORRAW;Per fitxers RAW +PREFERENCES_GIMPPATH;Directori d'instal. del GIMP +PREFERENCES_GTKTHEME;GTK predeterminat +PREFERENCES_HINT;Consell +PREFERENCES_HLTHRESHOLD;Llindar pèrdues en clars +PREFERENCES_ICCDIR;Directori dels perfils ICC +PREFERENCES_IMPROCPARAMS;Paràm. per omissió de procés d'imatge +PREFERENCES_INTENT_ABSOLUTE;Colorimètric absolut +PREFERENCES_INTENT_PERCEPTUAL;Perceptual +PREFERENCES_INTENT_RELATIVE;Colorimètric relatiu +PREFERENCES_INTENT_SATURATION;Saturació +PREFERENCES_LIVETHUMBNAILS;Minifotos vives (lent) +PREFERENCES_MONITORICC;Perfil del monitor +PREFERENCES_OUTDIR;Directori de sortida +PREFERENCES_OUTDIRFOLDER;Desa al directori +PREFERENCES_OUTDIRFOLDERHINT;Posa les imatges desades al directori seleccionat +PREFERENCES_OUTDIRHINT;Podeu usar les següents cadenes de format:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nAquestes cadenes de format refereixen als directoris i sub-paths del path del fitxer RAW.\n\nPer exemple, si /home/tom/image/02-09-2006/dsc0012.nef ha estat obert, el significat de les cadenes de format és:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, %p3=/home/tom, ...\n\nSi voleu desar la imatge actual on hi ha l'original, escriviu:\n%p1/%f\n\nSi voleu desar la imatge actual en el directori 'refetes' dins el directori on hi ha l'original, escriviu:\n%p1/refetes/%f\n\nSi voleu desar la imatge actual en el directori '/home/tom/refetes' conservant el mateix subdirectori de dates, escriviu:\n%p2/refetes/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;Podeu usar les següents cadenes de format:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nAquestes cadenes de format refereixen als directoris i sub-paths del path del fitxer RAW.\n\nPer exemple, si /home/tom/image/02-09-2006/dsc0012.nef ha estat obert, el significat de les cadenes de format és:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, %p3=/home/tom, ...\n\nSi voleu desar la imatge actual en el directori on hi ha l'original, escriviu:\n%p1/%f\n\nSi voleu desar la imatge actual en el directori 'refetes' sota el directori on hi ha l'original, escriviu:\n%p1/refetes/%f\n\nSi voleu desar la imatge actual en el directori '/home/tom/refetes' conservant el mateix subdirectori de dates, escriviu:\n%p2/refetes/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Usar plantilla +PREFERENCES_PARSEDEXTADD;Afegir extensió +PREFERENCES_PARSEDEXTADDHINT;Escriu una extensió i prem aquí per veure la llista +PREFERENCES_PARSEDEXTDELHINT;Esborrar l'extensió seleccionada de la llista +PREFERENCES_PARSEDEXT;Extensions analitzades +PREFERENCES_PROFILEHANDLING;Ficant mà als perfils de procés +PREFERENCES_PROFILELOADPR;Prioritat de càrrega de perfils +PREFERENCES_PROFILEPRCACHE;Perfil a la mem. cau +PREFERENCES_PROFILEPRFILE;Perfil juntament amb el fitxer +PREFERENCES_PROFILESAVECACHE;Desa els paràmetres de procés a la memòria cau +PREFERENCES_PROFILESAVEINPUT;Desa els paràm. de procés juntament amb la imatge +PREFERENCES_PSPATH;Directori d'instal. d'Adobe Photoshop +PREFERENCES_SELECTICCDIRDLG;Directori de perfils ICC... +PREFERENCES_SELECTLANG;Seleccionar idioma +PREFERENCES_SELECTMONITORPROFDLG;Selecc. perfil ICC del monitor... +PREFERENCES_SELECTTHEME;Seleccionar tema +PREFERENCES_SHOWBASICEXIF;Mostra inform. bàsica Exif +PREFERENCES_SHOWDATETIME;Indica data i hora +PREFERENCES_SHOWONLYRAW;Exposa només fitxers RAW +PREFERENCES_SHTHRESHOLD;Llindar pèrdues en foscos +PREFERENCES_STARTUPIMDIR;Directori inicial de les imatges +PREFERENCES_TAB_BROWSER;Gestor de fitxers +PREFERENCES_TAB_COLORMGR;Maneig del color +PREFERENCES_TAB_GENERAL;General +PREFERENCES_TAB_IMPROC;Processament de la imatge +PREFERENCES_TAB_OUTPUT;Opcions de sortida +PREFERENCES_THUMBSIZE;Tamany minifoto +PROFILEPANEL_FILEDLGFILTERANY;Tots els fitxers +PROFILEPANEL_FILEDLGFILTERPP;Perfils de postprocés +PROFILEPANEL_LABEL;Perfils de postprocés +PROFILEPANEL_LOADDLGLABEL;Carrega paràm. de postprocés... +PROFILEPANEL_PCUSTOM;Especial +PROFILEPANEL_PFILE;Del fitxer +PROFILEPANEL_PLASTPHOTO;Darrera foto +PROFILEPANEL_PLASTSAVED;Darrera desada +PROFILEPANEL_PROFILE;Perfil +PROFILEPANEL_SAVEDLGLABEL;Desar paràm. de postprocés... +PROFILEPANEL_TOOLTIPCOPY;Copia perfil actual al portapapers +PROFILEPANEL_TOOLTIPLOAD;Carrega perfil d'un fitxer +PROFILEPANEL_TOOLTIPPASTE; Enganxa perfil del portapapers +PROFILEPANEL_TOOLTIPSAVE;Desa l'actual com a perfil +PROGRESSBAR_DECODING;Decodificant fitxer RAW... +PROGRESSBAR_DEMOSAICING;Demosaicing... +PROGRESSBAR_LOADING;Carregant imatge... +PROGRESSBAR_LOADJPEG;Carregant fitxer JPEG... +PROGRESSBAR_LOADPNG;Carregant fitxer PNG... +PROGRESSBAR_LOADTIFF;Carregant fitxer TIFF... +PROGRESSBAR_PROCESSING;Processant imatge... +PROGRESSBAR_READY;A punt. +PROGRESSBAR_SAVEJPEG;Desant fitxer JPEG... +PROGRESSBAR_SAVEPNG;Desant fitxer PNG... +PROGRESSBAR_SAVETIFF;Desant fitxer TIFF... +PROGRESSDLG_LOADING;Carregant fitxer... +PROGRESSDLG_PROCESSING;Processant imatge... +PROGRESSDLG_SAVING;Desant fitxer... +QINFO_FOCALLENGTH;Distància focal +QINFO_ISO;ISO +QINFO_LENS;Objectiu +QINFO_NOEXIF;No hi ha dades Exif. +SAVEDLG_FILEFORMAT;Format del fitxer +SAVEDLG_JPEGQUAL;Qualitat JPEG +SAVEDLG_JPGFILTER;Fitxers JPEG +SAVEDLG_PNGCOMPR;Compressió PNG +SAVEDLG_PNGFILTER;Fitxers PNG +SAVEDLG_PUTTOQUEUEHEAD;Posa al principi de la cua de procés +SAVEDLG_PUTTOQUEUE;Posa a la cua de procés +SAVEDLG_PUTTOQUEUETAIL;Posa a la fi de la cua de procés +SAVEDLG_SAVEIMMEDIATELY;Desa ara mateix +SAVEDLG_SAVESPP;Desa els paràmetres de procés amb la imatge +SAVEDLG_TIFFFILTER;Fitxers TIFF +TOOLBAR_TOOLTIP_CROP;Selecció retall (Tecla: C) +TOOLBAR_TOOLTIP_HAND;Eina mà (Tecla: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Selecc. línia recta (Tecla: S) +TOOLBAR_TOOLTIP_WB;Afina balanç de blancs (Tecla: W) +TP_CACORRECTION_BLUE;Blau +TP_CACORRECTION_LABEL;Correcció A. C. (Aberració Cromàtica) +TP_CACORRECTION_RED;Vermell +TP_CHMIXER_BLUE;Blau +TP_CHMIXER_GREEN;Verd +TP_CHMIXER_LABEL;Barrejador de canals +TP_CHMIXER_RED;Vermell +TP_COARSETRAF_DEGREE;graus: +TP_COARSETRAF_TOOLTIP_HFLIP;Inversió horitzontal +TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotació esquerra +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotació dreta +TP_COARSETRAF_TOOLTIP_VFLIP;Inversió vertical +TP_COLORBOOST_ACHANNEL;Canal "a" +TP_COLORBOOST_AMOUNT;Quantitat +TP_COLORBOOST_AVOIDCOLORCLIP;Evitar pèrdua per color +TP_COLORBOOST_BCHANNEL;Canal "b" +TP_COLORBOOST_CHAB;a & b +TP_COLORBOOST_CHANNEL;Canal +TP_COLORBOOST_CHSEPARATE;independent +TP_COLORBOOST_ENABLESATLIMITER;Activa limitador de saturació +TP_COLORBOOST_LABEL;Augment de color +TP_COLORBOOST_SATLIMIT;Saturació límit +TP_COLORDENOISE_EDGESENSITIVE;Sensibilitat vores +TP_COLORDENOISE_EDGETOLERANCE;Tolerància vores +TP_COLORDENOISE_LABEL;Reducció del soroll de color +TP_COLORDENOISE_RADIUS;Radi +TP_COLORSHIFT_BLUEYELLOW;Blau-Groc +TP_COLORSHIFT_GREENMAGENTA;Verd-Magenta +TP_COLORSHIFT_LABEL;Canvi de color +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Fixa proporció: +TP_CROP_GTDIAGONALS;Regla de diagonals +TP_CROP_GTHARMMEANS1;Tipus armònic 1 +TP_CROP_GTHARMMEANS2;Tipus armònic 2 +TP_CROP_GTHARMMEANS3;Tipus armònic 3 +TP_CROP_GTHARMMEANS4;Tipus armònic 4 +TP_CROP_GTNONE;No cap +TP_CROP_GTRULETHIRDS;Regla dels terços +TP_CROP_GUIDETYPE;Tipus de guia: +TP_CROP_H;A +TP_CROP_LABEL;Retall +TP_CROP_SELECTCROP; Selecc. retall +TP_CROP_W;L +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Quantitat +TP_DISTORTION_LABEL;Distorsió +TP_EXPOSURE_AUTOLEVELS;Nivells automàtics +TP_EXPOSURE_BLACKLEVEL;Negre +TP_EXPOSURE_BRIGHTNESS;Brillantor +TP_EXPOSURE_CLIP;Retall +TP_EXPOSURE_COMPRHIGHLIGHTS;Compressió de clars +TP_EXPOSURE_COMPRSHADOWS;Compressió de foscos +TP_EXPOSURE_CONTRAST;Contrast +TP_EXPOSURE_CURVEEDITOR;Corba de to +TP_EXPOSURE_EXPCOMP;Compens. d'exposició +TP_EXPOSURE_LABEL;Exposició +TP_HLREC_CIELAB;Superposició CIELab +TP_HLREC_COLOR;Propagació de color +TP_HLREC_LABEL;Recuperació de clars +TP_HLREC_LUMINANCE;Recuperació de luminància +TP_HLREC_METHOD;Mètode: +TP_ICM_FILEDLGFILTERANY;Tots els fitxers +TP_ICM_FILEDLGFILTERICM;Fitxers de perfils ICC +TP_ICM_GAMMABEFOREINPUT;El perfil aplica Gamma +TP_ICM_INPUTCAMERA;Propi de la càmera +TP_ICM_INPUTCUSTOM;Especial +TP_ICM_INPUTDLGLABEL;Selecc. perfil d'entrada ICC... +TP_ICM_INPUTEMBEDDED;Usar l'encastat si és possible +TP_ICM_INPUTPROFILE;Perfil d'entrada +TP_ICM_LABEL;ICM +TP_ICM_NOICM;No cap ICM: Sortida sRGB +TP_ICM_OUTPUTDLGLABEL;Selecc. perfil de sortida ICC... +TP_ICM_OUTPUTPROFILE;Perfil de sortida +TP_ICM_SAVEREFERENCE;Desa com a imatge de ref. als perfils +TP_ICM_WORKINGPROFILE;Perfil de treball +TP_LUMACURVE_BLACKLEVEL;Negre +TP_LUMACURVE_BRIGHTNESS;Brillantor +TP_LUMACURVE_COMPRHIGHLIGHTS;Compressió de clars +TP_LUMACURVE_COMPRSHADOWS;Compressió de foscos +TP_LUMACURVE_CONTRAST;Contrast +TP_LUMACURVE_CURVEEDITOR;Corba de luminància +TP_LUMACURVE_LABEL;Corba de luminància +TP_LUMADENOISE_EDGETOLERANCE;Tolerància vores +TP_LUMADENOISE_LABEL;Reducció de soroll de luminància +TP_LUMADENOISE_RADIUS;Radi +TP_RESIZE_BICUBIC;Bicúbic +TP_RESIZE_BICUBICSF;Bicúbic (Fluix) +TP_RESIZE_BICUBICSH;Bicúbic (Més intens) +TP_RESIZE_BILINEAR;Bilinear +TP_RESIZE_FULLSIZE;Tamany imatge sencera: +TP_RESIZE_H;A: +TP_RESIZE_LABEL;Canviar tamany +TP_RESIZE_METHOD;Mètode: +TP_RESIZE_NEAREST;Més proper +TP_RESIZE_SCALE;Escala +TP_RESIZE_W;L: +TP_ROTATE_AUTOCROP;Auto retalla +TP_ROTATE_DEGREE;Graus +TP_ROTATE_FILL;Omple +TP_ROTATE_LABEL;Rota +TP_ROTATE_SELECTLINE; Selecc. línia recta +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Clars intensos +TP_SHADOWSHLIGHTS_HLTONALW;Amplada de to +TP_SHADOWSHLIGHTS_LABEL;Foscos/Clars intensos +TP_SHADOWSHLIGHTS_LOCALCONTR;Contrast local +TP_SHADOWSHLIGHTS_RADIUS;Radi +TP_SHADOWSHLIGHTS_SHADOWS;Foscos +TP_SHADOWSHLIGHTS_SHTONALW;Amplada de to +TP_SHARPENING_AMOUNT;Quantitat +TP_SHARPENING_EDRADIUS;Radi +TP_SHARPENING_EDTOLERANCE;Tolerància vores +TP_SHARPENING_HALOCONTROL;Control de halo +TP_SHARPENING_HCAMOUNT;Quantitat +TP_SHARPENING_LABEL;Enfocant +TP_SHARPENING_METHOD;Mètode +TP_SHARPENING_ONLYEDGES;Enfocar només vores +TP_SHARPENING_RADIUS;Radi +TP_SHARPENING_RLD_AMOUNT;Quantitat +TP_SHARPENING_RLD_DAMPING;Ablaniment +TP_SHARPENING_RLD_ITERATIONS;Iteracions +TP_SHARPENING_RLD;RL Deconvolució +TP_SHARPENING_THRESHOLD;Llindar +TP_SHARPENING_USM;Màscara d'enfocament +TP_VIGNETTING_AMOUNT;Quantitat +TP_VIGNETTING_LABEL;Correcció vorafosc +TP_VIGNETTING_RADIUS;Radi +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Càmera +TP_WBALANCE_CUSTOM;Especial +TP_WBALANCE_GREEN;Tint +TP_WBALANCE_LABEL;Balanç de blancs +TP_WBALANCE_METHOD;Mètode +TP_WBALANCE_SIZE;Tamany: +TP_WBALANCE_SPOTWB;Punt b. blancs +TP_WBALANCE_TEMPERATURE;Temperatura +ZOOMBAR_DETAIL;Detall +ZOOMBAR_HUGE;Enorme +ZOOMBAR_LARGE;Gran +ZOOMBAR_NORMAL;Normal +ZOOMBAR_PREVIEW;Previsualització +ZOOMBAR_SCALE;Escala +ZOOMBAR_SMALL;Petit + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) new file mode 100644 index 000000000..f21cea151 --- /dev/null +++ b/rtdata/languages/Chinese (Simplified) @@ -0,0 +1,704 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# 06.11.2008 +# Chinese simplified +# Yang Gao (grantyale) +# Added new translations for 2.4beta, fixed mistranslations(eg. Vignetting - æš—è§’/失光 instead of ç´«è¾¹ which corresponds to purple fringing, and RL Deconvolution) +# based on Version 13.2.2008 by Forrest Sun +ADJUSTER_RESET_TO_DEFAULT;é‡ç½®ç¼ºçœå‚æ•° +CURVEEDITOR_FILEDLGFILTERANY;ä»»æ„æ–‡ä»¶ +CURVEEDITOR_FILEDLGFILTERCURVE;曲线文件 +CURVEEDITOR_LINEAR;线性 +CURVEEDITOR_LOADDLGLABEL;æ­£è¯»å–æ›²çº¿... +CURVEEDITOR_SAVEDLGLABEL;æ­£ä¿å­˜æ›²çº¿... +CURVEEDITOR_TOOLTIPLINEAR;é‡ç½®æ›²çº¿ +CURVEEDITOR_TOOLTIPLOAD;è¯»å–æ›²çº¿ +CURVEEDITOR_TOOLTIPSAVE;ä¿å­˜æ›²çº¿ +EXIFFILTER_APERTURE;光圈 +EXIFFILTER_CAMERA;相机 +EXIFFILTER_DIALOGLABEL;按Exif筛选 +EXIFFILTER_FOCALLEN;ç„¦è· +EXIFFILTER_ISO;感光度 +EXIFFILTER_LENS;镜头 +EXIFFILTER_SHUTTER;å¿«é—¨ +EXIFPANEL_ADDEDITHINT;添加/编辑标签 +EXIFPANEL_ADDEDIT;添加/编辑 +EXIFPANEL_ADDTAGDLG_ENTERVALUE;输入内容 +EXIFPANEL_ADDTAGDLG_SELECTTAG;选择标签 +EXIFPANEL_ADDTAGDLG_TITLE;添加/编辑标签 +EXIFPANEL_KEEPHINT;输出文件时ä¿ç•™â€œå·²é€‰â€æ ‡ç­¾ +EXIFPANEL_KEEP;ä¿ç•™ +EXIFPANEL_REMOVEHINT;è¾“å‡ºæ–‡ä»¶æ—¶ç§»é™¤â€œå·²é€‰â€æ ‡ç­¾ +EXIFPANEL_REMOVE;移除 +EXIFPANEL_RESETALLHINT;é‡ç½®æ‰€æœ‰æ ‡ç­¾å†…容 +EXIFPANEL_RESETALL;全部é‡ç½® +EXIFPANEL_RESETHINT;é‡ç½®æ‰€é€‰æ ‡ç­¾å†…容 +EXIFPANEL_RESET;é‡ç½® +EXIFPANEL_SUBDIRECTORY;å­æ–‡ä»¶å¤¹ +FILEBROWSER_APPLYPROFILE;应用é…ç½® +FILEBROWSER_ARRANGEMENTHINT;切æ¢ç¼©ç•¥å›¾å¯¹é½æ–¹å¼ +FILEBROWSER_CLEARPROFILE;清空é…ç½® +FILEBROWSER_COPYPROFILE;å¤åˆ¶é…ç½® +FILEBROWSER_DELETEDLGLABEL;确认删除 +FILEBROWSER_DELETEDLGMSG;确定删除所选的%1个文件? +FILEBROWSER_EMPTYTRASHHINT;永久清空垃圾箱 +FILEBROWSER_EMPTYTRASH;清空垃圾箱 +FILEBROWSER_EXIFFILTERAPPLYHINT;文件æµè§ˆå™¨Exif筛选开关 +FILEBROWSER_EXIFFILTERAPPLY;应用 +FILEBROWSER_EXIFFILTERLABEL;Exif筛选 +FILEBROWSER_EXIFFILTERSETTINGSHINT;更改Exif筛选设置 +FILEBROWSER_EXIFFILTERSETTINGS;设置 +FILEBROWSER_PARTIALPASTEPROFILE;选择性粘贴 +FILEBROWSER_PASTEPROFILE;粘贴é…ç½® +FILEBROWSER_POPUPCANCELJOB;å–æ¶ˆä»»åŠ¡ +FILEBROWSER_POPUPMOVEEND;移动到队列尾部 +FILEBROWSER_POPUPMOVEHEAD;移动到队列头部 +FILEBROWSER_POPUPOPEN;打开 +FILEBROWSER_POPUPPROCESS;放入队列 +FILEBROWSER_POPUPRANK1;评 1 星 +FILEBROWSER_POPUPRANK2;评 2 星 +FILEBROWSER_POPUPRANK3;评 3 星 +FILEBROWSER_POPUPRANK4;评 4 星 +FILEBROWSER_POPUPRANK5;评 5 星 +FILEBROWSER_POPUPREMOVE;从文件系统中移除 +FILEBROWSER_POPUPRENAME;é‡å‘½å +FILEBROWSER_POPUPSELECTALL;全部选中 +FILEBROWSER_POPUPTRASH;移动到垃圾箱 +FILEBROWSER_POPUPUNRANK;å–æ¶ˆæ˜Ÿçº§ +FILEBROWSER_POPUPUNTRASH;从垃圾箱中移除 +FILEBROWSER_PROCESSINGSETTINGSHINT;设置文件格å¼åŠè¾“出文件夹 +FILEBROWSER_PROCESSINGSETTINGS;设置 +FILEBROWSER_RENAMEDLGLABEL;文件é‡å‘½å +FILEBROWSER_RENAMEDLGMSG;å°†"%1"æ›´å为: +FILEBROWSER_SHOWDIRHINT;显示文件夹中所有图片 +FILEBROWSER_SHOWQUEUEHINT;显示队列内容 +FILEBROWSER_SHOWRANK1HINT;显示1星图片 +FILEBROWSER_SHOWRANK2HINT;显示2星图片 +FILEBROWSER_SHOWRANK3HINT;显示3星图片 +FILEBROWSER_SHOWRANK4HINT;显示4星图片 +FILEBROWSER_SHOWRANK5HINT;显示5星图片 +FILEBROWSER_SHOWTRASHHINT;显示垃圾箱内容 +FILEBROWSER_SHOWUNRANKHINT;显示未评星图片 +FILEBROWSER_STARTPROCESSINGHINT;å¼€å§‹å¤„ç†æˆ–ä¿å­˜é˜Ÿåˆ—中的图片 +FILEBROWSER_STARTPROCESSING;å¼€å§‹å¤„ç† +FILEBROWSER_STOPPROCESSINGHINT;åœæ­¢å¤„ç†å›¾ç‰‡ +FILEBROWSER_STOPPROCESSING;åœæ­¢å¤„ç† +FILEBROWSER_THUMBSIZE;ç¼©ç•¥å›¾å¤§å° +FILEBROWSER_ZOOMINHINT;增大缩略图 +FILEBROWSER_ZOOMOUTHINT;å‡å°ç¼©ç•¥å›¾ +GENERAL_ABOUT;关于 +GENERAL_CANCEL;å–æ¶ˆ +GENERAL_DISABLED;ç¦ç”¨ +GENERAL_DISABLE;ç¦ç”¨ +GENERAL_ENABLED;å¼€å¯ +GENERAL_ENABLE;å¯ç”¨ +GENERAL_LANDSCAPE;æ¨ªå‘ +GENERAL_LOAD;è¯»å– +GENERAL_NA;ä¸é€‚用 +GENERAL_NO;å¦ +GENERAL_OK;确定 +GENERAL_PORTRAIT;çºµå‘ +GENERAL_SAVE;ä¿å­˜ +GENERAL_YES;是 +HISTOGRAM_LABEL;直方图 +HISTOGRAM_TOOLTIP_B;显示/éšè— è“色直方图 +HISTOGRAM_TOOLTIP_G;显示/éšè— 绿色直方图 +HISTOGRAM_TOOLTIP_L;显示/éšè— CIELAB 亮度直方图 +HISTOGRAM_TOOLTIP_R;显示/éšè— 红色直方图 +HISTORY_CHANGED;已更改 +HISTORY_CUSTOMCURVE;自定义曲线 +HISTORY_DELSNAPSHOT;移除快照 +HISTORY_FROMCLIPBOARD;ä»Žå‰ªè´´æ¿ +HISTORY_LABEL;åŽ†å² +HISTORY_MSG_10;阴影压缩 +HISTORY_MSG_11;影调曲线 +HISTORY_MSG_12;自动æ›å…‰ +HISTORY_MSG_13;æ›å…‰æº¢å‡º +HISTORY_MSG_14;亮度亮度 +HISTORY_MSG_15;亮度对比度 +HISTORY_MSG_16;亮度黑 +HISTORY_MSG_17;亮度高光压缩 +HISTORY_MSG_18;亮度阴影压缩 +HISTORY_MSG_19;亮度曲线 +HISTORY_MSG_1;图片加载完 +HISTORY_MSG_20;é”化 +HISTORY_MSG_21;é”化åŠå¾„ +HISTORY_MSG_22;é”化程度 +HISTORY_MSG_23;é”化阈值 +HISTORY_MSG_24;ä»…é”化边缘 +HISTORY_MSG_25;é”化边缘åŠå¾„ +HISTORY_MSG_26;é”化边缘容差 +HISTORY_MSG_27;é”化光晕控制 +HISTORY_MSG_28;å…‰æ™•æŽ§åˆ¶é‡ +HISTORY_MSG_29;é”åŒ–æ–¹å¼ +HISTORY_MSG_2;é…置加载完 +HISTORY_MSG_30;é‡å åŠå¾„ +HISTORY_MSG_31;é‡å ç¨‹åº¦ +HISTORY_MSG_32;é‡å è¡°å‡ +HISTORY_MSG_33;é‡å æ¬¡æ•° +HISTORY_MSG_34;é¿å…色彩溢出 +HISTORY_MSG_35;饱和度é™åˆ¶å™¨ +HISTORY_MSG_36;饱和度é™åˆ¶ +HISTORY_MSG_37;色彩增强 +HISTORY_MSG_38;æ‹å¹³è¡¡æ–¹å¼ +HISTORY_MSG_39;色温 +HISTORY_MSG_3;é…ç½®æ”¹å˜ +HISTORY_MSG_40;白平衡微调 +HISTORY_MSG_41;色彩åç§» "A" +HISTORY_MSG_42;色彩åç§» "B" +HISTORY_MSG_43;亮度é™å™ª +HISTORY_MSG_44;亮度é™å™ªåŠå¾„ +HISTORY_MSG_45;亮度é™å™ªè¾¹ç¼˜å®¹å·® +HISTORY_MSG_46;色彩é™å™ª +HISTORY_MSG_47;色彩é™å™ªåŠå¾„ +HISTORY_MSG_48;色彩é™å™ªè¾¹ç¼˜å®¹å·® +HISTORY_MSG_49;色彩é™å™ªè¾¹ç¼˜æ•感度 +HISTORY_MSG_4;åŽ†å²æµè§ˆ +HISTORY_MSG_50;阴影/高光工具 +HISTORY_MSG_51;高光增强 +HISTORY_MSG_52;阴影增强 +HISTORY_MSG_53;高光色度范围 +HISTORY_MSG_54;阴影色度范围 +HISTORY_MSG_55;局部对比度 +HISTORY_MSG_56;阴影/高光åŠå¾„ +HISTORY_MSG_57;粗略旋转 +HISTORY_MSG_58;水平翻转 +HISTORY_MSG_59;竖直翻转 +HISTORY_MSG_5;亮度 +HISTORY_MSG_60;旋转 +HISTORY_MSG_61;旋转 +HISTORY_MSG_62;镜头失真矫正 +HISTORY_MSG_63;设置书签 +HISTORY_MSG_64;剪切图片 +HISTORY_MSG_65;色散矫正 +HISTORY_MSG_66;高光还原 +HISTORY_MSG_67;高光还原程度 +HISTORY_MSG_68;é«˜å…‰è¿˜åŽŸæ–¹å¼ +HISTORY_MSG_69;工作色彩空间 +HISTORY_MSG_6;对比度 +HISTORY_MSG_70;输出色彩空间 +HISTORY_MSG_71;输入色å‚空间 +HISTORY_MSG_72;暗角矫正 +HISTORY_MSG_73;é€šé“æ··åˆå™¨ +HISTORY_MSG_74;è°ƒæ•´å¤§å°æ¯”例 +HISTORY_MSG_75;è°ƒæ•´å¤§å°æ–¹å¼ +HISTORY_MSG_76;Exifå…ƒæ•°æ® +HISTORY_MSG_77;IPTCå…ƒæ•°æ® +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;黑 +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;æ›å…‰è¡¥å¿ +HISTORY_MSG_9;高光压缩 +HISTORY_NEWSNAPSHOTAS;为... +HISTORY_NEWSNAPSHOT;新建快照 +HISTORY_NEWSSDIALOGLABEL;快照标签: +HISTORY_NEWSSDIALOGTITLE;添加新快照 +HISTORY_SETTO;设置为 +HISTORY_SNAPSHOTS;系列快照 +HISTORY_SNAPSHOT;å¿«ç…§ +ICMPANEL_FILEDLGFILTERANY;ä»»æ„æ–‡ä»¶ +ICMPANEL_FILEDLGFILTERICM;ICCé…置文件 +ICMPANEL_GAMMABEFOREINPUT;é…置使用Gammaæ ¡æ­£ +ICMPANEL_INPUTCAMERA;ç›¸æœºç¼ºçœ +ICMPANEL_INPUTCUSTOM;自定义 +ICMPANEL_INPUTDLGLABEL;选择输入ICCé…ç½®... +ICMPANEL_INPUTEMBEDDED;如å¯èƒ½ï¼Œä½¿ç”¨å†…ç½® +ICMPANEL_INPUTPROFILE;输入é…ç½® +ICMPANEL_NOICM;No ICM: sRGBé…ç½® +ICMPANEL_OUTPUTDLGLABEL;选择输出ICCé…ç½®... +ICMPANEL_OUTPUTPROFILE;输出é…ç½® +ICMPANEL_SAVEREFERENCE;ä¿å­˜å‚考图片用于生æˆé…ç½®ä¿¡æ¯ +ICMPANEL_WORKINGPROFILE;当å‰é…ç½® +IMAGEAREA_DETAILVIEW;细节视图 +IPTCPANEL_AUTHORHINT;作者姓å +IPTCPANEL_AUTHORSPOSITIONHINT;作者头衔 +IPTCPANEL_AUTHORSPOSITION;作者èŒä½ +IPTCPANEL_AUTHOR;作者 +IPTCPANEL_CAPTIONHINT;文字说明 +IPTCPANEL_CAPTIONWRITERHINT;å‚与创作人员 +IPTCPANEL_CAPTIONWRITER;说明作者 +IPTCPANEL_CAPTION;标题 +IPTCPANEL_CATEGORYHINT;æä¾›è€…所认为的作å“类别 +IPTCPANEL_CATEGORY;类别 +IPTCPANEL_CITYHINT;图片æ¥è‡ªåŸŽå¸‚ +IPTCPANEL_CITY;城市 +IPTCPANEL_COPYHINT;å°†IPTC设置å¤åˆ¶åˆ°å‰ªè´´æ¿ +IPTCPANEL_COPYRIGHTHINT;版æƒä¿¡æ¯ +IPTCPANEL_COPYRIGHT;ç‰ˆæƒ +IPTCPANEL_COUNTRYHINT;图片æ¥è‡ªå›½å®¶ +IPTCPANEL_COUNTRY;国家 +IPTCPANEL_CREDITHINT;图片æä¾›è€…,未必是作者 +IPTCPANEL_CREDIT;æä¾›è€… +IPTCPANEL_DATECREATEDHINT;图片创作日期,格å¼ï¼šå¹´æœˆæ—¥è¡¥é›¶(YYYYMMDD) +IPTCPANEL_DATECREATED;创作日期 +IPTCPANEL_EMBEDDEDHINT;å°†IPTCæ•°æ®é‡ç½®ä¸ºå›¾ç‰‡å†…åµŒæ•°æ® +IPTCPANEL_EMBEDDED;内嵌 +IPTCPANEL_HEADLINEHINT;å¯å‘布的内容简介 +IPTCPANEL_HEADLINE;æ‘˜è¦ +IPTCPANEL_INSTRUCTIONSHINT;å†™ç»™ç¼–è¾‘çš„ç‰¹æ®Šè¦æ±‚ +IPTCPANEL_INSTRUCTIONS;指令 +IPTCPANEL_KEYWORDSHINT;用于信æ¯ç´¢å¼• +IPTCPANEL_KEYWORDS;å…³é”®è¯ +IPTCPANEL_PASTEHINT;粘贴剪贴æ¿å†…çš„IPTC设置 +IPTCPANEL_PROVINCEHINT;图片æ¥è‡ªçœä»½ +IPTCPANEL_PROVINCE;çœä»½ +IPTCPANEL_RESETHINT;é‡ç½®ä¸ºé»˜è®¤é…ç½® +IPTCPANEL_RESET;é‡ç½® +IPTCPANEL_SOURCEHINT;å›¾ç‰‡å†…å®¹çŸ¥è¯†äº§æƒæ‰€æœ‰äºº +IPTCPANEL_SOURCE;æ¥æº +IPTCPANEL_SUPPCATEGORIESHINT;进一步细分类别 +IPTCPANEL_SUPPCATEGORIES;附加类别 +IPTCPANEL_TITLEHINT;作å“çš„åç§° +IPTCPANEL_TITLE;标题 +IPTCPANEL_TRANSREFERENCEHINT;原始å‘é€åœ°ç‚¹ä»£ç  +IPTCPANEL_TRANSREFERENCE;传输基准 +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;傿•°è®¾ç½® +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;为... +MAIN_BUTTON_SAVE;ä¿å­˜å›¾ç‰‡ +MAIN_BUTTON_SENDTOEDITOR;å‘é€åˆ°ç¼–辑器 +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;该文件已存在 +MAIN_MSG_CANNOTLOAD;无法加载图片 +MAIN_MSG_CANNOTSAVE;文件ä¿å­˜ä¸­å‡ºé”™ +MAIN_MSG_CANNOTSTARTEDITOR;Can not start editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Please set the correct path in the "Preferences" dialog. +MAIN_MSG_EXITJOBSINQUEUEINFO;退出时队列中未处ç†çš„图片将被丢弃。 +MAIN_MSG_EXITJOBSINQUEUEQUEST;队列中尚有图片未处ç†ï¼Œç¡®è®¤é€€å‡ºï¼Ÿ +MAIN_MSG_JOBSINQUEUE;任务列队中 +MAIN_MSG_QOVERWRITE;是å¦è¦†ç›–? +MAIN_TAB_BASIC;基本 +MAIN_TAB_COLOR;Color +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;æ›å…‰ +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;å…ƒæ•°æ® +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;è½¬æ¢ +MAIN_TOOLTIP_HIDEFP;显示/éšè—åº•éƒ¨é¢æ¿ (目录和文件æµè§ˆå™¨) (shortcut key: F) +MAIN_TOOLTIP_HIDEHP;显示/éšè—左颿¿ (包å«åކå², shortcut key: H) +MAIN_TOOLTIP_INDCLIPPEDH;高光溢出æç¤º +MAIN_TOOLTIP_INDCLIPPEDS;阴影ä¸è¶³æç¤º +MAIN_TOOLTIP_PREFERENCES;è®¾ç½®å‚æ•° +MAIN_TOOLTIP_QINFO;图片快æ·ä¿¡æ¯ +MAIN_TOOLTIP_SAVEAS;图片存于指定文件夹 +MAIN_TOOLTIP_SAVE;å›¾ç‰‡å­˜äºŽç¼ºçœæ–‡ä»¶å¤¹ +PARTIALPASTE_BASICGROUP;基本设置 +PARTIALPASTE_CACORRECTION;色彩校正 +PARTIALPASTE_COARSETRANS;90度旋转/翻转 +PARTIALPASTE_COLORBOOST;色彩增强 +PARTIALPASTE_COLORDENOISE;色彩é™å™ª +PARTIALPASTE_COLORGROUP;色彩相关设定 +PARTIALPASTE_COLORMIXER;色彩混åˆå™¨ +PARTIALPASTE_COLORSHIFT;色彩åç§» +PARTIALPASTE_COMPOSITIONGROUP;构图设置 +PARTIALPASTE_CROP;å‰ªè£ +PARTIALPASTE_DIALOGLABEL;选择性粘贴é…ç½® +PARTIALPASTE_DISTORTION;å½¢å˜æ ¡æ­£ +PARTIALPASTE_EXIFCHANGES;对exif所åšçš„修改 +PARTIALPASTE_EXPOSURE;æ›å…‰ +PARTIALPASTE_HLRECOVERY;é«˜æ„Ÿå…‰ä¿®å¤ +PARTIALPASTE_ICMSETTINGS;ICM 设置 +PARTIALPASTE_IPTCINFO;IPTC ä¿¡æ¯ +PARTIALPASTE_LENSGROUP;镜头相关设置 +PARTIALPASTE_LUMACURVE;亮度曲线 +PARTIALPASTE_LUMADENOISE;亮度é™å™ª +PARTIALPASTE_LUMINANCEGROUP;亮度相关设置 +PARTIALPASTE_METAICMGROUP;元数æ®/ICM 设置 +PARTIALPASTE_RESIZE;缩放 +PARTIALPASTE_ROTATION;旋转 +PARTIALPASTE_SHADOWSHIGHLIGHTS;阴影/高光 +PARTIALPASTE_SHARPENING;é”化 +PARTIALPASTE_VIGNETTING;暗角修正 +PARTIALPASTE_WHITEBALANCE;白平衡 +PREFERENCES_APPLNEXTSTARTUP;下次å¯åŠ¨ç”Ÿæ•ˆ +PREFERENCES_BLINKCLIPPED;é«˜å…‰åŒºåŸŸé—ªçƒ +PREFERENCES_CACHECLEARALL;全部清除 +PREFERENCES_CACHECLEARPROFILES;清除é…ç½® +PREFERENCES_CACHECLEARTHUMBS;清除缩略图 +PREFERENCES_CACHEFORMAT1;ä¸“æœ‰æ ¼å¼ (快速高质é‡) +PREFERENCES_CACHEFORMAT2;JPEG (è¾ƒå°æ–‡ä»¶) +PREFERENCES_CACHEMAXENTRIES;æœ€å¤§ç¼“å­˜æ•°é‡ +PREFERENCES_CACHEOPTS;缓存选项 +PREFERENCES_CACHESTRAT1;较高速度 +PREFERENCES_CACHESTRAT2;较低内存å ç”¨çއ +PREFERENCES_CACHESTRAT;缓存方案 +PREFERENCES_CACHETHUMBFORM;ç¼©ç•¥å›¾ç¼“å­˜æ ¼å¼ +PREFERENCES_CACHETHUMBHEIGHT;最大缩略图高度 +PREFERENCES_CLEARDLG_LINE1;正在清空缓存 +PREFERENCES_CLEARDLG_LINE2;å¯èƒ½éœ€è¦æ•°ç§’钟时间。 +PREFERENCES_CLEARDLG_TITLE;请ç¨ç­‰ +PREFERENCES_CLIPPINGIND;高光溢出æç¤º +PREFERENCES_CMETRICINTENT;è‰²å½©æ¨¡å¼ +PREFERENCES_DATEFORMATHINT;å¯ä»¥ä½¿ç”¨ä¸‹åˆ—控制符:\n%y : å¹´\n%m : 月h\n%d : æ—¥\n\n例如,中文日期格å¼:\n%y/%m/%d +PREFERENCES_DATEFORMAT;æ—¥æœŸæ ¼å¼ +PREFERENCES_DEFAULTLANG;缺çœè¯­è¨€ +PREFERENCES_DEFAULTTHEME;默认主题 +PREFERENCES_DEMOSAICINGALGO;马赛克还原算法 +PREFERENCES_DIRHOME;用户文件路径 +PREFERENCES_DIRLAST;上次访问路径 +PREFERENCES_DIROTHER;å…¶ä»– +PREFERENCES_DIRSELECTDLG;å¯åŠ¨æ—¶é€‰æ‹©å›¾ç‰‡è·¯å¾„... +PREFERENCES_DIRSOFTWARE;软件安装路径 +PREFERENCES_DMETHOD;æ–¹å¼ +PREFERENCES_EDITORCMDLINE;其他命令行 +PREFERENCES_EXTERNALEDITOR;外部编辑器 +PREFERENCES_FALSECOLOR;虚å‡è‰²å½©åŽ‹ç¼©æ­¥éª¤ +PREFERENCES_FBROWSEROPTS;文件æµè§ˆé€‰é¡¹ +PREFERENCES_FILEFORMAT;æ–‡ä»¶æ ¼å¼ +PREFERENCES_FORIMAGE;用于图片文件 +PREFERENCES_FORRAW;用于Raw文件 +PREFERENCES_GIMPPATH;GIMP安装文件夹 +PREFERENCES_GTKTHEME;GTK默认 +PREFERENCES_HINT;æç¤º +PREFERENCES_HLTHRESHOLD;高光溢出阈值 +PREFERENCES_ICCDIR;ICCé…置路径 +PREFERENCES_IMPROCPARAMS;缺çœå›¾ç‰‡å¤„ç†å‚æ•° +PREFERENCES_INTENT_ABSOLUTE;ç»å¯¹è‰²å½©æ¨¡å¼ +PREFERENCES_INTENT_PERCEPTUAL;æ„ŸçŸ¥æ¨¡å¼ +PREFERENCES_INTENT_RELATIVE;ç›¸å¯¹è‰²å½©æ¨¡å¼ +PREFERENCES_INTENT_SATURATION;饱和度 +PREFERENCES_LIVETHUMBNAILS;实时缩略图(较慢) +PREFERENCES_MONITORICC;显示器é…ç½® +PREFERENCES_OUTDIRFOLDERHINT;将已寸图片放至所选文件夹 +PREFERENCES_OUTDIRFOLDER;ä¿å­˜è‡³æ–‡ä»¶å¤¹ +PREFERENCES_OUTDIRHINT;å¯ä»¥ä½¿ç”¨ä¸‹åˆ—控制符:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\n这些控制符指å‘RAW文件所在文件夹åŠå­æ–‡ä»¶å¤¹ã€‚\n\n例如 å‡å¦‚ /home/tom/image/02-09-2006/dsc0012.nefå·²ç»æ‰“开,控制符的æ„义如下:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\n如果想将输出文件ä¿å­˜åˆ°è¾“入文件所在ä½ç½®ï¼š\n%p1/%f\n\n如果想将输出文件ä¿å­˜è‡³è¾“入文件夹内的'converted'å­æ–‡ä»¶å¤¹ï¼š\n%p1/converted/%f\n\n如果想将输出文件ä¿å­˜è‡³ '/home/tom/converted' å¹¶ä¿ç•™æŒ‰æ—¥æœŸæ‰€åˆ†çš„å­æ–‡ä»¶å¤¹ï¼š\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;å¯ä»¥ä½¿ç”¨ä¸‹åˆ—控制符:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\n这些控制符指å‘RAW文件所在文件夹åŠå­æ–‡ä»¶å¤¹ã€‚\n\n例如 å‡å¦‚ /home/tom/image/02-09-2006/dsc0012.nefå·²ç»æ‰“开,控制符的æ„义如下:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\n如果想将输出文件ä¿å­˜åˆ°è¾“入文件所在ä½ç½®ï¼š\n%p1/%f\n\n如果想将输出文件ä¿å­˜è‡³è¾“入文件夹内的'converted'å­æ–‡ä»¶å¤¹ï¼š\n%p1/converted/%f\n\n如果想将输出文件ä¿å­˜è‡³ '/home/tom/converted' å¹¶ä¿ç•™æŒ‰æ—¥æœŸæ‰€åˆ†çš„å­æ–‡ä»¶å¤¹ï¼š\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;ä½¿ç”¨æ¨¡æ¿ +PREFERENCES_OUTDIR;输出路径 +PREFERENCES_PARSEDEXTADDHINT;输入扩展å并按此按钮将其添加至列表 +PREFERENCES_PARSEDEXTADD;添加扩展å +PREFERENCES_PARSEDEXTDELHINT;从列表中删除选中的扩展å +PREFERENCES_PARSEDEXT;已知扩展å +PREFERENCES_PROFILEHANDLING;图片处ç†é…ç½®ç®¡ç† +PREFERENCES_PROFILELOADPR;é…置文件读å–优先级 +PREFERENCES_PROFILEPRCACHE;缓存中的é…置文件 +PREFERENCES_PROFILEPRFILE;与图片并列存放的é…置文件 +PREFERENCES_PROFILESAVECACHE;å°†é…置文件写至缓存 +PREFERENCES_PROFILESAVEINPUT;å°†é…置文件与图片并列存放 +PREFERENCES_PSPATH;Adobe Photoshop安装路径 +PREFERENCES_SELECTICCDIRDLG;选择ICC路径... +PREFERENCES_SELECTLANG;选择语言 +PREFERENCES_SELECTMONITORPROFDLG;选择显示器ICC路径... +PREFERENCES_SELECTTHEME;选择主题 +PREFERENCES_SHOWBASICEXIF;显示基本Exifä¿¡æ¯ +PREFERENCES_SHOWDATETIME;显示时间日期 +PREFERENCES_SHOWONLYRAW;仅显示Raw文件 +PREFERENCES_SHTHRESHOLD;阴影过暗阈值 +PREFERENCES_STARTUPIMDIR;å¯åŠ¨æ—¶è·¯å¾„ +PREFERENCES_TAB_BROWSER;文件æµè§ˆå™¨ +PREFERENCES_TAB_COLORMGR;è‰²å½©ç®¡ç† +PREFERENCES_TAB_GENERAL;一般 +PREFERENCES_TAB_IMPROC;å›¾ç‰‡å¤„ç† +PREFERENCES_TAB_OUTPUT;输出选项 +PREFERENCES_THUMBSIZE;ç¼©ç•¥å›¾å¤§å° +PROFILEPANEL_FILEDLGFILTERANY;ä»»æ„æ–‡ä»¶ +PROFILEPANEL_FILEDLGFILTERPP;处ç†å‚æ•°é…ç½® +PROFILEPANEL_LABEL;处ç†å‚æ•°é…ç½® +PROFILEPANEL_LOADDLGLABEL;加载处ç†å‚数为... +PROFILEPANEL_PCUSTOM;自定义 +PROFILEPANEL_PFILE;由文件 +PROFILEPANEL_PLASTPHOTO;上次图片 +PROFILEPANEL_PLASTSAVED;上次ä¿å­˜ +PROFILEPANEL_PROFILE;é…ç½® +PROFILEPANEL_SAVEDLGLABEL;ä¿å­˜å¤„ç†å‚数为... +PROFILEPANEL_TOOLTIPCOPY;将当å‰é…ç½®å¤åˆ¶åˆ°å‰ªè´´æ¿ +PROFILEPANEL_TOOLTIPLOAD;由文件加载é…ç½® +PROFILEPANEL_TOOLTIPPASTE;从剪贴æ¿ç²˜è´´é…ç½® +PROFILEPANEL_TOOLTIPSAVE;ä¿å­˜å½“å‰é…ç½® +PROGRESSBAR_DECODING;Raw文件解ç ä¸­... +PROGRESSBAR_DEMOSAICING;马赛克还原中... +PROGRESSBAR_LOADING;图片加载中... +PROGRESSBAR_LOADJPEG;JPEG文件加载中... +PROGRESSBAR_LOADPNG;PNG文件加载中... +PROGRESSBAR_LOADTIFF;TIFF文件加载中... +PROGRESSBAR_PROCESSING;图片处ç†ä¸­... +PROGRESSBAR_READY;就绪 +PROGRESSBAR_SAVEJPEG;JPEG文件ä¿å­˜ä¸­... +PROGRESSBAR_SAVEPNG;PNG文件ä¿å­˜ä¸­... +PROGRESSBAR_SAVETIFF;TIFF文件ä¿å­˜ä¸­... +PROGRESSDLG_LOADING;Loading file... +PROGRESSDLG_PROCESSING;Processing image... +PROGRESSDLG_SAVING;Saving file... +QINFO_FOCALLENGTH;ç„¦è· +QINFO_ISO;感光度 +QINFO_LENS;Lens +QINFO_NOEXIF;Exifæ•°æ®ä¸å¯ç”¨. +SAVEDLG_FILEFORMAT;æ–‡ä»¶æ ¼å¼ +SAVEDLG_JPEGQUAL;JPEGè´¨é‡ +SAVEDLG_JPGFILTER;JPEG文件 +SAVEDLG_PNGCOMPR;PNG压缩 +SAVEDLG_PNGFILTER;PNG文件 +SAVEDLG_PUTTOQUEUEHEAD;Put to the head of the processing queue +SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue +SAVEDLG_PUTTOQUEUE;放入队列 +SAVEDLG_SAVEIMMEDIATELY;ç«‹å³ä¿å­˜ +SAVEDLG_SAVESPP;éšå›¾ç‰‡ä¿å­˜å¤„ç†å‚æ•° +SAVEDLG_TIFFFILTER;TIFF文件 +TOOLBAR_TOOLTIP_CROP;剪è£é€‰æ‹© (shortcut key: C) +TOOLBAR_TOOLTIP_HAND;手形工具 (shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;基准线选择 (shortcut key: S) +TOOLBAR_TOOLTIP_WB;白平衡采样 (shortcut key: W) +TP_CACORRECTION_BLUE;è“ +TP_CACORRECTION_LABEL;色散矫正 +TP_CACORRECTION_RED;红 +TP_CHMIXER_BLUE;è“ +TP_CHMIXER_GREEN;绿 +TP_CHMIXER_LABEL;é€šé“æ··åˆ +TP_CHMIXER_RED;红 +TP_COARSETRAF_DEGREE;角度: +TP_COARSETRAF_TOOLTIP_HFLIP;水平翻转 +TP_COARSETRAF_TOOLTIP_ROTLEFT;左转 +TP_COARSETRAF_TOOLTIP_ROTRIGHT;å³è½¬ +TP_COARSETRAF_TOOLTIP_VFLIP;竖直翻转 +TP_COLORBOOST_ACHANNEL;é€šé“ "a" +TP_COLORBOOST_AMOUNT;程度 +TP_COLORBOOST_AVOIDCOLORCLIP;é¿å…色彩溢出 +TP_COLORBOOST_BCHANNEL;é€šé“ "b" +TP_COLORBOOST_CHAB;a å’Œ b +TP_COLORBOOST_CHANNEL;é€šé“ +TP_COLORBOOST_CHSEPARATE;分解 +TP_COLORBOOST_ENABLESATLIMITER;å¯ç”¨é¥±å’Œåº¦é™åˆ¶ +TP_COLORBOOST_LABEL;色彩增强 +TP_COLORBOOST_SATLIMIT;饱和度é™åˆ¶ +TP_COLORDENOISE_EDGESENSITIVE;è¾¹ç¼˜æ•æ„Ÿåº¦ +TP_COLORDENOISE_EDGETOLERANCE;边缘容差 +TP_COLORDENOISE_LABEL;色彩噪点抑制 +TP_COLORDENOISE_RADIUS;åŠå¾„ +TP_COLORSHIFT_BLUEYELLOW;è“-黄 +TP_COLORSHIFT_GREENMAGENTA;绿-洋红 +TP_COLORSHIFT_LABEL;色彩åç§» +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;比例: +TP_CROP_GTDIAGONALS;对角线法则 +TP_CROP_GTHARMMEANS1;黄金点 1 +TP_CROP_GTHARMMEANS2;黄金点 2 +TP_CROP_GTHARMMEANS3;黄金点 3 +TP_CROP_GTHARMMEANS4;黄金点 4 +TP_CROP_GTNONE;æ—  +TP_CROP_GTRULETHIRDS;1/3法则 +TP_CROP_GUIDETYPE;辅助方å¼: +TP_CROP_H;高 +TP_CROP_LABEL;å‰ªè£ +TP_CROP_SELECTCROP; 选择预设 +TP_CROP_W;宽 +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;程度 +TP_DISTORTION_LABEL;失真 +TP_EXPOSURE_AUTOLEVELS;自动色阶 +TP_EXPOSURE_BLACKLEVEL;黑 +TP_EXPOSURE_BRIGHTNESS;亮度 +TP_EXPOSURE_CLIP;高光溢出 +TP_EXPOSURE_COMPRHIGHLIGHTS;高光压缩 +TP_EXPOSURE_COMPRSHADOWS;阴影压缩 +TP_EXPOSURE_CONTRAST;对比度 +TP_EXPOSURE_CURVEEDITOR;影调曲线 +TP_EXPOSURE_EXPCOMP;æ›å…‰è¡¥å¿ +TP_EXPOSURE_LABEL;æ›å…‰ +TP_HLREC_CIELAB;CIELabæ¨¡å¼æ··åˆ +TP_HLREC_COLOR;色彩延伸 +TP_HLREC_LABEL;高光还原 +TP_HLREC_LUMINANCE;亮度还原 +TP_HLREC_METHOD;æ–¹å¼: +TP_ICM_FILEDLGFILTERANY;ä»»æ„æ–‡ä»¶ +TP_ICM_FILEDLGFILTERICM;ICCé…置文件 +TP_ICM_GAMMABEFOREINPUT;é…置应用Gammaæ ¡æ­£ +TP_ICM_INPUTCAMERA;ç›¸æœºç¼ºçœ +TP_ICM_INPUTCUSTOM;自定义 +TP_ICM_INPUTDLGLABEL;选择输入ICCé…ç½®... +TP_ICM_INPUTEMBEDDED;如å¯èƒ½ï¼Œä½¿ç”¨å†…ç½® +TP_ICM_INPUTPROFILE;输入é…ç½® +TP_ICM_LABEL;ICM +TP_ICM_NOICM;No ICM: sRGBé…ç½® +TP_ICM_OUTPUTDLGLABEL;选择输出ICCé…ç½®... +TP_ICM_OUTPUTPROFILE;输出é…ç½® +TP_ICM_SAVEREFERENCE;ä¿å­˜å‚考图片用于生æˆé…ç½®ä¿¡æ¯ +TP_ICM_WORKINGPROFILE;当å‰é…ç½® +TP_LUMACURVE_BLACKLEVEL;黑点 +TP_LUMACURVE_BRIGHTNESS;亮度 +TP_LUMACURVE_COMPRHIGHLIGHTS;高光压缩 +TP_LUMACURVE_COMPRSHADOWS;阴影压缩 +TP_LUMACURVE_CONTRAST;对比度 +TP_LUMACURVE_CURVEEDITOR;亮度曲线 +TP_LUMACURVE_LABEL;亮度曲线 +TP_LUMADENOISE_EDGETOLERANCE;边缘容差 +TP_LUMADENOISE_LABEL;亮度噪点抑制 +TP_LUMADENOISE_RADIUS;åŠå¾„ +TP_RESIZE_BICUBICSF;åŒä¸‰æ¬¡ (柔化) +TP_RESIZE_BICUBICSH;åŒä¸‰æ¬¡ (é”化) +TP_RESIZE_BICUBIC;åŒä¸‰æ¬¡ +TP_RESIZE_BILINEAR;åŒçº¿æ€§ +TP_RESIZE_FULLSIZE;全照片尺寸: +TP_RESIZE_H;高: +TP_RESIZE_LABEL;è°ƒæ•´å¤§å° +TP_RESIZE_METHOD;æ–¹å¼: +TP_RESIZE_NEAREST;最近点 +TP_RESIZE_SCALE;比例 +TP_RESIZE_W;宽: +TP_ROTATE_AUTOCROP;è‡ªåŠ¨å‰ªè£ +TP_ROTATE_DEGREE;角度 +TP_ROTATE_FILL;å¡«å…… +TP_ROTATE_LABEL;旋转 +TP_ROTATE_SELECTLINE; 选择基准线 +TP_SHADOWSHLIGHTS_HIGHLIGHTS;高光 +TP_SHADOWSHLIGHTS_HLTONALW;影调范围 +TP_SHADOWSHLIGHTS_LABEL;阴影/高光 +TP_SHADOWSHLIGHTS_LOCALCONTR;局部对比度 +TP_SHADOWSHLIGHTS_RADIUS;åŠå¾„ +TP_SHADOWSHLIGHTS_SHADOWS;阴影 +TP_SHADOWSHLIGHTS_SHTONALW;影调范围 +TP_SHARPENING_AMOUNT;程度 +TP_SHARPENING_EDRADIUS;åŠå¾„ +TP_SHARPENING_EDTOLERANCE;边缘容差 +TP_SHARPENING_HALOCONTROL;光晕控制 +TP_SHARPENING_HCAMOUNT;程度 +TP_SHARPENING_LABEL;é”化 +TP_SHARPENING_METHOD;æ–¹å¼ +TP_SHARPENING_ONLYEDGES;ä»…é”化边缘 +TP_SHARPENING_RADIUS;åŠå¾„ +TP_SHARPENING_RLD_AMOUNT;程度 +TP_SHARPENING_RLD_DAMPING;è¡°å‡ +TP_SHARPENING_RLD_ITERATIONS;迭代 +TP_SHARPENING_RLD;ç†æŸ¥æ£®-露西去å·ç§¯æ³• +TP_SHARPENING_THRESHOLD;阈值 +TP_SHARPENING_USM;虚åƒå±è”½ +TP_VIGNETTING_AMOUNT;程度 +TP_VIGNETTING_LABEL;暗角矫正 +TP_VIGNETTING_RADIUS;åŠå¾„ +TP_WBALANCE_AUTO;自动 +TP_WBALANCE_CAMERA;相机 +TP_WBALANCE_CUSTOM;自定义 +TP_WBALANCE_GREEN;色度 +TP_WBALANCE_LABEL;白平衡 +TP_WBALANCE_METHOD;æ–¹å¼ +TP_WBALANCE_SIZE;大å°: +TP_WBALANCE_SPOTWB;白平衡采样 +TP_WBALANCE_TEMPERATURE;色温 +ZOOMBAR_DETAIL;细节 +ZOOMBAR_HUGE;很大 +ZOOMBAR_LARGE;大 +ZOOMBAR_NORMAL;普通 +ZOOMBAR_PREVIEW;预览 +ZOOMBAR_SCALE;比例 +ZOOMBAR_SMALL;å° + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Chinese (Traditional) b/rtdata/languages/Chinese (Traditional) new file mode 100644 index 000000000..1d2067042 --- /dev/null +++ b/rtdata/languages/Chinese (Traditional) @@ -0,0 +1,703 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# 29.07.2008 +# Chinese Traditional +# Mingjui Liao +ADJUSTER_RESET_TO_DEFAULT;é‡ç½®é è¨­åƒæ•¸ +CURVEEDITOR_FILEDLGFILTERANY;ä»»æ„æ–‡ä»¶ +CURVEEDITOR_FILEDLGFILTERCURVE;曲線檔 +CURVEEDITOR_LINEAR;線性 +CURVEEDITOR_LOADDLGLABEL;正載入曲線... +CURVEEDITOR_SAVEDLGLABEL;正儲存曲線... +CURVEEDITOR_TOOLTIPLINEAR;é‡ç½®æ›²ç·š +CURVEEDITOR_TOOLTIPLOAD;載入曲線 +CURVEEDITOR_TOOLTIPSAVE;儲存曲線 +EXIFFILTER_APERTURE;Aperture +EXIFFILTER_CAMERA;Camera +EXIFFILTER_DIALOGLABEL;Exif Filter +EXIFFILTER_FOCALLEN;Focal Length +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Lens +EXIFFILTER_SHUTTER;Shutter +EXIFPANEL_ADDEDIT;Add/Edit +EXIFPANEL_ADDEDITHINT;Add new tag or edit tag +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Enter value +EXIFPANEL_ADDTAGDLG_SELECTTAG;Select tag +EXIFPANEL_ADDTAGDLG_TITLE;Add/Edit Tag +EXIFPANEL_KEEPHINT;Keep the selected tags when writing output file +EXIFPANEL_KEEP;Keep +EXIFPANEL_REMOVEHINT;Remove the selected tags when writing output file +EXIFPANEL_REMOVE;Remove +EXIFPANEL_RESETALLHINT;Reset all tags to their original values +EXIFPANEL_RESETALL;Reset All +EXIFPANEL_RESETHINT;Reset the selected tags to their original values +EXIFPANEL_RESET;Reset +EXIFPANEL_SUBDIRECTORY;Subdirectory +FILEBROWSER_APPLYPROFILE;Apply profile +FILEBROWSER_ARRANGEMENTHINT;Change between vertical/horizontal alignment of thumbnails +FILEBROWSER_CLEARPROFILE;Clear profile +FILEBROWSER_COPYPROFILE;Copy profile +FILEBROWSER_DELETEDLGLABEL;File delete confirmation +FILEBROWSER_DELETEDLGMSG;Are you sure you want to delete the selected %1 files? +FILEBROWSER_EMPTYTRASH;Empty Trash +FILEBROWSER_EMPTYTRASHHINT;Permanently delete the files of the trash +FILEBROWSER_EXIFFILTERAPPLY;Apply +FILEBROWSER_EXIFFILTERAPPLYHINT;Switch on/off exif filter of the file browser +FILEBROWSER_EXIFFILTERLABEL;Exif Filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Change settings of the exif filter +FILEBROWSER_EXIFFILTERSETTINGS;Setup +FILEBROWSER_PARTIALPASTEPROFILE;Partial paste +FILEBROWSER_PASTEPROFILE;Paste profile +FILEBROWSER_POPUPCANCELJOB;Cancel job +FILEBROWSER_POPUPMOVEEND;Move to end of queue +FILEBROWSER_POPUPMOVEHEAD;Move to head of queue +FILEBROWSER_POPUPOPEN;Open +FILEBROWSER_POPUPPROCESS;Put to processing queue +FILEBROWSER_POPUPRANK1;Rank 1 +FILEBROWSER_POPUPRANK2;Rank 2 +FILEBROWSER_POPUPRANK3;Rank 3 +FILEBROWSER_POPUPRANK4;Rank 4 +FILEBROWSER_POPUPRANK5;Rank 5 +FILEBROWSER_POPUPREMOVE;Remove from filesystem +FILEBROWSER_POPUPRENAME;Rename +FILEBROWSER_POPUPSELECTALL;Select all +FILEBROWSER_POPUPTRASH;Move to trash +FILEBROWSER_POPUPUNRANK;Unrank +FILEBROWSER_POPUPUNTRASH;Remove from trash +FILEBROWSER_PROCESSINGSETTINGSHINT;Set the file format and output directory +FILEBROWSER_PROCESSINGSETTINGS;Settings +FILEBROWSER_RENAMEDLGLABEL;Rename file +FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +FILEBROWSER_SHOWDIRHINT;Show all images of the directory +FILEBROWSER_SHOWQUEUEHINT;Show content of the processing queue +FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1 star +FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2 star +FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3 star +FILEBROWSER_SHOWRANK4HINT;Show images ranked as 4 star +FILEBROWSER_SHOWRANK5HINT;Show images ranked as 5 star +FILEBROWSER_SHOWTRASHHINT;Show content of the trash +FILEBROWSER_SHOWUNRANKHINT;Show unranked images +FILEBROWSER_STARTPROCESSINGHINT;Start processing/saving of images in the queue +FILEBROWSER_STARTPROCESSING;Start Processing +FILEBROWSER_STOPPROCESSINGHINT;Stop processing of images +FILEBROWSER_STOPPROCESSING;Stop processing +FILEBROWSER_THUMBSIZE;Thumb. size +FILEBROWSER_ZOOMINHINT;Increase thumbnail size +FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size +GENERAL_ABOUT;關於 +GENERAL_CANCEL;å–æ¶ˆ +GENERAL_DISABLED;已關閉 +GENERAL_DISABLE;關閉 +GENERAL_ENABLED;已開啟 +GENERAL_ENABLE;啟用 +GENERAL_LANDSCAPE;æ©«å‘ +GENERAL_LOAD;載入 +GENERAL_NA;ä¸é©ç”¨ +GENERAL_NO;å¦ +GENERAL_OK;確定 +GENERAL_PORTRAIT;ç¸±å‘ +GENERAL_SAVE;儲存存 +GENERAL_YES;是 +HISTOGRAM_LABEL;Histogram +HISTOGRAM_TOOLTIP_B;顯示/éš±è— è—色直方圖 +HISTOGRAM_TOOLTIP_G;顯示/éš±è— ç¶ è‰²ç›´æ–¹åœ– +HISTOGRAM_TOOLTIP_L;顯示/éš±è—e CIELAB 亮度直方圖 +HISTOGRAM_TOOLTIP_R;顯示/éš±è— ç´…è‰²ç›´æ–¹åœ– +HISTORY_CHANGED;Changed +HISTORY_CUSTOMCURVE;自定義曲線 +HISTORY_DELSNAPSHOT;移除快照 +HISTORY_FROMCLIPBOARD;From clipboard +HISTORY_LABEL;æ­·å² +HISTORY_MSG_10;暗部壓縮 +HISTORY_MSG_11;色調曲線 +HISTORY_MSG_12;自動æ›å…‰ +HISTORY_MSG_13;æ›å…‰æº¢å‡º +HISTORY_MSG_14;光強亮度 +HISTORY_MSG_15;光強尿¯”度 +HISTORY_MSG_16;光強黑 +HISTORY_MSG_17;光強亮部壓縮 +HISTORY_MSG_18;光強暗部壓縮 +HISTORY_MSG_19;光強曲線 +HISTORY_MSG_1;圖片載入完 +HISTORY_MSG_20;銳化 +HISTORY_MSG_21;銳化åŠå¾‘ +HISTORY_MSG_22;銳化程度 +HISTORY_MSG_23;銳化闕值 +HISTORY_MSG_24;僅銳化邊緣 +HISTORY_MSG_25;銳化邊緣åŠå¾‘ +HISTORY_MSG_26;銳化邊緣容差 +HISTORY_MSG_27;銳化光暈控制 +HISTORY_MSG_28;å…‰æšˆæŽ§åˆ¶é‡ +HISTORY_MSG_29;éŠ³åŒ–æ–¹å¼ +HISTORY_MSG_2;é…置載入完 +HISTORY_MSG_30;é‡ç–ŠåŠå¾‘ +HISTORY_MSG_31;é‡ç–Šç¨‹åº¦ +HISTORY_MSG_32;é‡ç–Šè¡°æ¸› +HISTORY_MSG_33;é‡ç–Šæ¬¡æ•¸ +HISTORY_MSG_34;é¿å…色彩溢出 +HISTORY_MSG_35;飽和度é™åˆ¶å™¨ +HISTORY_MSG_36;飽和度é™åˆ¶ +HISTORY_MSG_37;色彩增益 +HISTORY_MSG_38;æ‹å¹³è¡¡æ–¹å¼ +HISTORY_MSG_39;色溫 +HISTORY_MSG_3;é…置改變 +HISTORY_MSG_40;白平衡微調 +HISTORY_MSG_41;色彩åç§» "A" +HISTORY_MSG_42;色彩åç§» "B" +HISTORY_MSG_43;光強é™å™ª +HISTORY_MSG_44;光強é™å™ªåŠå¾‘ +HISTORY_MSG_45;光強é™å™ªé‚Šç·£å®¹å·® +HISTORY_MSG_46;色彩é™å™ª +HISTORY_MSG_47;色彩é™å™ªåŠå¾‘ +HISTORY_MSG_48;色彩é™å™ªé‚Šç·£å®¹å·® +HISTORY_MSG_49;色彩é™å™ªé‚Šç·£æ•感度 +HISTORY_MSG_4;æ­·å²æµè¦½ +HISTORY_MSG_50;暗部/亮部工具 +HISTORY_MSG_51;亮部增益 +HISTORY_MSG_52;暗部增益 +HISTORY_MSG_53;äº®éƒ¨è‰²åº¦ç¯„åœ +HISTORY_MSG_54;æš—éƒ¨è‰²åº¦ç¯„åœ +HISTORY_MSG_55;å±€éƒ¨å°æ¯”度 +HISTORY_MSG_56;暗部/亮部åŠå¾‘ +HISTORY_MSG_57;粗略旋轉 +HISTORY_MSG_58;水準翻轉 +HISTORY_MSG_59;豎直翻轉 +HISTORY_MSG_5;亮度 +HISTORY_MSG_60;旋轉 +HISTORY_MSG_61;旋轉 +HISTORY_MSG_62;é¡é ­å¤±çœŸçŸ¯æ­£ +HISTORY_MSG_63;設置書簽 +HISTORY_MSG_64;剪切圖片 +HISTORY_MSG_65;C/A矯正 +HISTORY_MSG_66;高光還原 +HISTORY_MSG_67;高光還原程度 +HISTORY_MSG_68;é«˜å…‰é‚„åŽŸæ–¹å¼ +HISTORY_MSG_69;工作色彩空間 +HISTORY_MSG_6;å°æ¯”度 +HISTORY_MSG_70;輸出色彩空間 +HISTORY_MSG_71;輸入色åƒç©ºé–“ +HISTORY_MSG_72;邊暈矯正 +HISTORY_MSG_73;é€šé“æ··åˆå™¨ +HISTORY_MSG_74;èª¿æ•´å¤§å°æ¯”例 +HISTORY_MSG_75;èª¿æ•´å¤§å°æ–¹å¼ +HISTORY_MSG_76;Exif Metadata +HISTORY_MSG_77;IPTC Metadata +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;黑 +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;æ›å…‰è£œå„Ÿ +HISTORY_MSG_9;亮部壓縮 +HISTORY_NEWSNAPSHOTAS;為... +HISTORY_NEWSNAPSHOT;新建快照 +HISTORY_NEWSSDIALOGLABEL;快照標籤: +HISTORY_NEWSSDIALOGTITLE;添加新快照 +HISTORY_SETTO;設置為 +HISTORY_SNAPSHOTS;系列快照 +HISTORY_SNAPSHOT;å¿«ç…§ +ICMPANEL_FILEDLGFILTERANY;ä»»æ„æ–‡ä»¶ +ICMPANEL_FILEDLGFILTERICM;ICCé…置檔 +ICMPANEL_GAMMABEFOREINPUT;Profile applies Gamma +ICMPANEL_INPUTCAMERA;相機é è¨­ +ICMPANEL_INPUTCUSTOM;自定義 +ICMPANEL_INPUTDLGLABEL;鏿“‡è¼¸å…¥ICCé…ç½®... +ICMPANEL_INPUTEMBEDDED;如å¯èƒ½ï¼Œä½¿ç”¨å…§ç½® +ICMPANEL_INPUTPROFILE;輸入é…ç½® +ICMPANEL_NOICM;No ICM: sRGBé…ç½® +ICMPANEL_OUTPUTDLGLABEL;鏿“‡è¼¸å‡ºICCé…ç½®... +ICMPANEL_OUTPUTPROFILE;輸出é…ç½® +ICMPANEL_SAVEREFERENCE;Save reference image for profiling +ICMPANEL_WORKINGPROFILE;ç•¶å‰é…ç½® +IMAGEAREA_DETAILVIEW;細節視圖 +IPTCPANEL_AUTHOR;Author +IPTCPANEL_AUTHORHINT;Name of the creator of the object, e.g. writer, photographer or graphic artist (By-line). +IPTCPANEL_AUTHORSPOSITION;Author's position +IPTCPANEL_AUTHORSPOSITIONHINT;Title of the creator or creators of the object (By-line Title). +IPTCPANEL_CAPTION;Caption +IPTCPANEL_CAPTIONHINT;A textual description of the data (Caption - Abstract) +IPTCPANEL_CAPTIONWRITER;Caption Writer +IPTCPANEL_CAPTIONWRITERHINT;The name of the person involved in the writing, editing or correcting the image or caption/abstract (Writer - Editor +IPTCPANEL_CATEGORY;Category +IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider (Category). +IPTCPANEL_CITY;City +IPTCPANEL_CITYHINT;City of image origin (City). +IPTCPANEL_COPYHINT;Copy IPTC settings to clipboard +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COPYRIGHTHINT;Any necessary copyright notice (Copyright Notice). +IPTCPANEL_COUNTRY;Country +IPTCPANEL_COUNTRYHINT;The name of the country/primary location where the image was created (Country - Primary Location Name). +IPTCPANEL_CREDIT;Credit +IPTCPANEL_CREDITHINT;Identifies the provider of the image, not necessarily the owner/creator (Credit). +IPTCPANEL_DATECREATED;Date Created +IPTCPANEL_DATECREATEDHINT;The date the intellectual content of the image was created; Format: JJJJMMTT (Date Created). +IPTCPANEL_EMBEDDED;Embedded +IPTCPANEL_EMBEDDEDHINT;Reset to IPTC data embedded in the image file +IPTCPANEL_HEADLINE;Headline +IPTCPANEL_HEADLINEHINT;A publishable entry providing a synopsis of the contents of the image (Headline). +IPTCPANEL_INSTRUCTIONSHINT;Other editorial instructions concerning the use of the image (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Instructions +IPTCPANEL_KEYWORDSHINT;Used to indicate specific information retrieval words (keywords). +IPTCPANEL_KEYWORDS;Keywords +IPTCPANEL_PASTEHINT;Paste IPTC settings from clipboard +IPTCPANEL_PROVINCEHINT;The Province/State where the image originates (Province-State). +IPTCPANEL_PROVINCE;Province +IPTCPANEL_RESETHINT;Reset to profile default +IPTCPANEL_RESET;Reset +IPTCPANEL_SOURCEHINT;The original owner of the intellectual content of the image (Source). +IPTCPANEL_SOURCE;Source +IPTCPANEL_SUPPCATEGORIESHINT;Further refines the subject of the image (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Suppl. Categories +IPTCPANEL_TITLEHINT;A shorthand reference for the image (Object Name). +IPTCPANEL_TITLE;Title +IPTCPANEL_TRANSREFERENCEHINT;A code representing the location of original transmission (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Trans. Reference +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;åƒæ•¸è¨­ç½® +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;為... +MAIN_BUTTON_SAVE;儲存圖片 +MAIN_BUTTON_SENDTOEDITOR;Send to editor +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;該文件已存在. +MAIN_MSG_CANNOTLOAD;無法載入圖片 +MAIN_MSG_CANNOTSAVE;檔儲存中出錯 +MAIN_MSG_CANNOTSTARTEDITOR;Can not start editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Please set the correct path in the "Preferences" dialog. +MAIN_MSG_EXITJOBSINQUEUEINFO;Unprocessed images in the queue will be lost on exit. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Are you sure you want to exit? There are unprocessed images waiting in the queue. +MAIN_MSG_JOBSINQUEUE;任務列隊中 +MAIN_MSG_QOVERWRITE;是å¦è¦†è“‹? +MAIN_TAB_BASIC;基本 +MAIN_TAB_COLOR;Color +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Exposure +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;è½‰æ› +MAIN_TOOLTIP_HIDEFP;顯示/éš±è—åº•éƒ¨é¢æ¿ (目錄和檔æµè¦½å™¨, shortcut key: F) +MAIN_TOOLTIP_HIDEHP;顯示/éš±è—左颿¿ (åŒ…å«æ­·å², shortcut key: H)) +MAIN_TOOLTIP_INDCLIPPEDH;高光溢出æç¤º +MAIN_TOOLTIP_INDCLIPPEDS;暗部ä¸è¶³æç¤º +MAIN_TOOLTIP_PREFERENCES;è¨­ç½®åƒæ•¸ +MAIN_TOOLTIP_QINFO;圖片快æ·è³‡è¨Š +MAIN_TOOLTIP_SAVEAS;圖片存於指定檔夾 +MAIN_TOOLTIP_SAVE;圖片存於é è¨­æª”夾 +PARTIALPASTE_BASICGROUP;Basic settings +PARTIALPASTE_CACORRECTION;C/A correction +PARTIALPASTE_COARSETRANS;90 deg rotation / flipping +PARTIALPASTE_COLORBOOST;Color boost +PARTIALPASTE_COLORDENOISE;Color denoise +PARTIALPASTE_COLORGROUP;Color related settings +PARTIALPASTE_COLORMIXER;Color mixer +PARTIALPASTE_COLORSHIFT;Color shift +PARTIALPASTE_COMPOSITIONGROUP;Composition settings +PARTIALPASTE_CROP;Crop +PARTIALPASTE_DIALOGLABEL;Partial paste processing profile +PARTIALPASTE_DISTORTION;Distortion correction +PARTIALPASTE_EXIFCHANGES;Changes to exif data +PARTIALPASTE_EXPOSURE;Exposure +PARTIALPASTE_HLRECOVERY;Highlight recovery +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Lens related settings +PARTIALPASTE_LUMACURVE;Luminance curve +PARTIALPASTE_LUMADENOISE;Luminance noise reduction +PARTIALPASTE_LUMINANCEGROUP;Luminance related settings +PARTIALPASTE_METAICMGROUP;Metadata/ICM settings +PARTIALPASTE_RESIZE;Resize +PARTIALPASTE_ROTATION;Rotation +PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights +PARTIALPASTE_SHARPENING;Sharpening +PARTIALPASTE_VIGNETTING;Vignetting correction +PARTIALPASTE_WHITEBALANCE;White balance +PREFERENCES_APPLNEXTSTARTUP;下次啟動生效 +PREFERENCES_BLINKCLIPPED;高光å€åŸŸé–ƒçˆ +PREFERENCES_CACHECLEARALL;Clear All +PREFERENCES_CACHECLEARPROFILES;Clear Profiles +PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +PREFERENCES_CACHEFORMAT1;Proprietary (faster and better quality) +PREFERENCES_CACHEFORMAT2;JPEG (smaller disk footprint) +PREFERENCES_CACHEMAXENTRIES;Maximal Number of Cache Entries +PREFERENCES_CACHEOPTS;Cache Options +PREFERENCES_CACHESTRAT1;Prefer Speed to Low Memory Consumption +PREFERENCES_CACHESTRAT2;Prefer Low Memory Consumption to Speed +PREFERENCES_CACHESTRAT;Cache Strategy +PREFERENCES_CACHETHUMBFORM;Cache Thumbnail Format +PREFERENCES_CACHETHUMBHEIGHT;Maximal Thumbnail Height +PREFERENCES_CLEARDLG_LINE1;Clearing cache +PREFERENCES_CLEARDLG_LINE2;This may take a few seconds. +PREFERENCES_CLEARDLG_TITLE;Please wait +PREFERENCES_CLIPPINGIND;高光æç¤º +PREFERENCES_CMETRICINTENT;è‰²å½©æ¨¡å¼ +PREFERENCES_DATEFORMATHINT;You can use the following formatting strings:\n%y : year\n%m : month\n%d : day\n\nFor example, the hungarian date format is:\n%y/%m/%d +PREFERENCES_DATEFORMAT;æ—¥æœŸæ ¼å¼ +PREFERENCES_DEFAULTLANG;é è¨­èªžè¨€ +PREFERENCES_DEFAULTTHEME;Default theme +PREFERENCES_DEMOSAICINGALGO;解拼演算法 +PREFERENCES_DIRHOME;用戶檔路徑 +PREFERENCES_DIRLAST;上次訪å•路徑 +PREFERENCES_DIROTHER;å…¶ä»– +PREFERENCES_DIRSELECTDLG;å•Ÿå‹•æ™‚é¸æ“‡åœ–片路徑... +PREFERENCES_DIRSOFTWARE;軟體安è£è·¯å¾‘ +PREFERENCES_DMETHOD;æ–¹å¼ +PREFERENCES_EDITORCMDLINE;Other command line +PREFERENCES_EXTERNALEDITOR;External editor +PREFERENCES_FALSECOLOR;è™›å‡è‰²å½©å£“縮步驟 +PREFERENCES_FBROWSEROPTS;檔æµè¦½é¸é … +PREFERENCES_FILEFORMAT;æª”æ ¼å¼ +PREFERENCES_FORIMAGE;用於圖片檔 +PREFERENCES_FORRAW;用於Raw文件 +PREFERENCES_GIMPPATH;GIMP installation directory +PREFERENCES_GTKTHEME;GTK default +PREFERENCES_HINT;æç¤º +PREFERENCES_HLTHRESHOLD;高光溢出闕值 +PREFERENCES_ICCDIR;ICCé…置路徑 +PREFERENCES_IMPROCPARAMS;é è¨­åœ–片處ç†åƒæ•¸ +PREFERENCES_INTENT_ABSOLUTE;絕å°è‰²å½©æ¨¡å¼ +PREFERENCES_INTENT_PERCEPTUAL;æ„ŸçŸ¥æ¨¡å¼ +PREFERENCES_INTENT_RELATIVE;相å°è‰²å½©æ¨¡å¼ +PREFERENCES_INTENT_SATURATION;飽和度 +PREFERENCES_LIVETHUMBNAILS;Live Thumbnails (slower) +PREFERENCES_MONITORICC;顯示器é…ç½® +PREFERENCES_OUTDIRFOLDERHINT;Put the saved images to the seledted folder +PREFERENCES_OUTDIRFOLDER;Save to folder +PREFERENCES_OUTDIRHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Use Template +PREFERENCES_OUTDIR;輸出路徑 +PREFERENCES_PARSEDEXTADD;Add Extension +PREFERENCES_PARSEDEXTADDHINT;Type an extension and press this button to append list +PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list +PREFERENCES_PARSEDEXT;Parsed Extensions +PREFERENCES_PROFILEHANDLING;Processing Profile Handling +PREFERENCES_PROFILELOADPR;Profile Loading Priority +PREFERENCES_PROFILEPRCACHE;Profile in Cache +PREFERENCES_PROFILEPRFILE;Profile Next to the Input File +PREFERENCES_PROFILESAVECACHE;Save Processing Parameters to the Cache +PREFERENCES_PROFILESAVEINPUT;Save Processing Parameters Next to the Input File +PREFERENCES_PSPATH;Adobe Photoshop installation directory +PREFERENCES_SELECTICCDIRDLG;鏿“‡ICC路徑... +PREFERENCES_SELECTLANG;鏿“‡èªžè¨€ +PREFERENCES_SELECTMONITORPROFDLG;鏿“‡é¡¯ç¤ºå™¨ICC路徑... +PREFERENCES_SELECTTHEME;Select theme +PREFERENCES_SHOWBASICEXIF;顯示基本Exif資訊 +PREFERENCES_SHOWDATETIME;顯示時間日期 +PREFERENCES_SHOWONLYRAW;僅顯示Raw檔 +PREFERENCES_SHTHRESHOLD;暗部ä¸è¶³é—•值 +PREFERENCES_STARTUPIMDIR;啟動時路徑 +PREFERENCES_TAB_BROWSER;檔æµè¦½å™¨ +PREFERENCES_TAB_COLORMGR;è‰²å½©ç®¡ç† +PREFERENCES_TAB_GENERAL;一般 +PREFERENCES_TAB_IMPROC;åœ–ç‰‡è™•ç† +PREFERENCES_TAB_OUTPUT;輸出é¸é … +PREFERENCES_THUMBSIZE;ç¸®ç•¥åœ–å¤§å° +PROFILEPANEL_FILEDLGFILTERANY;ä»»æ„æ–‡ä»¶ +PROFILEPANEL_FILEDLGFILTERPP;處ç†åƒæ•¸é…ç½® +PROFILEPANEL_LABEL;處ç†åƒæ•¸é…ç½® +PROFILEPANEL_LOADDLGLABEL;載入處ç†åƒæ•¸ç‚º... +PROFILEPANEL_PCUSTOM;自定義 +PROFILEPANEL_PFILE;由文件 +PROFILEPANEL_PLASTPHOTO;上次圖片 +PROFILEPANEL_PLASTSAVED;上次儲存 +PROFILEPANEL_PROFILE;é…ç½® +PROFILEPANEL_SAVEDLGLABEL;儲存處ç†åƒæ•¸ç‚º... +PROFILEPANEL_TOOLTIPCOPY;Copy current profile to clipboard +PROFILEPANEL_TOOLTIPLOAD;由檔載入é…ç½® +PROFILEPANEL_TOOLTIPPASTE; Paste profile from clipboard +PROFILEPANEL_TOOLTIPSAVE;儲存當å‰é…ç½® +PROGRESSBAR_DECODING;Raw檔解碼中... +PROGRESSBAR_DEMOSAICING;Raw檔解拼中... +PROGRESSBAR_LOADING;圖片載入中... +PROGRESSBAR_LOADJPEG;JPEG載入中... +PROGRESSBAR_LOADPNG;PNG載入中... +PROGRESSBAR_LOADTIFF;TIFF載入中... +PROGRESSBAR_PROCESSING;圖片處ç†ä¸­... +PROGRESSBAR_READY;就緒. +PROGRESSBAR_SAVEJPEG;JPEG儲存中... +PROGRESSBAR_SAVEPNG;PNG儲存中... +PROGRESSBAR_SAVETIFF;TIFF儲存中... +PROGRESSDLG_LOADING;Loading file... +PROGRESSDLG_PROCESSING;Processing image... +PROGRESSDLG_SAVING;Saving file... +QINFO_FOCALLENGTH;ç„¦è· +QINFO_ISO;ISO +QINFO_LENS;Lens +QINFO_NOEXIF;Exif資料ä¸å¯ç”¨. +SAVEDLG_FILEFORMAT;æª”æ ¼å¼ +SAVEDLG_JPEGQUAL;JPEGå“質 +SAVEDLG_JPGFILTER;JPEG文件 +SAVEDLG_PNGCOMPR;PNG壓縮 +SAVEDLG_PNGFILTER;PNG文件 +SAVEDLG_PUTTOQUEUEHEAD;Put to the head of the processing queue +SAVEDLG_PUTTOQUEUE;Put into processing queue +SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue +SAVEDLG_SAVEIMMEDIATELY;Save immediately +SAVEDLG_SAVESPP;隨圖片儲存處ç†åƒæ•¸ +SAVEDLG_TIFFFILTER;TIFF文件 +TOOLBAR_TOOLTIP_CROP;剪è£é¸æ“‡ (shortcut key: C) +TOOLBAR_TOOLTIP_HAND;手形工具 (shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;åŸºæº–ç·šé¸æ“‡ (shortcut key: S) +TOOLBAR_TOOLTIP_WB;白平衡點 (shortcut key: W) +TP_CACORRECTION_BLUE;è— +TP_CACORRECTION_LABEL;C/A 矯正 +TP_CACORRECTION_RED;ç´… +TP_CHMIXER_BLUE;è— +TP_CHMIXER_GREEN;ç¶  +TP_CHMIXER_LABEL;é€šé“æ··åˆ +TP_CHMIXER_RED;ç´… +TP_COARSETRAF_DEGREE;角度: +TP_COARSETRAF_TOOLTIP_HFLIP;水準翻轉 +TP_COARSETRAF_TOOLTIP_ROTLEFT;左轉 +TP_COARSETRAF_TOOLTIP_ROTRIGHT;å³è½‰ +TP_COARSETRAF_TOOLTIP_VFLIP;豎直翻轉 +TP_COLORBOOST_ACHANNEL;é€šé“ "a" +TP_COLORBOOST_AMOUNT;程度 +TP_COLORBOOST_AVOIDCOLORCLIP;é¿å…色彩溢出 +TP_COLORBOOST_BCHANNEL;é€šé“ "b" +TP_COLORBOOST_CHAB;a å’Œ b +TP_COLORBOOST_CHANNEL;é€šé“ +TP_COLORBOOST_CHSEPARATE;分解 +TP_COLORBOOST_ENABLESATLIMITER;啟用飽和度é™åˆ¶ +TP_COLORBOOST_LABEL;色彩增益 +TP_COLORBOOST_SATLIMIT;飽和度é™åˆ¶ +TP_COLORDENOISE_EDGESENSITIVE;é‚Šç·£æ•æ„Ÿåº¦ +TP_COLORDENOISE_EDGETOLERANCE;邊緣容差 +TP_COLORDENOISE_LABEL;色彩噪點抑制 +TP_COLORDENOISE_RADIUS;åŠå¾‘ +TP_COLORSHIFT_BLUEYELLOW;è—-黃 +TP_COLORSHIFT_GREENMAGENTA;ç¶ -æ´‹ç´… +TP_COLORSHIFT_LABEL;色彩åç§» +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;比例: +TP_CROP_GTDIAGONALS;å°è§’線法則 +TP_CROP_GTHARMMEANS1;黃金點 1 +TP_CROP_GTHARMMEANS2;黃金點 2 +TP_CROP_GTHARMMEANS3;黃金點 3 +TP_CROP_GTHARMMEANS4;黃金點 4 +TP_CROP_GTNONE;ç„¡ +TP_CROP_GTRULETHIRDS;1/3法則 +TP_CROP_GUIDETYPE;輔助方å¼: +TP_CROP_H;高 +TP_CROP_LABEL;å‰ªè£ +TP_CROP_SELECTCROP; 鏿“‡é è¨­ +TP_CROP_W;寬 +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;程度 +TP_DISTORTION_LABEL;ç•«é¢æ­ªæ›²åƒå·® +TP_EXPOSURE_AUTOLEVELS;自動色階 +TP_EXPOSURE_BLACKLEVEL;黑 +TP_EXPOSURE_BRIGHTNESS;亮度 +TP_EXPOSURE_CLIP;高光 +TP_EXPOSURE_COMPRHIGHLIGHTS;亮部壓縮 +TP_EXPOSURE_COMPRSHADOWS;暗部壓縮 +TP_EXPOSURE_CONTRAST;å°æ¯”度 +TP_EXPOSURE_CURVEEDITOR;色調曲線 +TP_EXPOSURE_EXPCOMP;æ›å…‰è£œå„Ÿ +TP_EXPOSURE_LABEL;æ›å…‰ +TP_HLREC_CIELAB;CIELab Blending +TP_HLREC_COLOR;色彩延伸 +TP_HLREC_LABEL;高光挽回 +TP_HLREC_LUMINANCE;亮度挽回 +TP_HLREC_METHOD;æ–¹å¼: +TP_ICM_FILEDLGFILTERANY;ä»»æ„æ–‡ä»¶ +TP_ICM_FILEDLGFILTERICM;ICCé…置檔 +TP_ICM_GAMMABEFOREINPUT;Profile applies Gamma +TP_ICM_INPUTCAMERA;相機é è¨­ +TP_ICM_INPUTCUSTOM;自定義 +TP_ICM_INPUTDLGLABEL;鏿“‡è¼¸å…¥ICCé…ç½®... +TP_ICM_INPUTEMBEDDED;如å¯èƒ½ï¼Œä½¿ç”¨å…§ç½® +TP_ICM_INPUTPROFILE;輸入é…ç½® +TP_ICM_LABEL;ICM +TP_ICM_NOICM;No ICM: sRGBé…ç½® +TP_ICM_OUTPUTDLGLABEL;鏿“‡è¼¸å‡ºICCé…ç½®... +TP_ICM_OUTPUTPROFILE;輸出é…ç½® +TP_ICM_SAVEREFERENCE;Save reference image for profiling +TP_ICM_WORKINGPROFILE;ç•¶å‰é…ç½® +TP_LUMACURVE_BLACKLEVEL;黑 +TP_LUMACURVE_BRIGHTNESS;亮度 +TP_LUMACURVE_COMPRHIGHLIGHTS;亮部壓縮 +TP_LUMACURVE_COMPRSHADOWS;暗部壓縮 +TP_LUMACURVE_CONTRAST;å°æ¯”度 +TP_LUMACURVE_CURVEEDITOR;亮度曲線 +TP_LUMACURVE_LABEL;亮度曲線 +TP_LUMADENOISE_EDGETOLERANCE;邊緣容差 +TP_LUMADENOISE_LABEL;亮度噪點抑制 +TP_LUMADENOISE_RADIUS;åŠå¾‘ +TP_RESIZE_BICUBICSF;雙三次 (柔化) +TP_RESIZE_BICUBICSH;雙三次 (銳化) +TP_RESIZE_BICUBIC;雙三次 +TP_RESIZE_BILINEAR;雙線性 +TP_RESIZE_FULLSIZE;全照片尺寸: +TP_RESIZE_H;高: +TP_RESIZE_LABEL;èª¿æ•´å¤§å° +TP_RESIZE_METHOD;æ–¹å¼: +TP_RESIZE_NEAREST;最近點 +TP_RESIZE_SCALE;比例 +TP_RESIZE_W;寬: +TP_ROTATE_AUTOCROP;è‡ªå‹•å‰ªè£ +TP_ROTATE_DEGREE;角度 +TP_ROTATE_FILL;å¡«å…… +TP_ROTATE_LABEL;旋轉 +TP_ROTATE_SELECTLINE; 鏿“‡åŸºæº–ç·š +TP_SHADOWSHLIGHTS_HIGHLIGHTS;亮部 +TP_SHADOWSHLIGHTS_HLTONALW;è‰²èª¿ç¯„åœ +TP_SHADOWSHLIGHTS_LABEL;暗部/亮部 +TP_SHADOWSHLIGHTS_LOCALCONTR;å±€éƒ¨å°æ¯”度 +TP_SHADOWSHLIGHTS_RADIUS;åŠå¾‘ +TP_SHADOWSHLIGHTS_SHADOWS;é™°å½± +TP_SHADOWSHLIGHTS_SHTONALW;è‰²èª¿ç¯„åœ +TP_SHARPENING_AMOUNT;程度 +TP_SHARPENING_EDRADIUS;åŠå¾‘ +TP_SHARPENING_EDTOLERANCE;邊緣容差 +TP_SHARPENING_HALOCONTROL;光暈控制 +TP_SHARPENING_HCAMOUNT;程度 +TP_SHARPENING_LABEL;銳化 +TP_SHARPENING_METHOD;æ–¹å¼ +TP_SHARPENING_ONLYEDGES;僅銳化邊緣 +TP_SHARPENING_RADIUS;åŠå¾‘ +TP_SHARPENING_RLD_AMOUNT;程度 +TP_SHARPENING_RLD_DAMPING;衰減 +TP_SHARPENING_RLD_ITERATIONS;迭代 +TP_SHARPENING_RLD;å·¦å³é‡ç–Š +TP_SHARPENING_THRESHOLD;闕值 +TP_SHARPENING_USM;銳化 +TP_VIGNETTING_AMOUNT;程度 +TP_VIGNETTING_LABEL;邊暈矯正 +TP_VIGNETTING_RADIUS;åŠå¾‘ +TP_WBALANCE_AUTO;自動 +TP_WBALANCE_CAMERA;相機 +TP_WBALANCE_CUSTOM;自定義 +TP_WBALANCE_GREEN;色度 +TP_WBALANCE_LABEL;白平衡 +TP_WBALANCE_METHOD;æ–¹å¼ +TP_WBALANCE_SIZE;大å°: +TP_WBALANCE_SPOTWB;WB點 +TP_WBALANCE_TEMPERATURE;色溫 +ZOOMBAR_DETAIL;細節 +ZOOMBAR_HUGE;很大 +ZOOMBAR_LARGE;大 +ZOOMBAR_NORMAL;普通 +ZOOMBAR_PREVIEW;é è¦½ +ZOOMBAR_SCALE;比例 +ZOOMBAR_SMALL;å° + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Czech b/rtdata/languages/Czech new file mode 100644 index 000000000..69fe26fe4 --- /dev/null +++ b/rtdata/languages/Czech @@ -0,0 +1,707 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# czech +# ---------------------------------------- +# 20.1.2008: translated by absolution +# 21.2.2008: updated by mkyral (typos and some missing strings) +# 24.4.2008: updated by mkyral (for version 2.4m1) +# 28.10.2008: updated by mkyral (for version 2.4 beta1) +# +ADJUSTER_RESET_TO_DEFAULT;Vrátit se k původnímu +CURVEEDITOR_FILEDLGFILTERANY;Jakékoliv soubory +CURVEEDITOR_FILEDLGFILTERCURVE;Soubory kÅ™ivek +CURVEEDITOR_LINEAR;Lineární +CURVEEDITOR_LOADDLGLABEL;NaÄíst kÅ™ivku... +CURVEEDITOR_SAVEDLGLABEL;Uložit kÅ™ivku... +CURVEEDITOR_TOOLTIPLINEAR;Vrátit se k lineární kÅ™ivce +CURVEEDITOR_TOOLTIPLOAD;NaÄíst kÅ™ivku ze souboru +CURVEEDITOR_TOOLTIPSAVE;Uložit souÄasnou kÅ™ivku +EXIFFILTER_APERTURE;Clona +EXIFFILTER_CAMERA;Aparát +EXIFFILTER_DIALOGLABEL;Filtruj dle Exif +EXIFFILTER_FOCALLEN;Ohnisková vzdálenost +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objektiv +EXIFFILTER_SHUTTER;Rychlost závÄ›rky +EXIFPANEL_ADDEDITHINT;PÅ™idej/Oprav Å¡títek +EXIFPANEL_ADDEDIT;PÅ™idej/Změň +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Vlož hodnotu +EXIFPANEL_ADDTAGDLG_SELECTTAG;Vyber Å¡títek +EXIFPANEL_ADDTAGDLG_TITLE;PÅ™idej/Změň Å¡títek +EXIFPANEL_KEEPHINT;Ulož vybrané Å¡títky pÅ™i zápisu do souboru +EXIFPANEL_KEEP;Zachovej +EXIFPANEL_REMOVEHINT;Neulož vybrané Å¡títky pÅ™i zápisu do souboru +EXIFPANEL_REMOVE;ZahoÄ +EXIFPANEL_RESETALLHINT;Obnov původní hodnoty u vÅ¡ech Å¡títků +EXIFPANEL_RESETALL;Obnov vÅ¡e +EXIFPANEL_RESETHINT;Obnov původní hodnoty u vybraných Å¡títků +EXIFPANEL_RESET;Obnov +EXIFPANEL_SUBDIRECTORY;Podadresář +FILEBROWSER_APPLYPROFILE;Aplikuj profil +FILEBROWSER_ARRANGEMENTHINT;PÅ™epnutí mezi vertikálním/horizontálním zarovnáním náhledů +FILEBROWSER_CLEARPROFILE;Vymaž profil +FILEBROWSER_COPYPROFILE;Kopíruj profil +FILEBROWSER_DELETEDLGLABEL;Potvrzení smazání souboru +FILEBROWSER_DELETEDLGMSG;Opravdu chcete vymazat %1 souborů? +FILEBROWSER_EMPTYTRASHHINT;Navždy vymaže soubory v koÅ¡i +FILEBROWSER_EMPTYTRASH;Vysypat koÅ¡ +FILEBROWSER_EXIFFILTERAPPLYHINT;Zapne/Vypne filtrování dle exif v prohlížeÄi souborů +FILEBROWSER_EXIFFILTERAPPLY;Použij +FILEBROWSER_EXIFFILTERLABEL;Exif Filtr +FILEBROWSER_EXIFFILTERSETTINGSHINT;ZmÄ›na nastavení exif filtru +FILEBROWSER_EXIFFILTERSETTINGS;Nastavení +FILEBROWSER_PARTIALPASTEPROFILE;Vlož ÄásteÄnÄ› +FILEBROWSER_PASTEPROFILE;Vlož profil +FILEBROWSER_POPUPCANCELJOB;ZruÅ¡ úlohu +FILEBROWSER_POPUPMOVEEND;PÅ™esuň na konec fronty +FILEBROWSER_POPUPMOVEHEAD;PÅ™esuň na zaÄátek fronty +FILEBROWSER_POPUPOPEN;OtevÅ™i +FILEBROWSER_POPUPPROCESS;Vlož do fronty +FILEBROWSER_POPUPRANK1;Hodnocení 1 +FILEBROWSER_POPUPRANK2;Hodnocení 2 +FILEBROWSER_POPUPRANK3;Hodnocení 3 +FILEBROWSER_POPUPRANK4;Hodnocení 4 +FILEBROWSER_POPUPRANK5;Hodnocení 5 +FILEBROWSER_POPUPREMOVE;Odstraň ze systému souborů +FILEBROWSER_POPUPRENAME;PÅ™ejmenuj +FILEBROWSER_POPUPSELECTALL;Vyber vÅ¡e +FILEBROWSER_POPUPTRASH;PÅ™esuň do koÅ¡e +FILEBROWSER_POPUPUNRANK;Odstraň hodnocení +FILEBROWSER_POPUPUNTRASH;Vymaž z koÅ¡e +FILEBROWSER_PROCESSINGSETTINGSHINT;Nastavení formátu souboru a výstupního adresáře +FILEBROWSER_PROCESSINGSETTINGS;Nastavení +FILEBROWSER_RENAMEDLGLABEL;PÅ™ejmenování souboru +FILEBROWSER_RENAMEDLGMSG;PÅ™ejmenovat soubor "%1" na: +FILEBROWSER_SHOWDIRHINT;Ukaž vÅ¡echny obrázky v adresáři +FILEBROWSER_SHOWQUEUEHINT;Ukaž obsah fronty +FILEBROWSER_SHOWRANK1HINT;Ukaž obrázky hodnocené 1 hvÄ›zdiÄkou +FILEBROWSER_SHOWRANK2HINT;Ukaž obrázky hodnocené 2 hvÄ›zdiÄkama +FILEBROWSER_SHOWRANK3HINT;Ukaž obrázky hodnocené 3 hvÄ›zdiÄkama +FILEBROWSER_SHOWRANK4HINT;Ukaž obrázky hodnocené 4 hvÄ›zdiÄkama +FILEBROWSER_SHOWRANK5HINT;Ukaž obrázky hodnocené 5 hvÄ›zdiÄkama +FILEBROWSER_SHOWTRASHHINT;Ukaž obsah koÅ¡e +FILEBROWSER_SHOWUNRANKHINT;Ukaž nehodnocené obrázky +FILEBROWSER_STARTPROCESSINGHINT;Spustí zpracování nebo ukládání obrázků ve frontÄ› +FILEBROWSER_STARTPROCESSING;SpusÅ¥ zpracování +FILEBROWSER_STOPPROCESSINGHINT;Zastaví zpracovávaní obrázků +FILEBROWSER_STOPPROCESSING;Zastav zpracovávaní +FILEBROWSER_THUMBSIZE;Velikost náhledů +FILEBROWSER_ZOOMINHINT;ZvÄ›tší velikost náhledů +FILEBROWSER_ZOOMOUTHINT;Zmenší velikost náhledů +GENERAL_ABOUT;O programu +GENERAL_CANCEL;Storno +GENERAL_DISABLED;Vypnuto +GENERAL_DISABLE;Vypnout +GENERAL_ENABLED;Zapnuto +GENERAL_ENABLE;Zapnout +GENERAL_LANDSCAPE;Na šířku +GENERAL_LOAD;NaÄíst +GENERAL_NA;n/a +GENERAL_NO;Ne +GENERAL_OK;OK +GENERAL_PORTRAIT;Na výšku +GENERAL_SAVE;Uschovat +GENERAL_YES;Ano +HISTOGRAM_LABEL;Histogram +HISTOGRAM_TOOLTIP_B;Schovej Äi zobraz histogram pro MODROU +HISTOGRAM_TOOLTIP_G;Schovej Äi zobraz histogram pro ZELENOU +HISTOGRAM_TOOLTIP_L;Schovej Äi zobraz histogram pro JAS v CIELAB +HISTOGRAM_TOOLTIP_R;Schovej Äi zobraz histogram pro ÄŒERVENOU +HISTORY_CHANGED;ZmÄ›nÄ›no +HISTORY_CUSTOMCURVE;Vlastní kÅ™ivka +HISTORY_DELSNAPSHOT;Odstranit snímek +HISTORY_FROMCLIPBOARD;Ze schránky +HISTORY_LABEL;Historie +HISTORY_MSG_10;Komprese stínů +HISTORY_MSG_11;Tónová kÅ™ivka +HISTORY_MSG_12;Automatická expozice +HISTORY_MSG_13;Oříznutí exozice +HISTORY_MSG_14;Jas (CIELAB) +HISTORY_MSG_15;Kontrast (CIELAB) +HISTORY_MSG_16;ÄŒerná (CIELAB) +HISTORY_MSG_17;Komprese svÄ›tel (CIELAB) +HISTORY_MSG_18;Komprese stínů (CIELAB) +HISTORY_MSG_19;Tónová kÅ™ivka (CIELAB) +HISTORY_MSG_1;Obrázek naÄten +HISTORY_MSG_20;DoostÅ™ení +HISTORY_MSG_21;PolomÄ›r doostÅ™ení +HISTORY_MSG_22;Míra doostÅ™ení +HISTORY_MSG_23;Práh doostÅ™ení +HISTORY_MSG_24;DoostÅ™ení pouze v okrajích +HISTORY_MSG_25;PolomÄ›r detekce okrajů pÅ™i doostÅ™ení +HISTORY_MSG_26;Tolerance okrajů pÅ™i doostÅ™ení +HISTORY_MSG_27;Omezení haló artefatů pÅ™i doostÅ™ení +HISTORY_MSG_28;Míra omezení haló artefatů +HISTORY_MSG_29;Metoda doostÅ™ení +HISTORY_MSG_2;Profil naÄten +HISTORY_MSG_30;PolomÄ›r dekonvoluce +HISTORY_MSG_31;Míra dekonvoluce +HISTORY_MSG_32;Útlum dekonvoluce +HISTORY_MSG_33;PoÄet opakování dekonvoluce +HISTORY_MSG_34;Zabránit oříznutí barev +HISTORY_MSG_35;Omezování sytosti +HISTORY_MSG_36;Omezení sytosti +HISTORY_MSG_37;Sytost barev +HISTORY_MSG_38;Metoda vyvážení bílé +HISTORY_MSG_39;Barevná teplota +HISTORY_MSG_3;Profil zmÄ›nÄ›n +HISTORY_MSG_40;Odstín vyvážení bílé +HISTORY_MSG_41;Posun barev "A" +HISTORY_MSG_42;Posun barev "B" +HISTORY_MSG_43;Redukce Å¡umu v jasech +HISTORY_MSG_44;PolomÄ›r redukce Å¡umu v jasech +HISTORY_MSG_45;Okrajová telorence v redukce Å¡umu v jasech +HISTORY_MSG_46;Redukce barevného Å¡umu +HISTORY_MSG_47;PolomÄ›r redukce barevného Å¡umu +HISTORY_MSG_48;Okrajová toleranve v redukci barevného Å¡umu +HISTORY_MSG_49;Redukce barevného Å¡umu s ohledem na okraje +HISTORY_MSG_4;Prohlížení historie +HISTORY_MSG_50;Nástroj Stíny/svÄ›tla +HISTORY_MSG_51;ZvýraznÄ›ní svÄ›tel +HISTORY_MSG_52;ZvýraznÄ›ní stínů +HISTORY_MSG_53;Tónová rozsah jasů +HISTORY_MSG_54;Tónový rozsah stínů +HISTORY_MSG_55;Místní kontrast +HISTORY_MSG_56;PolomÄ›r svÄ›tel a stínů +HISTORY_MSG_57;Hrubé otáÄení +HISTORY_MSG_58;Horizontální pÅ™eklopení +HISTORY_MSG_59;Vertikální pÅ™eklopení +HISTORY_MSG_5;Jas +HISTORY_MSG_60;OtáÄení +HISTORY_MSG_61;OtoÄení +HISTORY_MSG_62;Úprava zkreslení objektivu +HISTORY_MSG_63;Záložka zvolena +HISTORY_MSG_64;Oříznout obrázek +HISTORY_MSG_65;Úprava chromatické vady +HISTORY_MSG_66;Obnovení jasů +HISTORY_MSG_67;Míra obnovení jasů +HISTORY_MSG_68;Metoda obnovení jasů +HISTORY_MSG_69;Pracovní barevný prostor +HISTORY_MSG_6;Kontrast +HISTORY_MSG_70;Výstupní barevný prostor +HISTORY_MSG_71;Vstupní barevný prostor +HISTORY_MSG_72;Úprave vinÄ›tace +HISTORY_MSG_73;Míchání kanálů +HISTORY_MSG_74;Míra zmÄ›ny rozmÄ›rů +HISTORY_MSG_75;Metoda zmÄ›ny rozmÄ›ru +HISTORY_MSG_76;Exif Metadata +HISTORY_MSG_77;IPTC Metadata +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;ÄŒerná +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;ExpoziÄní korekce +HISTORY_MSG_9;Komprese svÄ›tel +HISTORY_NEWSNAPSHOTAS;Jako... +HISTORY_NEWSNAPSHOT;Nový snímek +HISTORY_NEWSSDIALOGLABEL;Titulek snímku: +HISTORY_NEWSSDIALOGTITLE;PÅ™idat nový snímek +HISTORY_SETTO;Nastavit na +HISTORY_SNAPSHOT;Snímek +HISTORY_SNAPSHOTS;Snímky +ICMPANEL_FILEDLGFILTERANY;Jakékoliv soubory +ICMPANEL_FILEDLGFILTERICM;Soubory ICC profilů +ICMPANEL_GAMMABEFOREINPUT;Profil provádí Gama korekci +ICMPANEL_INPUTCAMERA;Výchozí profil fotoaparátu +ICMPANEL_INPUTCUSTOM;Vlastní +ICMPANEL_INPUTDLGLABEL;Vyber vstupní ICC profil... +ICMPANEL_INPUTEMBEDDED;Použít vložený profil, pokud je k dispozici +ICMPANEL_INPUTPROFILE;Vstupní profil +ICMPANEL_NOICM;Bez správy barev: sRGB výstup +ICMPANEL_OUTPUTDLGLABEL;Vyber výstupní ICC profil... +ICMPANEL_OUTPUTPROFILE;Výstupní barevný prostor +ICMPANEL_SAVEREFERENCE;Uložit referenÄní obrázek pro profilování +ICMPANEL_WORKINGPROFILE;Pracovní barevný prostor +IMAGEAREA_DETAILVIEW;Detailní pohled +IPTCPANEL_AUTHOR;Autor +IPTCPANEL_AUTHORHINT;Jméno autora, například spisovatele, fotografa nebo grafika (By-line). +IPTCPANEL_AUTHORSPOSITION;Autorova pozice +IPTCPANEL_AUTHORSPOSITIONHINT;Titul/pozice autora nebo autorů obrázku (By-line Title). +IPTCPANEL_CAPTIONHINT;Textový popis dat (Popis - Shrnutí) +IPTCPANEL_CAPTION;Popis +IPTCPANEL_CAPTIONWRITERHINT;Jméno osoby, která vložila, zmÄ›nila nebo opravila obrázek nebo popis/shrnutí (Autor - Editor) +IPTCPANEL_CAPTIONWRITER;PopisovaÄ +IPTCPANEL_CATEGORYHINT;Obsah obrázku dle názoru dodavatele (Kategorie). +IPTCPANEL_CATEGORY;Kategorie +IPTCPANEL_CITYHINT;Místo vzniku obrázku (MÄ›sto). +IPTCPANEL_CITY;MÄ›sto +IPTCPANEL_COPYHINT;Zkopíruj IPTC nastavení do schránky +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COPYRIGHTHINT;Autorská práva (Copyright Notice). +IPTCPANEL_COUNTRYHINT;Jméno zemÄ›/lokace kde byl obrázek vytvoÅ™en (ZemÄ› - Lokace). +IPTCPANEL_COUNTRY;ZemÄ› +IPTCPANEL_CREDITHINT;Dodavatel obrázku, ne nutnÄ› vlastník/autor (Credit). +IPTCPANEL_CREDIT;Zásluhy +IPTCPANEL_DATECREATED;Datum vytvoÅ™ení +IPTCPANEL_DATECREATEDHINT;Kdy byl obrázek vytvoÅ™en; Formát: RRRRMMDD (Datum vytvoÅ™ení). +IPTCPANEL_EMBEDDEDHINT;Obnov IPTC data z obrázku +IPTCPANEL_EMBEDDED;Uložené +IPTCPANEL_HEADLINEHINT;UveÅ™ejnitelný krátký popis obrázku (Nadpis). +IPTCPANEL_HEADLINE;Nadpis +IPTCPANEL_INSTRUCTIONSHINT;Další instrukce vztahující se k obrázku (Speciální instrukce). +IPTCPANEL_INSTRUCTIONS;Instrukce +IPTCPANEL_KEYWORDSHINT;Jednoslovná hesla popisující obrázek (KlíÄová slova). +IPTCPANEL_KEYWORDS;KlíÄová slova +IPTCPANEL_PASTEHINT;Vlož IPTC nastavení ze schránky +IPTCPANEL_PROVINCEHINT;Kraj/stát kde byl obrázek vytvoÅ™en (Kraj-Stát). +IPTCPANEL_PROVINCE;Kraj +IPTCPANEL_RESETHINT;Obnov výchozí profil +IPTCPANEL_RESET;Obnov +IPTCPANEL_SOURCEHINT;Původní vlastník intelektuálního obsahu obrázku (Zdroj). +IPTCPANEL_SOURCE;Zdroj +IPTCPANEL_SUPPCATEGORIES;Dodat. kategorie +IPTCPANEL_SUPPCATEGORIESHINT;UpÅ™esňující popis obsahu obrázku (DodateÄné kategorie). +IPTCPANEL_TITLEHINT;Zkrácený popis obrázku (Jméno obrázku). +IPTCPANEL_TITLE;Titulek +IPTCPANEL_TRANSREFERENCEHINT;Kód místa, odkud byl pÅ™evzat originální obrázek (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Trans. Reference +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Volby +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;jako... +MAIN_BUTTON_SAVE;Uložit +MAIN_BUTTON_SENDTOEDITOR;Odeslat do editoru +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Soubor již existuje. +MAIN_MSG_CANNOTLOAD;NepodaÅ™ilo se naÄíst obrázek +MAIN_MSG_CANNOTSAVE;Chyba pÅ™i ukládání souboru. +MAIN_MSG_CANNOTSTARTEDITOR;Can not start editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Please set the correct path in the "Preferences" dialog. +MAIN_MSG_EXITJOBSINQUEUEINFO;Nezpracované obrázky ve frontÄ› budou ztraceny! +MAIN_MSG_EXITJOBSINQUEUEQUEST;OPravdu chcete skonÄit? Ve frontÄ› jsou nezpracované obrázky. +MAIN_MSG_JOBSINQUEUE;Úlohy ve frontÄ› +MAIN_MSG_QOVERWRITE;Chcete jej pÅ™epsat? +MAIN_TAB_BASIC;Základní +MAIN_TAB_COLOR;Barvy +MAIN_TAB_DETAIL;Detaily +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Expozice +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Transformace +MAIN_TOOLTIP_HIDEFP;Zobrazit Äi schovat dolní panel (složky a prohlížeÄ souborů, shortcut key: F)) +MAIN_TOOLTIP_HIDEHP;Zobrazit Äi schovat levý panel (obsahující historii, shortcut key: H) +MAIN_TOOLTIP_INDCLIPPEDH;Zvýraznit oříznuté jasy +MAIN_TOOLTIP_INDCLIPPEDS;Zvýraznit oříznuté stíny +MAIN_TOOLTIP_PREFERENCES;ZmÄ›nit volby +MAIN_TOOLTIP_QINFO;StruÄné informace o obrázku +MAIN_TOOLTIP_SAVEAS;Uložit obrázek do vybrané složky +MAIN_TOOLTIP_SAVE;Uložit obrázek do výchozí složky +PARTIALPASTE_BASICGROUP;Základní nastavení +PARTIALPASTE_CACORRECTION;Korekce C/A +PARTIALPASTE_COARSETRANS;Orientace / pÅ™evrácení +PARTIALPASTE_COLORBOOST;Posílení barev +PARTIALPASTE_COLORDENOISE;OdstranÄ›ní barevného Å¡umu +PARTIALPASTE_COLORGROUP;Nastavení barev +PARTIALPASTE_COLORMIXER;Mixér barev +PARTIALPASTE_COLORSHIFT;Posun barev +PARTIALPASTE_COMPOSITIONGROUP;Nastavení kompozice +PARTIALPASTE_CROP;OÅ™ez +PARTIALPASTE_DIALOGLABEL;Nastavení profilu ÄásteÄného vložení +PARTIALPASTE_DISTORTION;Korekce zkreslení +PARTIALPASTE_EXIFCHANGES;Upravené exif data +PARTIALPASTE_EXPOSURE;Expozice +PARTIALPASTE_HLRECOVERY;Obnovení svÄ›tel +PARTIALPASTE_ICMSETTINGS;Nastavení ICM +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Nastavení objektivu +PARTIALPASTE_LUMACURVE;KÅ™ivka jasu +PARTIALPASTE_LUMADENOISE;Redukce Å¡umu v jasech +PARTIALPASTE_LUMINANCEGROUP;Nastavení svÄ›tel +PARTIALPASTE_METAICMGROUP;Nastavení metadat a ICM +PARTIALPASTE_RESIZE;ZmÄ›na velikosti +PARTIALPASTE_ROTATION;Rotace +PARTIALPASTE_SHADOWSHIGHLIGHTS;Stíny/SvÄ›tla +PARTIALPASTE_SHARPENING;DoostÅ™ení +PARTIALPASTE_VIGNETTING;Korekce vinÄ›tace +PARTIALPASTE_WHITEBALANCE;Nastavení bílé +PREFERENCES_APPLNEXTSTARTUP;Projeví se pÅ™i dalším spuÅ¡tÄ›ní +PREFERENCES_BLINKCLIPPED;Blikání v oříznutých oblastech +PREFERENCES_CACHECLEARALL;Vymaž vÅ¡e +PREFERENCES_CACHECLEARPROFILES;Vymaž profily +PREFERENCES_CACHECLEARTHUMBS;Vymaž náhledy +PREFERENCES_CACHEFORMAT1;Vlastní (rychlejší a kvalitnÄ›jší) +PREFERENCES_CACHEFORMAT2;JPEG (Menší velikost) +PREFERENCES_CACHEMAXENTRIES;Maximální poÄet záznamů v cache. +PREFERENCES_CACHEOPTS;Vlastnosti cache +PREFERENCES_CACHESTRAT1;UpÅ™ednostnit rychlost pÅ™ed spotÅ™ebou pamÄ›ti +PREFERENCES_CACHESTRAT2;UpÅ™ednostnit menší spotÅ™ebu pamÄ›ti pÅ™ed rychlostí +PREFERENCES_CACHESTRAT;Strategie cache +PREFERENCES_CACHETHUMBFORM;Formát náhledů v cache +PREFERENCES_CACHETHUMBHEIGHT;Maximální velikost náhledu +PREFERENCES_CLEARDLG_LINE1;ÄŒiÅ¡tÄ›ní cache +PREFERENCES_CLEARDLG_LINE2;může trvat nÄ›kolik sekund. +PREFERENCES_CLEARDLG_TITLE;Prosím poÄkejte. +PREFERENCES_CLIPPINGIND;ZvýraznÄ›ní oříznutých jasů Äi stínů +PREFERENCES_CMETRICINTENT;Kolorimetrická metoda +PREFERENCES_DATEFORMAT;Formát data +PREFERENCES_DATEFORMATHINT;Lze použít následující formátovací Å™etÄ›zce:\n%y : rok (year)\n%m : mÄ›síc (month)\n%d : den (day)\n\nNapříklad Äeský formát data:\n%d. %m. %y +PREFERENCES_DEFAULTLANG;Výchozí jazyk +PREFERENCES_DEFAULTTHEME;Výchozí vzhled +PREFERENCES_DEMOSAICINGALGO;Demozajkovací algoritmus +PREFERENCES_DIRHOME;Domovská složka +PREFERENCES_DIRLAST;Poslední navÅ¡tívená složka +PREFERENCES_DIROTHER;Jiná +PREFERENCES_DIRSELECTDLG;Zvolte složku s obrázky pro spuÅ¡tÄ›ní... +PREFERENCES_DIRSOFTWARE;InstalaÄní složka +PREFERENCES_DMETHOD;Metoda +PREFERENCES_EDITORCMDLINE;Jiný příkaz +PREFERENCES_EXTERNALEDITOR;Externí editor +PREFERENCES_FALSECOLOR;PoÄet kroků pÅ™i potlaÄování chybných barev +PREFERENCES_FBROWSEROPTS;Volby prohlížeÄe souborů +PREFERENCES_FILEFORMAT;Formát souboru +PREFERENCES_FORIMAGE;Pro obrázkové soubory +PREFERENCES_FORRAW;Pro RAW soubory +PREFERENCES_GIMPPATH;GIMP instalaÄní adresář +PREFERENCES_GTKTHEME;GTK výchozí +PREFERENCES_HINT;NápovÄ›da +PREFERENCES_HLTHRESHOLD;Práh pro oříznutá svÄ›tla +PREFERENCES_ICCDIR;Složka ICC profilů +PREFERENCES_IMPROCPARAMS;Výchozí profily pro zpracování obrázku +PREFERENCES_INTENT_ABSOLUTE;Absolutní kolorimetrie +PREFERENCES_INTENT_PERCEPTUAL;Vnímání +PREFERENCES_INTENT_RELATIVE;Relativní kolorimetrie +PREFERENCES_INTENT_SATURATION;Saturace +PREFERENCES_LIVETHUMBNAILS;Živé náhledy (pomalejší) +PREFERENCES_MONITORICC;Profil monitoru +PREFERENCES_OUTDIRFOLDERHINT;Uloží obrázky do vybraného adresáře +PREFERENCES_OUTDIRFOLDER;Ulož do souboru +PREFERENCES_OUTDIRHINT;Lze použít následující formátovací Å™etÄ›zce:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nTyto formátovací Å™etÄ›zce reprezentují adresáře a Äásti cesty, kde je uložen raw soubor.\n\nNapříklad pokud je otevÅ™en soubor /home/tom/image/02-09-2006/dsc0012.nef, mají jednotlivé formátovací Å™etÄ›zce tento význam:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nPokud si pÅ™ejete uložit výstupní obrázek vedle originálu, napiÅ¡tÄ›:\n%p1/%f\n\nJestliže si jej ale pÅ™ejete uložit do adresáře 'converted' ve stejném adresáři jako originál, napiÅ¡tÄ›:\n%p1/converted/%f\n\nPro uložení výstupního obrázku do adresáře '/home/tom/converted' se zachováním adresáře s datem, použijte:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;Lze použít následující formátovací Å™etÄ›zce:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nTyto formátovací Å™etÄ›zce reprezentují adresáře a Äásti cesty, kde je uložen raw soubor.\n\nNapříklad pokud je otevÅ™en soubor /home/tom/image/02-09-2006/dsc0012.nef, mají jednotlivé formátovací Å™etÄ›zce tento význam:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nPokud si pÅ™ejete uložit výstupní obrázek vedle originálu, napiÅ¡tÄ›:\n%p1/%f\n\nJestliže si jej ale pÅ™ejete uložit do adresáře 'converted' ve stejném adresáři jako originál, napiÅ¡tÄ›:\n%p1/converted/%f\n\nPro uložení výstupního obrázku do adresáře '/home/tom/converted' se zachováním adresáře s datem, použijte:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Použij Å¡ablonu +PREFERENCES_OUTDIR;Výstupní složka +PREFERENCES_PARSEDEXTADDHINT;Vložte příponu a stisknÄ›te toto tlaÄítko pro pÅ™idání do seznamu +PREFERENCES_PARSEDEXTADD;PÅ™idej příponu +PREFERENCES_PARSEDEXTDELHINT;Vymaže oznaÄenou příponu ze seznamu +PREFERENCES_PARSEDEXT;Zobrazované přípony +PREFERENCES_PROFILEHANDLING;Profily zpracování +PREFERENCES_PROFILELOADPR;Priorita nahrávání profilu +PREFERENCES_PROFILEPRCACHE;Profil v cache +PREFERENCES_PROFILEPRFILE;Profil uložený se zdrojovým souborem +PREFERENCES_PROFILESAVECACHE;Ukládat parametry zpracování do cache +PREFERENCES_PROFILESAVEINPUT;Ukládat parametry zpracování se zdrojovým souborem +PREFERENCES_PSPATH;Adobe Photoshop instalaÄní adresář +PREFERENCES_SELECTICCDIRDLG;Zvolte složky s ICC profily... +PREFERENCES_SELECTLANG;Volba jazyka +PREFERENCES_SELECTMONITORPROFDLG;Zvolte ICC profil obrazovky... +PREFERENCES_SELECTTHEME;Vybraný vzhled +PREFERENCES_SHOWBASICEXIF;Zobrazovat základní informace z EXIF +PREFERENCES_SHOWDATETIME;Zobrazovat datum a Äas +PREFERENCES_SHOWONLYRAW;Zobrazovat pouze soubory RAW +PREFERENCES_SHTHRESHOLD;Práh pro oříznuté stíny +PREFERENCES_STARTUPIMDIR;Složka s obrázky pÅ™i spuÅ¡tÄ›ní +PREFERENCES_TAB_BROWSER;ProhlížeÄ souborů +PREFERENCES_TAB_COLORMGR;Správa barev +PREFERENCES_TAB_GENERAL;Obecné +PREFERENCES_TAB_IMPROC;Zpracování obrázku +PREFERENCES_TAB_OUTPUT;Volby výstupu +PREFERENCES_THUMBSIZE;Velikost náhledu +PROFILEPANEL_FILEDLGFILTERANY;Jakékoliv souboru +PROFILEPANEL_FILEDLGFILTERPP;Profily zpracování +PROFILEPANEL_LABEL;Profily zpracování +PROFILEPANEL_LOADDLGLABEL;NaÄíst parametry zpracování... +PROFILEPANEL_PCUSTOM;Vlastní +PROFILEPANEL_PFILE;Ze souboru +PROFILEPANEL_PLASTPHOTO;Poslední obrázek +PROFILEPANEL_PLASTSAVED;Poslední uschovaný +PROFILEPANEL_PROFILE;Profil +PROFILEPANEL_SAVEDLGLABEL;Uschovat parametry zpracování... +PROFILEPANEL_TOOLTIPCOPY;Uložit aktuální profil do schránky +PROFILEPANEL_TOOLTIPLOAD;NaÄíst profil ze souboru +PROFILEPANEL_TOOLTIPPASTE;Vložit profil ze schránky +PROFILEPANEL_TOOLTIPSAVE;Uschovat souÄasný profil +PROGRESSBAR_DECODING;Dekódování RAW... +PROGRESSBAR_DEMOSAICING;Demozajkování... +PROGRESSBAR_LOADING;NaÄítám obrázek... +PROGRESSBAR_LOADJPEG;NaÄítám JPEG... +PROGRESSBAR_LOADPNG;NaÄítám PNG... +PROGRESSBAR_LOADTIFF;NaÄítám TIFF... +PROGRESSBAR_PROCESSING;Zpracovávám obrázek... +PROGRESSBAR_READY;PÅ™ipraven. +PROGRESSBAR_SAVEJPEG;Ukládám jako JPEG... +PROGRESSBAR_SAVEPNG;Ukládám jako PNG... +PROGRESSBAR_SAVETIFF;Ukládám jako TIFF... +PROGRESSDLG_LOADING;Loading file... +PROGRESSDLG_PROCESSING;Processing image... +PROGRESSDLG_SAVING;Saving file... +QINFO_FOCALLENGTH;Ohnisková vzdálenost +QINFO_ISO;ISO +QINFO_LENS;Lens +QINFO_NOEXIF;Exif údaje nejsou k dispozici. +SAVEDLG_FILEFORMAT;Formát souboru +SAVEDLG_JPEGQUAL;JPEG Kvalita +SAVEDLG_JPGFILTER;Soubory JPEG +SAVEDLG_PNGCOMPR;PNG Komprese +SAVEDLG_PNGFILTER;Soubory PNG +SAVEDLG_PUTTOQUEUEHEAD;Put to the head of the processing queue +SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue +SAVEDLG_PUTTOQUEUE;Vložit soubor do fronty +SAVEDLG_SAVEIMMEDIATELY;OkamžitÄ› uložit +SAVEDLG_SAVESPP;Uschovat s obrazem i parametry zpracování +SAVEDLG_TIFFFILTER;Soubory TIFF +TOOLBAR_TOOLTIP_CROP;OznaÄení výřezu (shortcut key: C) +TOOLBAR_TOOLTIP_HAND;Nástroj ruka (shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;VyznaÄení roviny (shortcut key: S) +TOOLBAR_TOOLTIP_WB;Bodové vyvážení bílé (shortcut key: W) +TP_CACORRECTION_BLUE;Modrá +TP_CACORRECTION_LABEL;Oprava chromatické vady +TP_CACORRECTION_RED;ÄŒervená +TP_CHMIXER_BLUE;Modrá +TP_CHMIXER_GREEN;Zelená +TP_CHMIXER_LABEL;Míchání kanálů +TP_CHMIXER_RED;ÄŒervená +TP_COARSETRAF_DEGREE;Stupeň: +TP_COARSETRAF_TOOLTIP_HFLIP;PÅ™eklopit horizontálnÄ› +TP_COARSETRAF_TOOLTIP_ROTLEFT;OtoÄit doleva +TP_COARSETRAF_TOOLTIP_ROTRIGHT;OtoÄit doprava +TP_COARSETRAF_TOOLTIP_VFLIP;PÅ™eklopit vertikálnÄ› +TP_COLORBOOST_ACHANNEL;kanál "a" +TP_COLORBOOST_AMOUNT;Míra +TP_COLORBOOST_AVOIDCOLORCLIP;Zabránit oříznutí barvy +TP_COLORBOOST_BCHANNEL;kanál "b" +TP_COLORBOOST_CHAB;a & b +TP_COLORBOOST_CHANNEL;Kanál +TP_COLORBOOST_CHSEPARATE;zvlášť +TP_COLORBOOST_ENABLESATLIMITER;Omezovat sytost +TP_COLORBOOST_LABEL;Sytost barev +TP_COLORBOOST_SATLIMIT;Limit sytosti +TP_COLORDENOISE_EDGESENSITIVE;Citlivost k okrajům +TP_COLORDENOISE_EDGETOLERANCE;Tolerance okrajům +TP_COLORDENOISE_LABEL;Redukce barevného Å¡umu +TP_COLORDENOISE_RADIUS;PolomÄ›r +TP_COLORSHIFT_BLUEYELLOW;Modrá-Žlutá +TP_COLORSHIFT_GREENMAGENTA;Modrá-Purpurová +TP_COLORSHIFT_LABEL;Barevný posun +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;PomÄ›r stran: +TP_CROP_GTDIAGONALS;Pravidlo diagonál +TP_CROP_GTHARMMEANS1;Zlatý Å™ez 1 +TP_CROP_GTHARMMEANS2;Zlatý Å™ez 2 +TP_CROP_GTHARMMEANS3;Zlatý Å™ez 3 +TP_CROP_GTHARMMEANS4;Zlatý Å™ez 4 +TP_CROP_GTNONE;Žádné +TP_CROP_GTRULETHIRDS;Pravidlo tÅ™etin +TP_CROP_GUIDETYPE;Druh vodítek: +TP_CROP_H;V +TP_CROP_LABEL;Výřez +TP_CROP_SELECTCROP; OznaÄení výřezu +TP_CROP_W;Å  +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Míra +TP_DISTORTION_LABEL;Oprava zkreslení objektivu +TP_EXPOSURE_AUTOLEVELS;ÚrovnÄ› automaticky +TP_EXPOSURE_BLACKLEVEL;ÄŒerná +TP_EXPOSURE_BRIGHTNESS;Jas +TP_EXPOSURE_CLIP;Oříznutí +TP_EXPOSURE_COMPRHIGHLIGHTS;Komprese svÄ›tel +TP_EXPOSURE_COMPRSHADOWS;Komprese stínů +TP_EXPOSURE_CONTRAST;Kontrast +TP_EXPOSURE_CURVEEDITOR;Tonální kÅ™ivka +TP_EXPOSURE_EXPCOMP;Korekce expozice +TP_EXPOSURE_LABEL;Expozice +TP_HLREC_CIELAB;Mísení CIELAB +TP_HLREC_COLOR;Propagace barev +TP_HLREC_LABEL;Obnovení jasů +TP_HLREC_LUMINANCE;Obnovení jasů +TP_HLREC_METHOD;Metoda: +TP_ICM_FILEDLGFILTERANY;Jakékoliv soubory +TP_ICM_FILEDLGFILTERICM;Soubory ICC profilů +TP_ICM_GAMMABEFOREINPUT;Profil provádí Gama korekci +TP_ICM_INPUTCAMERA;Výchozí profil fotoaparátu +TP_ICM_INPUTCUSTOM;Vlastní +TP_ICM_INPUTDLGLABEL;Vyber vstupní ICC profil... +TP_ICM_INPUTEMBEDDED;Použít vložený profil, pokud je k dispozici +TP_ICM_INPUTPROFILE;Vstupní profil +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Bez správy barev: sRGB výstup +TP_ICM_OUTPUTDLGLABEL;Vyber výstupní ICC profil... +TP_ICM_OUTPUTPROFILE;Výstupní barevný prostor +TP_ICM_SAVEREFERENCE;Uložit referenÄní obrázek pro profilování +TP_ICM_WORKINGPROFILE;Pracovní barevný prostor +TP_LUMACURVE_BLACKLEVEL;ÄŒerná +TP_LUMACURVE_BRIGHTNESS;Jas +TP_LUMACURVE_COMPRHIGHLIGHTS;Komprese svÄ›tel +TP_LUMACURVE_COMPRSHADOWS;Komprese stínů +TP_LUMACURVE_CONTRAST;Kontrast +TP_LUMACURVE_CURVEEDITOR;KÅ™ivka +TP_LUMACURVE_LABEL;KÅ™ivka jasu v CIELAB +TP_LUMADENOISE_EDGETOLERANCE;Tolerance okrajů +TP_LUMADENOISE_LABEL;Redukce Å¡umu v jasech +TP_LUMADENOISE_RADIUS;PolomÄ›r +TP_RESIZE_BICUBIC;Bikubická +TP_RESIZE_BICUBICSF;Bikubická (MÄ›kÄí) +TP_RESIZE_BICUBICSH;Bikubická (OstÅ™ejší) +TP_RESIZE_BILINEAR;Bilineární +TP_RESIZE_FULLSIZE;Plná velikost obrázku: +TP_RESIZE_H;V: +TP_RESIZE_LABEL;ZmÄ›nit rozmÄ›ry +TP_RESIZE_METHOD;Metoda: +TP_RESIZE_NEAREST;Nejbližší +TP_RESIZE_SCALE;Měřítko +TP_RESIZE_W;Å : +TP_ROTATE_AUTOCROP;Automatický oÅ™ez +TP_ROTATE_DEGREE;StupnÄ› +TP_ROTATE_FILL;Vyplnit +TP_ROTATE_LABEL;OtáÄení +TP_ROTATE_SELECTLINE; VyznaÄ rovinu +TP_SHADOWSHLIGHTS_HIGHLIGHTS;SvÄ›tla +TP_SHADOWSHLIGHTS_HLTONALW;Tonální rozsah +TP_SHADOWSHLIGHTS_LABEL;Stíny/SvÄ›tla +TP_SHADOWSHLIGHTS_LOCALCONTR;Místní kontrast +TP_SHADOWSHLIGHTS_RADIUS;PolomÄ›r +TP_SHADOWSHLIGHTS_SHADOWS;Stíny +TP_SHADOWSHLIGHTS_SHTONALW;Tonální rozsah +TP_SHARPENING_AMOUNT;Míra +TP_SHARPENING_EDRADIUS;PolomÄ›r +TP_SHARPENING_EDTOLERANCE;Tolerance okrajů +TP_SHARPENING_HALOCONTROL;Omezení haló artefatů +TP_SHARPENING_HCAMOUNT;Míra +TP_SHARPENING_LABEL;DoostÅ™ení +TP_SHARPENING_METHOD;Metoda +TP_SHARPENING_ONLYEDGES;DoostÅ™it pouze okraje +TP_SHARPENING_RADIUS;PolomÄ›r +TP_SHARPENING_RLD_AMOUNT;Míra +TP_SHARPENING_RLD_DAMPING;Útlum +TP_SHARPENING_RLD_ITERATIONS;PoÄet opakování +TP_SHARPENING_RLD;RL Dekonvoluce +TP_SHARPENING_THRESHOLD;Práh +TP_SHARPENING_USM;Maskovat rozostÅ™ení +TP_VIGNETTING_AMOUNT;Míra +TP_VIGNETTING_LABEL;Oprava vinÄ›tace +TP_VIGNETTING_RADIUS;PolomÄ›r +TP_WBALANCE_AUTO;Automaticky +TP_WBALANCE_CAMERA;Fotoaparát +TP_WBALANCE_CUSTOM;Vlastní +TP_WBALANCE_GREEN;Odstín +TP_WBALANCE_LABEL;Vyvážení bílé +TP_WBALANCE_METHOD;Metoda +TP_WBALANCE_SIZE;RozmÄ›r: +TP_WBALANCE_SPOTWB;Bodové vyvážení +TP_WBALANCE_TEMPERATURE;Teplota +ZOOMBAR_DETAIL;Detail +ZOOMBAR_HUGE;Veliký +ZOOMBAR_LARGE;VÄ›tší +ZOOMBAR_NORMAL;Normální +ZOOMBAR_PREVIEW;Náhled +ZOOMBAR_SCALE;Měřítko +ZOOMBAR_SMALL;Malý + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Dansk b/rtdata/languages/Dansk new file mode 100644 index 000000000..a09870017 --- /dev/null +++ b/rtdata/languages/Dansk @@ -0,0 +1,703 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# Danish translation of RawTherapee +# Translated by krengbo +# 2009-06-27 +ADJUSTER_RESET_TO_DEFAULT;Nulstil til standard +CURVEEDITOR_FILEDLGFILTERANY;Alle filer +CURVEEDITOR_FILEDLGFILTERCURVE;Kurve-filer +CURVEEDITOR_LINEAR;Lineær +CURVEEDITOR_LOADDLGLABEL;Indlæs kurve... +CURVEEDITOR_SAVEDLGLABEL;Gem kurve... +CURVEEDITOR_TOOLTIPLINEAR;Nulstil kurve til lineær +CURVEEDITOR_TOOLTIPLOAD;Indlæs kurve fra fil +CURVEEDITOR_TOOLTIPSAVE;Gem nuværende kurve +EXIFFILTER_APERTURE;Blænde +EXIFFILTER_CAMERA;Kamera +EXIFFILTER_DIALOGLABEL;Exif Filter +EXIFFILTER_FOCALLEN;Brændvidde +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objektiv +EXIFFILTER_SHUTTER;Lukkertid +EXIFPANEL_ADDEDITHINT;Tilføj nyt tags eller rediger tags +EXIFPANEL_ADDEDIT;Tilføj/Rediger +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Indtast værdi +EXIFPANEL_ADDTAGDLG_SELECTTAG;Vælg tags +EXIFPANEL_ADDTAGDLG_TITLE;Tilføj/Rediger tags +EXIFPANEL_KEEP;Bevar +EXIFPANEL_KEEPHINT;Bevar de valgte tags under skrivning af fil +EXIFPANEL_REMOVE;Fjern +EXIFPANEL_REMOVEHINT;Fjern de valgte tags under skrivning af fil +EXIFPANEL_RESETALL;Gendan alt +EXIFPANEL_RESETALLHINT;Gendan alle tags til de oprindelige værdier +EXIFPANEL_RESET;Gendan +EXIFPANEL_RESETHINT;Gendan valgte tags til de oprindelige værdier +EXIFPANEL_SUBDIRECTORY;Undermappe +FILEBROWSER_APPLYPROFILE;Anvend profil +FILEBROWSER_ARRANGEMENTHINT;Skifte mellem lodret og vandret tilpasning af miniaturer +FILEBROWSER_CLEARPROFILE;Ryd profil +FILEBROWSER_COPYPROFILE;Kopier profil +FILEBROWSER_DELETEDLGLABEL;Bekræft sletning af fil +FILEBROWSER_DELETEDLGMSG;Er du sikker pÃ¥, at du vil slette de %1 valgte filer? +FILEBROWSER_EMPTYTRASHHINT;Slet filerne i papirkurv permanent +FILEBROWSER_EMPTYTRASH;Tøm papirkurv +FILEBROWSER_EXIFFILTERAPPLY;Anvend +FILEBROWSER_EXIFFILTERAPPLYHINT;SlÃ¥ exif filter til eller fra i filbrowseren +FILEBROWSER_EXIFFILTERLABEL;Exif filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Skift indstillinger pÃ¥ exif filteret +FILEBROWSER_EXIFFILTERSETTINGS;Indstillinger +FILEBROWSER_PARTIALPASTEPROFILE;Indsæt delvist +FILEBROWSER_PASTEPROFILE;Indsæt profil +FILEBROWSER_POPUPCANCELJOB;Annuler opgave +FILEBROWSER_POPUPMOVEEND;Flyt til slutning af køen +FILEBROWSER_POPUPMOVEHEAD;Flyt til starten af køen +FILEBROWSER_POPUPOPEN;Ã…bn +FILEBROWSER_POPUPPROCESS;Sæt i opgavekø +FILEBROWSER_POPUPRANK1;Vurdering 1 +FILEBROWSER_POPUPRANK2;Vurdering 2 +FILEBROWSER_POPUPRANK3;Vurdering 3 +FILEBROWSER_POPUPRANK4;Vurdering 4 +FILEBROWSER_POPUPRANK5;Vurdering 5 +FILEBROWSER_POPUPREMOVE;fjern fra filsystem +FILEBROWSER_POPUPRENAME;Omdøb +FILEBROWSER_POPUPSELECTALL;Vælg alt +FILEBROWSER_POPUPTRASH;Flyt til papirkurv +FILEBROWSER_POPUPUNRANK;Fjern vurdering +FILEBROWSER_POPUPUNTRASH;Fjern fra papirkurv +FILEBROWSER_PROCESSINGSETTINGSHINT;Vælg filformat og destinationsmappe +FILEBROWSER_PROCESSINGSETTINGS;Indstillinger +FILEBROWSER_RENAMEDLGLABEL;Omdøb fil +FILEBROWSER_RENAMEDLGMSG;Omdøb filen "%1" til: +FILEBROWSER_SHOWDIRHINT;Vis alle billeder i mappen +FILEBROWSER_SHOWQUEUEHINT;Vis indhold i opgavekøen +FILEBROWSER_SHOWRANK1HINT;Vis billeder vurderet med 1 stjerne +FILEBROWSER_SHOWRANK2HINT;Vis billeder vurderet med 2 stjerner +FILEBROWSER_SHOWRANK3HINT;Vis billeder vurderet med 3 stjerner +FILEBROWSER_SHOWRANK4HINT;Vis billeder vurderet med 4 stjerner +FILEBROWSER_SHOWRANK5HINT;Vis billeder vurderet med 5 stjerner +FILEBROWSER_SHOWTRASHHINT;Vis indhold i papirkurven +FILEBROWSER_SHOWUNRANKHINT;Vis billeder uden vurdering +FILEBROWSER_STARTPROCESSING;Begynd bearbejdning +FILEBROWSER_STARTPROCESSINGHINT;Begynd at bearbejde/gemme billeder i køen +FILEBROWSER_STOPPROCESSINGHINT;Stop bearbejdningen af billeder +FILEBROWSER_STOPPROCESSING;Stop bearbejdning +FILEBROWSER_THUMBSIZE;Miniaturestr. +FILEBROWSER_ZOOMINHINT;Gør miniaturer større +FILEBROWSER_ZOOMOUTHINT;Gør miniaturer mindre +GENERAL_ABOUT;Om +GENERAL_CANCEL;Annuler +GENERAL_DISABLED;Fravalgt +GENERAL_DISABLE;Fravælg +GENERAL_ENABLED;Valgt +GENERAL_ENABLE;Vælg +GENERAL_LANDSCAPE;Bredformat +GENERAL_LOAD;Indlæs +GENERAL_NA;Ikke muligt +GENERAL_NO;Nej +GENERAL_OK;OK +GENERAL_PORTRAIT;Højformat +GENERAL_SAVE;Gem +GENERAL_YES;Ja +HISTOGRAM_LABEL;Histogram +HISTOGRAM_TOOLTIP_B;Vis/skjul blÃ¥t histogram +HISTOGRAM_TOOLTIP_G;Vis/skjul grønt histogram +HISTOGRAM_TOOLTIP_L;Vis/skjul CIELAB histogram +HISTOGRAM_TOOLTIP_R;Vis/skjul rødt histogram +HISTORY_CHANGED;Ændret +HISTORY_CUSTOMCURVE;Tilpasset kurve +HISTORY_DELSNAPSHOT;Slet +HISTORY_FROMCLIPBOARD;Fra udklipsholder +HISTORY_LABEL;Historie +HISTORY_MSG_10;Skyggereduktion +HISTORY_MSG_11;Tonekurve +HISTORY_MSG_12;Autoeksponering +HISTORY_MSG_13;Eksponeringsadvarsel +HISTORY_MSG_14;Lysstyrke +HISTORY_MSG_15;Kontrast +HISTORY_MSG_16;Sort +HISTORY_MSG_17;Reduktion af højlys. +HISTORY_MSG_18;Reduktion af skygger +HISTORY_MSG_19;Kurve +HISTORY_MSG_1;Foto indlæst +HISTORY_MSG_20;Skarphed +HISTORY_MSG_21;Skarphed radius +HISTORY_MSG_22;Skarphed mængde +HISTORY_MSG_23;Skarphed tærskel +HISTORY_MSG_24;Gør kun kanter skarpere +HISTORY_MSG_25;Skarphed kantdetektion radius +HISTORY_MSG_26;Skarphed kantolerance +HISTORY_MSG_27;Skarphed halo-kontrol +HISTORY_MSG_28;Halo-kontrol mængde +HISTORY_MSG_29;Skarphedsmetode +HISTORY_MSG_2;Profil indlæst +HISTORY_MSG_30;Udfoldning radius +HISTORY_MSG_31;Udfoldning mængde +HISTORY_MSG_32;Udfoldning dæmpning +HISTORY_MSG_33;Udfoldning gentagelser +HISTORY_MSG_34;UndgÃ¥ farveklipning +HISTORY_MSG_35;Mætningsbegrænser +HISTORY_MSG_36;Mætningsgrænse +HISTORY_MSG_37;Forstærk farver +HISTORY_MSG_38;Hvidbalancemetode +HISTORY_MSG_39;Farvetemoeratur +HISTORY_MSG_3;Profil ændret +HISTORY_MSG_40;Hvidbalance nuance +HISTORY_MSG_41;Farveskift "A" +HISTORY_MSG_42;Farveskift "B" +HISTORY_MSG_43;Begræns lysstøj +HISTORY_MSG_44;Lysstøj radius +HISTORY_MSG_45;Lysstæj kanttolerance +HISTORY_MSG_46;Begræns farvestøj +HISTORY_MSG_47;Farvestøj radius +HISTORY_MSG_48;Farvestøj kanttolerance +HISTORY_MSG_49;Kantfølsomhed farvestøj +HISTORY_MSG_4;Gennemse historie +HISTORY_MSG_50;Skygger/højlys værktøj +HISTORY_MSG_51;Forstærk højlys +HISTORY_MSG_52;Forstærk skygger +HISTORY_MSG_53;Højlys toneomfang +HISTORY_MSG_54;Skygger toneomfang +HISTORY_MSG_55;Lokal kontrast +HISTORY_MSG_56;Skygger/højlys radius +HISTORY_MSG_57;Grov rotering +HISTORY_MSG_58;Vend vandret +HISTORY_MSG_59;Vend lodret +HISTORY_MSG_5;Lysstyrke +HISTORY_MSG_60;Roter +HISTORY_MSG_61;Roter +HISTORY_MSG_62;Ret objektivfejl +HISTORY_MSG_63;Snapshot valgt +HISTORY_MSG_64;Beskær billede +HISTORY_MSG_65;Kromatisk aberration +HISTORY_MSG_66;Red højlys +HISTORY_MSG_67;Red højlys mængde +HISTORY_MSG_68;Red højlys metode +HISTORY_MSG_69;Nuværende farverum +HISTORY_MSG_6;Kontrast +HISTORY_MSG_70;Output farverum +HISTORY_MSG_71;Input farverum +HISTORY_MSG_72;Vignettering +HISTORY_MSG_73;Kanalmixer +HISTORY_MSG_74;Skift størrelse mÃ¥l +HISTORY_MSG_75;Skift størrelse metode +HISTORY_MSG_76;Exif metadata +HISTORY_MSG_77;IPTC metadata +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;Sort +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;Eksponeringskompensation +HISTORY_MSG_9;Kompensation af højlys +HISTORY_NEWSNAPSHOTAS;Som... +HISTORY_NEWSNAPSHOT;Tilføj... +HISTORY_NEWSSDIALOGLABEL;Mærke pÃ¥ snapshot: +HISTORY_NEWSSDIALOGTITLE;Tilføj nyt snapshot +HISTORY_SETTO;Sæt til +HISTORY_SNAPSHOT;Snapshot +HISTORY_SNAPSHOTS;Snapshots +ICMPANEL_FILEDLGFILTERANY;Alle filer +ICMPANEL_FILEDLGFILTERICM;ICC Profil-filer +ICMPANEL_GAMMABEFOREINPUT;Profil anvender Gamma +ICMPANEL_INPUTCAMERA;Kamerastandard +ICMPANEL_INPUTCUSTOM;Brugervalgt +ICMPANEL_INPUTDLGLABEL;Vælg Input ICC-profil... +ICMPANEL_INPUTEMBEDDED;Brug indlejrede, hvis mulligt +ICMPANEL_INPUTPROFILE;Input-profil +ICMPANEL_NOICM;No ICM: sRGB output +ICMPANEL_OUTPUTDLGLABEL;Vælg output ICC-profil... +ICMPANEL_OUTPUTPROFILE;Output-profil +ICMPANEL_SAVEREFERENCE;Gem referencebillede til profilering +ICMPANEL_WORKINGPROFILE;Nuværende profil +IMAGEAREA_DETAILVIEW;Se detaljer +IPTCPANEL_AUTHOR;Forfatter +IPTCPANEL_AUTHORHINT;Navn pÃ¥ skaberen af projektet, fx forfatter, fotograf eller grafisk kunstner (byline). +IPTCPANEL_AUTHORSPOSITION;Forfatterens stilling +IPTCPANEL_AUTHORSPOSITIONHINT;Stillingsbetegnelse for skaberen eller skaberne af objektet (byline titel). +IPTCPANEL_CAPTION;Billedtekst +IPTCPANEL_CAPTIONHINT;En beskrivelse af informationerne i tekstform. +IPTCPANEL_CAPTIONWRITERHINT;Navnet pÃ¥ den person, der har været indblandet i at skrive, redigere eller korrekturlæse billedet eller billedteksten. +IPTCPANEL_CAPTIONWRITER;Skribent pÃ¥ billedtekst +IPTCPANEL_CATEGORYHINT;Identificerer billedets emne efter skaberens mening. +IPTCPANEL_CATEGORY;Kategori +IPTCPANEL_CITY;By +IPTCPANEL_CITYHINT;Byen, hvor billedet er taget.. +IPTCPANEL_COPYHINT;Kopier IPTC-indstillinger til udklipsholder. +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COPYRIGHTHINT;Enhver nødvendig copyright-oplysning. +IPTCPANEL_COUNTRYHINT;Navnet pÃ¥ det land, hvor billedet blev taget. +IPTCPANEL_COUNTRY;Land +IPTCPANEL_CREDIT;Anerkendelse +IPTCPANEL_CREDITHINT;Identificerer den, der stiller billedet til rÃ¥dighed, ikke nødvendigvis ejeren/skaberen. +IPTCPANEL_DATECREATED;Dato skabt +IPTCPANEL_DATECREATEDHINT;Den dato, hvor det intellektuelle indhold i billedet blev skabt; Format: Ã…Ã…Ã…Ã…MMDD (Date Created). +IPTCPANEL_EMBEDDEDHINT;Genskab til indlejrede IPTC-data i billedfilen +IPTCPANEL_EMBEDDED;Indlejret +IPTCPANEL_HEADLINEHINT;En indførsel, som kan udgives og giver en opsummering af billedets indhold. +IPTCPANEL_HEADLINE;Overskrift +IPTCPANEL_INSTRUCTIONSHINT;Andre redaktionelle instruktioner angÃ¥ende billedets brug. +IPTCPANEL_INSTRUCTIONS;Instruktioner +IPTCPANEL_KEYWORDSHINT;Bruges til at angive særlige søgbare ord. +IPTCPANEL_KEYWORDS;Søgeord +IPTCPANEL_PASTEHINT;Indsæt IPTC-indstillinger fra udklipsholder +IPTCPANEL_PROVINCEHINT;Provinsen/delstaten, hvor billedet stammer fra. +IPTCPANEL_PROVINCE;Provins +IPTCPANEL_RESET;Genskab +IPTCPANEL_RESETHINT;Genskab til profilstandard +IPTCPANEL_SOURCEHINT;Den originale ejer af billedets intellektuelle indhold. +IPTCPANEL_SOURCE;Kilde +IPTCPANEL_SUPPCATEGORIESHINT;Yderligere angivelse af billedets emne. +IPTCPANEL_SUPPCATEGORIES;Suppl. katergorier +IPTCPANEL_TITLEHINT;En kort beskrivelse af billedet. +IPTCPANEL_TITLE;Titel +IPTCPANEL_TRANSREFERENCEHINT;En kode, der repræsenterer placeringen for den originale overlevering. +IPTCPANEL_TRANSREFERENCE;Overleveringsreference +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Indstillinger +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;Som... +MAIN_BUTTON_SAVE;Gem billede +MAIN_BUTTON_SENDTOEDITOR;Send til redigeringsprogram +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Filen eksisterer allerede. +MAIN_MSG_CANNOTLOAD;Kan ikke indlæse billede +MAIN_MSG_CANNOTSAVE;Kan ikke gemme filen +MAIN_MSG_CANNOTSTARTEDITOR;Kan ikke starte redigeringsprogram. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Brug venligst den korrekte sti i dialogboksen "Indstillinger". +MAIN_MSG_EXITJOBSINQUEUEINFO;Ubearbejdede billeder i køen vil blive mistet, nÃ¥r du lukker. +MAIN_MSG_EXITJOBSINQUEUEQUEST;er du sikker pÃ¥, at du vil lukke? Der er ubearbejdede billeder, som venter i køen. +MAIN_MSG_JOBSINQUEUE;Opgave(r) i køen +MAIN_MSG_QOVERWRITE;Vil du overskrive? +MAIN_TAB_BASIC;Grundlæggende +MAIN_TAB_COLOR;Farver +MAIN_TAB_DETAIL;Detaljer +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Eksponering +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Justér +MAIN_TOOLTIP_HIDEFP;Vis/skjul panelet i bunden (stifinder og filbrowser, genvejstast: F) +MAIN_TOOLTIP_HIDEHP;Vis/skjul panelet til venstre (heriblandt Historie, genvejstast: H) +MAIN_TOOLTIP_INDCLIPPEDH;Markér udbrændte højlys +MAIN_TOOLTIP_INDCLIPPEDS;Markér udbrændte skygger +MAIN_TOOLTIP_PREFERENCES;Vælg indstillinger +MAIN_TOOLTIP_QINFO;Udvalgte oplysninger om billedet +MAIN_TOOLTIP_SAVEAS;Gem billedet i en valgfri mappe +MAIN_TOOLTIP_SAVE;Gem billedet i standardmappen +PARTIALPASTE_BASICGROUP;Grundlæggende indstillinger +PARTIALPASTE_CACORRECTION;Kromatisk aberration +PARTIALPASTE_COARSETRANS;Drej/vend 90 grader +PARTIALPASTE_COLORBOOST;Forstærk farver +PARTIALPASTE_COLORDENOISE;Fjern farvestøj +PARTIALPASTE_COLORGROUP;Farverelaterede indstillinger +PARTIALPASTE_COLORMIXER;Farveblander +PARTIALPASTE_COLORSHIFT;Farveskift +PARTIALPASTE_COMPOSITIONGROUP;Kompositionsindstillinger +PARTIALPASTE_CROP;Beskær +PARTIALPASTE_DIALOGLABEL;Delvist indsætte bearbejdningsprofil +PARTIALPASTE_DISTORTION;Fortegning +PARTIALPASTE_EXIFCHANGES;Ændringer til exif-data +PARTIALPASTE_EXPOSURE;Eksponering +PARTIALPASTE_HLRECOVERY;Red højlys +PARTIALPASTE_ICMSETTINGS;ICM-indstillinger +PARTIALPASTE_IPTCINFO;IPTC-info +PARTIALPASTE_LENSGROUP;Objektivrelaterede indstillinger +PARTIALPASTE_LUMACURVE;Kurve +PARTIALPASTE_LUMADENOISE;Fjern lysstøj +PARTIALPASTE_LUMINANCEGROUP;Lysrelaterede indstillinger +PARTIALPASTE_METAICMGROUP;Metadata-/ICM-indstillinger +PARTIALPASTE_RESIZE;Ret størrelse +PARTIALPASTE_ROTATION;Rotér +PARTIALPASTE_SHADOWSHIGHLIGHTS;Skygger/Højlys +PARTIALPASTE_SHARPENING;Skarphed +PARTIALPASTE_VIGNETTING;Vignettering +PARTIALPASTE_WHITEBALANCE;Hvidbalance +PREFERENCES_APPLNEXTSTARTUP;Anvendes ved næste opstart +PREFERENCES_BLINKCLIPPED;Blink i udbrændte omrÃ¥der +PREFERENCES_CACHECLEARALL;Ryd alt +PREFERENCES_CACHECLEARPROFILES;Ryd profiler +PREFERENCES_CACHECLEARTHUMBS;Ryd miniaturer +PREFERENCES_CACHEFORMAT1;Proprietær (hurtigere og bedre kvalitet) +PREFERENCES_CACHEFORMAT2;JPEG (fylder mindre pÃ¥ disken) +PREFERENCES_CACHEMAXENTRIES;Maksimalt antal indskrivninger i cache +PREFERENCES_CACHEOPTS;Cache-indstillinger +PREFERENCES_CACHESTRAT1;Foretræk hastighed frem for lavt hukommelsesforbrug +PREFERENCES_CACHESTRAT2;Foretræk lavt hukommelsesforbrug frem for hastighed +PREFERENCES_CACHESTRAT;Cache-strategi +PREFERENCES_CACHETHUMBFORM;Cache miniature-format +PREFERENCES_CACHETHUMBHEIGHT;Maksimal miniaturehøjde +PREFERENCES_CLEARDLG_LINE1;Rydder cache +PREFERENCES_CLEARDLG_LINE2;Dette kan tage nogle sekunder. +PREFERENCES_CLEARDLG_TITLE;Vent venligst +PREFERENCES_CLIPPINGIND;Indikator for udbrændte omrÃ¥der +PREFERENCES_CMETRICINTENT;Colorimetrisk fortsæt +PREFERENCES_DATEFORMAT;Datoformat +PREFERENCES_DATEFORMATHINT;Du kan bruge følgende formatindstillinger:\n%y : Ã¥r\n%m : mÃ¥ned\n%d : dag\n\nDet typiske datoformat i danmark er:\n%d/%m/%y +PREFERENCES_DEFAULTLANG;Sprog +PREFERENCES_DEFAULTTHEME;Tema +PREFERENCES_DEMOSAICINGALGO;Algoritme til rekonstruktion +PREFERENCES_DIRHOME;Standardmappe +PREFERENCES_DIRLAST;Sidst anvendte mappe +PREFERENCES_DIROTHER;Andet +PREFERENCES_DIRSELECTDLG;Vælg startmappe... +PREFERENCES_DIRSOFTWARE;Installationsmappe +PREFERENCES_DMETHOD;Metode +PREFERENCES_EDITORCMDLINE;Anden kommandostreng +PREFERENCES_EXTERNALEDITOR;Eksternt redigeringsprogram +PREFERENCES_FALSECOLOR;Antal trin til undertrykkelse af forkert farve +PREFERENCES_FBROWSEROPTS;Indstllinger til filbrowser +PREFERENCES_FILEFORMAT;Filformat +PREFERENCES_FORIMAGE;Til billedfiler +PREFERENCES_FORRAW;Til RAW-filer +PREFERENCES_GIMPPATH;Installationsmappe til GIMP +PREFERENCES_GTKTHEME;GTK-standard +PREFERENCES_HINT;Hentydning +PREFERENCES_HLTHRESHOLD;Tærskel for udbrændte højlys +PREFERENCES_ICCDIR;Mappe med ICC-profiler +PREFERENCES_IMPROCPARAMS;Normale billedbehandlingsparametre +PREFERENCES_INTENT_ABSOLUTE;Absolut Colorimetrisk +PREFERENCES_INTENT_PERCEPTUAL;Opfattelsesorienteret +PREFERENCES_INTENT_RELATIVE;Relativ Colorimetrisk +PREFERENCES_INTENT_SATURATION;Mætning +PREFERENCES_LIVETHUMBNAILS;Opdaterede miniaturer (langsommere) +PREFERENCES_MONITORICC;Skærmprofil +PREFERENCES_OUTDIRFOLDER;Gem i mappe +PREFERENCES_OUTDIRFOLDERHINT;Læg det gemte billede i den valgte mappe +PREFERENCES_OUTDIRHINT;Du kan benytte følgende formatstrenge:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nDisse formatstrenge henviser til mapperne og undermapperne for RAW-filens sti.\n\nFx, hvis filen /Users\Peter\Pictures/02-09-2006/dsc0012.nefer blevet Ã¥bnet, er betydningen af formatstrengen:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/Users\Peter\Pictures/02-09-2006, %p2=/Users\Peter\Pictures, p3=/Users\Peter\Pictures, ...\n\nhvis du vil gemme output-billedet i samme mappe som originalen, skal du skrive:\n%p1/%f\n\nHvis du vil gemme output-billedet i en mappe, der hedder 'konverteret', som er placeret i originalens mappe, skal du skrive:\n%p1/konverteret/%f\n\nHvis du vil gemme output-billedet i mappen Users\Peter\Pictures\konverteret og beholde den samme undermappe med dato, skal du skrive:\n%p2/konverteret/%d1/%f +PREFERENCES_OUTDIR;Output-mappe +PREFERENCES_OUTDIRTEMPLATE;Brug skabelon +PREFERENCES_OUTDIRTEMPLATEHINT;Du kan benytte følgende formatstrenge:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nDisse formatstrenge henviser til mapperne og undermapperne for RAW-filens sti.\n\nFx, hvis filen /Users\Peter\Pictures/02-09-2006/dsc0012.nefer blevet Ã¥bnet, er betydningen af formatstrengen:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/Users\Peter\Pictures/02-09-2006, %p2=/Users\Peter\Pictures, p3=/Users\Peter\Pictures, ...\n\nhvis du vil gemme output-billedet i samme mappe som originalen, skal du skrive:\n%p1/%f\n\nHvis du vil gemme output-billedet i en mappe, der hedder 'konverteret', som er placeret i originalens mappe, skal du skrive:\n%p1/konverteret/%f\n\nHvis du vil gemme output-billedet i mappen Users\Peter\Pictures\konverteret og beholde den samme undermappe med dato, skal du skrive:\n%p2/konverteret/%d1/%f +PREFERENCES_PARSEDEXTADDHINT;Indtast en filendelse, og klik her for at tilføje til listen +PREFERENCES_PARSEDEXTADD;Tilføj filtype +PREFERENCES_PARSEDEXTDELHINT;Slet valgte filtype fra listen +PREFERENCES_PARSEDEXT;Indlæste filtyper +PREFERENCES_PROFILEHANDLING;Bearbejder profilbehandling +PREFERENCES_PROFILELOADPR;Profilindlæsningsrækkefølge +PREFERENCES_PROFILEPRCACHE;Profil i cache +PREFERENCES_PROFILEPRFILE;Profil sammen med input-filen +PREFERENCES_PROFILESAVECACHE;Gem bearbejdningsparametre i cache +PREFERENCES_PROFILESAVEINPUT;Gem bearbejdningsparametre sammen med input-filen +PREFERENCES_PSPATH;Installationsmappe til Adobe Photoshop +PREFERENCES_SELECTICCDIRDLG;Vælg mappe med ICC-profiler... +PREFERENCES_SELECTLANG;Vælg sprog +PREFERENCES_SELECTMONITORPROFDLG;Vælg skærmens ICC-profil... +PREFERENCES_SELECTTHEME;Vælg tema +PREFERENCES_SHOWBASICEXIF;Vis grundlæggende exif-data +PREFERENCES_SHOWDATETIME;Vis dato og tid +PREFERENCES_SHOWONLYRAW;Vis kun RAW-filer +PREFERENCES_SHTHRESHOLD;Tærskel for udbrændte skygger +PREFERENCES_STARTUPIMDIR;Billedmappe ved opstart +PREFERENCES_TAB_BROWSER;Filbrowser +PREFERENCES_TAB_COLORMGR;Farvestyring +PREFERENCES_TAB_GENERAL;Generelt +PREFERENCES_TAB_IMPROC;Billedbehandling +PREFERENCES_TAB_OUTPUT;Output-indstillinger +PREFERENCES_THUMBSIZE;Størrelse pÃ¥ miniaturer +PROFILEPANEL_FILEDLGFILTERANY;Alle filer +PROFILEPANEL_FILEDLGFILTERPP;Efterbehandlingsprofiler +PROFILEPANEL_LABEL;Efterbehandlingsprofiler +PROFILEPANEL_LOADDLGLABEL;Indlæs efterbehandlingsparametre... +PROFILEPANEL_PCUSTOM;Brugervalgt +PROFILEPANEL_PFILE;Fra fil +PROFILEPANEL_PLASTPHOTO;Seneste foto +PROFILEPANEL_PLASTSAVED;Senest gemte +PROFILEPANEL_PROFILE;Profil +PROFILEPANEL_SAVEDLGLABEL;Gem efterbehandlingsparametre... +PROFILEPANEL_TOOLTIPCOPY;Kopier nuværende profil til udklipsholder +PROFILEPANEL_TOOLTIPLOAD;Indlæs en profil fra fil +PROFILEPANEL_TOOLTIPPASTE; Indsæt profil fra udklipsholder +PROFILEPANEL_TOOLTIPSAVE;Gem nuværende profil +PROGRESSBAR_DECODING;Afkoder RAW-fil... +PROGRESSBAR_DEMOSAICING;Analyserer... +PROGRESSBAR_LOADING;Indlæser billede... +PROGRESSBAR_LOADJPEG;Indlæser JPEG-fil... +PROGRESSBAR_LOADPNG;Indlæser PNG-fil... +PROGRESSBAR_LOADTIFF;Indlæser TIFF-fil... +PROGRESSBAR_PROCESSING;bearbejder billede... +PROGRESSBAR_READY;Klar. +PROGRESSBAR_SAVEJPEG;Gemmer JPEG-fil... +PROGRESSBAR_SAVEPNG;Gemmer PNG-fil... +PROGRESSBAR_SAVETIFF;Gemmer TIFF-fil... +PROGRESSDLG_LOADING;Indlæser fil... +PROGRESSDLG_PROCESSING;bearbejder billede... +PROGRESSDLG_SAVING;Gemmer fil... +QINFO_FOCALLENGTH;Brændvidde +QINFO_ISO;ISO +QINFO_LENS;Objektiv +QINFO_NOEXIF;Exif-data ikke tilgængelig. +SAVEDLG_FILEFORMAT;Filformat +SAVEDLG_JPEGQUAL;JPEG-kvalitet +SAVEDLG_JPGFILTER;JPEG-filer +SAVEDLG_PNGCOMPR;PNG-komprimering +SAVEDLG_PNGFILTER;PNG-filer +SAVEDLG_PUTTOQUEUEHEAD;Sæt i begyndelsen af bearbejdningskøen +SAVEDLG_PUTTOQUEUE;Sæt i bearbejdningskø +SAVEDLG_PUTTOQUEUETAIL;Sæt i enden af bearbejdningskøen +SAVEDLG_SAVEIMMEDIATELY;Gem med det samme +SAVEDLG_SAVESPP;Gem bearbejdningsparametre med billede +SAVEDLG_TIFFFILTER;TIFF-filer +TOOLBAR_TOOLTIP_CROP;Beskær markering (Genvejstast: C) +TOOLBAR_TOOLTIP_HAND;HÃ¥ndværktøj (Genvejstast: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Ret op (Genvejstast: S) +TOOLBAR_TOOLTIP_WB;Vælg hvidbalance (Genvejstast: W) +TP_CACORRECTION_BLUE;BlÃ¥ +TP_CACORRECTION_LABEL;Kromatisk aberration +TP_CACORRECTION_RED;Rød +TP_CHMIXER_BLUE;BlÃ¥ +TP_CHMIXER_GREEN;Grøn +TP_CHMIXER_LABEL;Kanalmixer +TP_CHMIXER_RED;Rød +TP_COARSETRAF_DEGREE;grader: +TP_COARSETRAF_TOOLTIP_HFLIP;Vend vandret +TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotér mod uret +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotér med uret +TP_COARSETRAF_TOOLTIP_VFLIP;Vend lodret +TP_COLORBOOST_ACHANNEL;Kanal "a" +TP_COLORBOOST_AMOUNT;Mængde +TP_COLORBOOST_AVOIDCOLORCLIP;UndgÃ¥ farveklipning +TP_COLORBOOST_BCHANNEL;Kanal "b" +TP_COLORBOOST_CHAB;a & b +TP_COLORBOOST_CHANNEL;Kanal +TP_COLORBOOST_CHSEPARATE;Separér +TP_COLORBOOST_ENABLESATLIMITER;Anvend mætningsbegrænser +TP_COLORBOOST_LABEL;Forstærk farver +TP_COLORBOOST_SATLIMIT;Mætningsbegrænsning +TP_COLORDENOISE_EDGESENSITIVE;Kantfølsomhed +TP_COLORDENOISE_EDGETOLERANCE;kanttolerance +TP_COLORDENOISE_LABEL;Farvestøj +TP_COLORDENOISE_RADIUS;Radius +TP_COLORSHIFT_BLUEYELLOW;BlÃ¥-Gul +TP_COLORSHIFT_GREENMAGENTA;Grøn-Magenta +TP_COLORSHIFT_LABEL;Farveskift +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Fasthold sideforhold: +TP_CROP_GTDIAGONALS;Reglen om diagonaler +TP_CROP_GTHARMMEANS1;Harmonisk metode 1 +TP_CROP_GTHARMMEANS2;Harmonisk metode 2 +TP_CROP_GTHARMMEANS3;Harmonisk metode 3 +TP_CROP_GTHARMMEANS4;Harmonisk metode 4 +TP_CROP_GTNONE;Ingen +TP_CROP_GTRULETHIRDS;Reglen om tredjedele +TP_CROP_GUIDETYPE;Hjælpelinjer: +TP_CROP_H;H +TP_CROP_LABEL;Beskær +TP_CROP_SELECTCROP; Vælg beskæring +TP_CROP_W;B +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Mængde +TP_DISTORTION_LABEL;Fortegning +TP_EXPOSURE_AUTOLEVELS;Auto-niveauer +TP_EXPOSURE_BLACKLEVEL;Sort +TP_EXPOSURE_BRIGHTNESS;Lysstyrke +TP_EXPOSURE_CLIP;Klip +TP_EXPOSURE_COMPRHIGHLIGHTS;Komprimering af højlys +TP_EXPOSURE_COMPRSHADOWS;Komprimering af skygger +TP_EXPOSURE_CONTRAST;Kontrast +TP_EXPOSURE_CURVEEDITOR;Tonekurve +TP_EXPOSURE_EXPCOMP;Eksp. komp. +TP_EXPOSURE_LABEL;Eksponering +TP_HLREC_CIELAB;CIELab blanding +TP_HLREC_COLOR;Farveudbredelse +TP_HLREC_LABEL;Red højlys +TP_HLREC_LUMINANCE;Red lysforhold +TP_HLREC_METHOD;Metode: +TP_ICM_FILEDLGFILTERANY;alle filer +TP_ICM_FILEDLGFILTERICM;ICC-profil-filer +TP_ICM_GAMMABEFOREINPUT;Profil anvender gamma +TP_ICM_INPUTCAMERA;Kamerastandard +TP_ICM_INPUTCUSTOM;Brugervalgt +TP_ICM_INPUTDLGLABEL;Vælg input ICC-profil... +TP_ICM_INPUTEMBEDDED;Brug indlejrede, hvis muligt +TP_ICM_INPUTPROFILE;Input profil +TP_ICM_LABEL;ICM +TP_ICM_NOICM;No ICM: sRGB output +TP_ICM_OUTPUTDLGLABEL;Vælg output ICC-profil... +TP_ICM_OUTPUTPROFILE;Output profil +TP_ICM_SAVEREFERENCE;Gem referencebillede til profilering +TP_ICM_WORKINGPROFILE;Arbejdsprofil +TP_LUMACURVE_BLACKLEVEL;Sort +TP_LUMACURVE_BRIGHTNESS;Lysstyrke +TP_LUMACURVE_COMPRHIGHLIGHTS;Komprimering af højlys +TP_LUMACURVE_COMPRSHADOWS;Komprimering af skygger +TP_LUMACURVE_CONTRAST;Skygger +TP_LUMACURVE_CURVEEDITOR;Kurve for lysforhold +TP_LUMACURVE_LABEL;Kurve for lysforhold +TP_LUMADENOISE_EDGETOLERANCE;Kanttolerance +TP_LUMADENOISE_LABEL;Lysstøj +TP_LUMADENOISE_RADIUS;Radius +TP_RESIZE_BICUBIC;Bikubisk +TP_RESIZE_BICUBICSF;Bikubisk (blødere) +TP_RESIZE_BICUBICSH;Bikubisk (skarpere) +TP_RESIZE_BILINEAR;Bilineær +TP_RESIZE_FULLSIZE;Fuld billedstørrelse: +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Skift størrelse +TP_RESIZE_METHOD;Metode: +TP_RESIZE_NEAREST;Nærmeste +TP_RESIZE_SCALE;Skalér +TP_RESIZE_W;B: +TP_ROTATE_AUTOCROP;Autobeskæring +TP_ROTATE_DEGREE;Grader +TP_ROTATE_FILL;Udfyld +TP_ROTATE_LABEL;Rotér +TP_ROTATE_SELECTLINE;Vælg lige linie +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Højlys +TP_SHADOWSHLIGHTS_HLTONALW;Toneomfang +TP_SHADOWSHLIGHTS_LABEL;Skygger/højlys +TP_SHADOWSHLIGHTS_LOCALCONTR;Local kontrast +TP_SHADOWSHLIGHTS_RADIUS;Radius +TP_SHADOWSHLIGHTS_SHADOWS;Skygger +TP_SHADOWSHLIGHTS_SHTONALW;Toneomfang +TP_SHARPENING_AMOUNT;Mængde +TP_SHARPENING_EDRADIUS;Radius +TP_SHARPENING_EDTOLERANCE;Kanttolerance +TP_SHARPENING_HALOCONTROL;Halo-kontrol +TP_SHARPENING_HCAMOUNT;Mængde +TP_SHARPENING_LABEL;Skarphed +TP_SHARPENING_METHOD;Metode +TP_SHARPENING_ONLYEDGES;Gør kun kanter skarpere +TP_SHARPENING_RADIUS;Radius +TP_SHARPENING_RLD_AMOUNT;Mængde +TP_SHARPENING_RLD_DAMPING;Dæmpning +TP_SHARPENING_RLD_ITERATIONS;Gentagelser +TP_SHARPENING_RLD;RL Udfoldning +TP_SHARPENING_THRESHOLD;Tærskel +TP_SHARPENING_USM;Uskarp maske +TP_VIGNETTING_AMOUNT;Mængde +TP_VIGNETTING_LABEL;Vignettering +TP_VIGNETTING_RADIUS;Radius +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Kamera +TP_WBALANCE_CUSTOM;Brugervalgt +TP_WBALANCE_GREEN;Nuance +TP_WBALANCE_LABEL;Hvidbalance +TP_WBALANCE_METHOD;Metode +TP_WBALANCE_SIZE;Størrelse: +TP_WBALANCE_SPOTWB;MÃ¥l WB +TP_WBALANCE_TEMPERATURE;Temperatur +ZOOMBAR_DETAIL;Detalje +ZOOMBAR_HUGE;Kæmpe +ZOOMBAR_LARGE;Stor +ZOOMBAR_NORMAL;Normal +ZOOMBAR_PREVIEW;ForhÃ¥ndsvisning +ZOOMBAR_SCALE;Skalér +ZOOMBAR_SMALL;Lille + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch new file mode 100644 index 000000000..a432bcbb2 --- /dev/null +++ b/rtdata/languages/Deutsch @@ -0,0 +1,713 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# Deutsch: Deutschland +# (keenonkites; Aktualisierte Version für 2.3 beta2) +# (phberlin; basiert auf keenonkites' Erstübersetzung) +# 08.01.2008/15.01.2008/20.02.2008 +# 19.12.2008: keenonkites, Anpassungen für 2.4beta4 +# 20.12.2007 +# 20.9.2008: keenonkites, Anpassungen für 2.4m2 +# 22.12.2007 +# 4.4.2008: Anpassungen für 2.4 +# Leichte Anpassungen (keenonkites/klonk) +ADJUSTER_RESET_TO_DEFAULT;Zurück zum Standard +CURVEEDITOR_FILEDLGFILTERANY;Alle Dateien +CURVEEDITOR_FILEDLGFILTERCURVE;Kurvendateien +CURVEEDITOR_LINEAR;Linear +CURVEEDITOR_LOADDLGLABEL;Kurve Laden... +CURVEEDITOR_SAVEDLGLABEL;Kurve Speichern... +CURVEEDITOR_TOOLTIPLINEAR;Zurücksetzen der Kurve (linear) +CURVEEDITOR_TOOLTIPLOAD;Laden einer Kurve +CURVEEDITOR_TOOLTIPSAVE;Speichern der aktuellen Kurve +EXIFFILTER_APERTURE;Blende +EXIFFILTER_CAMERA;Kamera +EXIFFILTER_DIALOGLABEL;Exif Filter +EXIFFILTER_FOCALLEN;Brennweite +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objektiv +EXIFFILTER_SHUTTER;Verschlusszeit +EXIFPANEL_ADDEDIT;Neu/Ändern +EXIFPANEL_ADDEDITHINT;Hinzufügen eines neuen oder Ändern eines bestehenden Attributs +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Wert eingeben +EXIFPANEL_ADDTAGDLG_SELECTTAG;Attribut wählen +EXIFPANEL_ADDTAGDLG_TITLE;Attribut hinzufügen/ändern +EXIFPANEL_KEEP;Behalten +EXIFPANEL_KEEPHINT;Behalten der gewählten Attribute beim Erzeugen des Bildes +EXIFPANEL_REMOVE;Entfernen +EXIFPANEL_REMOVEHINT;Entfernen der gewählten Attributen beim Erzeugen des Bildes +EXIFPANEL_RESET;Zurücksetzen +EXIFPANEL_RESETALL;Alle zurücksetzen +EXIFPANEL_RESETALLHINT;Alle Attribute zu den ursrpünglichen Werten zurücksetzen +EXIFPANEL_RESETHINT;Gewählte Attribute zu den ursprünglich Werten zurücksetzen +EXIFPANEL_SUBDIRECTORY;Unterverzeichnis +FILEBROWSER_APPLYPROFILE;Profil anwenden +FILEBROWSER_ARRANGEMENTHINT;Wechseln zwischen vertikaler und horizontaler Ausrichtung der Voransichten +FILEBROWSER_CLEARPROFILE;Profil löschen +FILEBROWSER_COPYPROFILE;Profil kopieren +FILEBROWSER_DELETEDLGLABEL;Bestätige Löschen von Dateien +FILEBROWSER_DELETEDLGMSG;Wollen sie wirklich %1 Dateien löschen? +FILEBROWSER_EMPTYTRASH;Papierkorb leeren +FILEBROWSER_EMPTYTRASHHINT;Endgültiges Löschen der Dateien im Papierkorb +FILEBROWSER_EXIFFILTERAPPLY;Anwenden +FILEBROWSER_EXIFFILTERAPPLYHINT;Ein-/Ausschalten des Exif Filters im Datei-Browser +FILEBROWSER_EXIFFILTERLABEL;Exif Filter +FILEBROWSER_EXIFFILTERSETTINGS;Einstellungen +FILEBROWSER_EXIFFILTERSETTINGSHINT;Ändern der Einstellungen des Exif Filters +FILEBROWSER_PARTIALPASTEPROFILE;Profil selektiv einfügen +FILEBROWSER_PASTEPROFILE;Profil einfügen +FILEBROWSER_POPUPCANCELJOB;Job abbrechen +FILEBROWSER_POPUPMOVEEND;Ans Ende der Warteschlange verschieben +FILEBROWSER_POPUPMOVEHEAD;An den Anfang der Warteschlange verschieben +FILEBROWSER_POPUPOPEN;Öffnen +FILEBROWSER_POPUPPROCESS;Bild zur Warteschlange hinzufügen +FILEBROWSER_POPUPRANK1;Mit 1 Stern bewerten +FILEBROWSER_POPUPRANK2;Mit 2 Sternen bewerten +FILEBROWSER_POPUPRANK3;Mit 3 Sternen bewerten +FILEBROWSER_POPUPRANK4;Mit 4 Sternen bewerten +FILEBROWSER_POPUPRANK5;Mit 5 Sternen bewerten +FILEBROWSER_POPUPREMOVE;Aus dem Verzeichnis Löschen +FILEBROWSER_POPUPRENAME;Umbenennen +FILEBROWSER_POPUPSELECTALL;Alle auswählen +FILEBROWSER_POPUPTRASH;In den Papierkorb verschieben +FILEBROWSER_POPUPUNRANK;Entfernen der Bewertung +FILEBROWSER_POPUPUNTRASH;Aus dem Papierkorb retten +FILEBROWSER_PROCESSINGSETTINGS;Einstellungen +FILEBROWSER_PROCESSINGSETTINGSHINT;Einstellen von Ausgabeformat und Ausgabeverzeichnis +FILEBROWSER_RENAMEDLGLABEL;Datei umbenennen +FILEBROWSER_RENAMEDLGMSG;Umbenennen der Datei "%1" nach: +FILEBROWSER_SHOWDIRHINT;Alle Bilder im Verzeichnis zeigen +FILEBROWSER_SHOWQUEUEHINT;Inhalt der Warteschlange zeigen +FILEBROWSER_SHOWRANK1HINT;Bilder 1 Stern zeigen +FILEBROWSER_SHOWRANK2HINT;Bilder 2 Stern zeigen +FILEBROWSER_SHOWRANK3HINT;Bilder 3 Stern zeigen +FILEBROWSER_SHOWRANK4HINT;Bilder 4 Stern zeigen +FILEBROWSER_SHOWRANK5HINT;Bilder 5 Stern zeigen +FILEBROWSER_SHOWTRASHHINT;Bilder im Papierkorb zeigen +FILEBROWSER_SHOWUNRANKHINT;Unbewertete Bilder zeigen +FILEBROWSER_STARTPROCESSING;Verarbeitung starten +FILEBROWSER_STARTPROCESSINGHINT;Verarbeitung/Speichern der Bilder in der Warteschlange starten +FILEBROWSER_STOPPROCESSING;Verarbeitung stoppen +FILEBROWSER_STOPPROCESSINGHINT;Verarbeitung der Bilder stoppen +FILEBROWSER_THUMBSIZE;Grösse d. Vorschau +FILEBROWSER_ZOOMINHINT;Vergrössern der Vorschau +FILEBROWSER_ZOOMOUTHINT;Verkleinern der Vorschau +GENERAL_ABOUT;Über +GENERAL_CANCEL;Abbruch +GENERAL_DISABLE;ausschalten +GENERAL_DISABLED;ausgeschaltet +GENERAL_ENABLE;einschalten +GENERAL_ENABLED;eingeschaltet +GENERAL_LANDSCAPE;Quer +GENERAL_LOAD;Laden +GENERAL_NA;n/a +GENERAL_NO;Nein +GENERAL_OK;OK +GENERAL_PORTRAIT;Hoch +GENERAL_SAVE;Speichern +GENERAL_YES;Ja +HISTOGRAM_LABEL;Histogram +HISTOGRAM_TOOLTIP_B;Zeigen/Verstecke BLAU-Histogramm +HISTOGRAM_TOOLTIP_G;Zeigen/Verstecke GRÜN-Histogramm +HISTOGRAM_TOOLTIP_L;Zeigen/Verstecke CIELAB-Luminanz-Histogramm +HISTOGRAM_TOOLTIP_R;Zeigen/Verstecke ROT-Histogramm +HISTORY_CHANGED;Verändert +HISTORY_CUSTOMCURVE;Benutzerdefinierte Kurve +HISTORY_DELSNAPSHOT;Variante löschen +HISTORY_FROMCLIPBOARD;Aus der Zwischenablage +HISTORY_LABEL;Abfolge der Änderungen +HISTORY_MSG_10;Schatten-Kompression +HISTORY_MSG_11;Tonwertkurve +HISTORY_MSG_12;Automatische Belichtung +HISTORY_MSG_13;Belichtungsbeschneidung +HISTORY_MSG_14;Luminanz Helligkeit +HISTORY_MSG_15;Luminanz Kontrast +HISTORY_MSG_16;Luminanz Schwarz +HISTORY_MSG_17;Luminanz Lichter-Kompression +HISTORY_MSG_18;Luminanz Schatten-Kompression +HISTORY_MSG_19;Luminanz Kurve +HISTORY_MSG_1;Bild geladen +HISTORY_MSG_20;Schärfen +HISTORY_MSG_21;Schärfen Radius +HISTORY_MSG_22;Schärfen Menge +HISTORY_MSG_23;Schärfen Schwellwert +HISTORY_MSG_24;Schärfen nur Kanten +HISTORY_MSG_25;Schärfen Kantensuche Radius +HISTORY_MSG_26;Schärfen Kanten-Toleranz +HISTORY_MSG_27;Schärfen Halo-Kontrolle +HISTORY_MSG_28;Schärfen Halo-Kontrolle Menge +HISTORY_MSG_29;Schärfen Methode +HISTORY_MSG_2;Profil geladen +HISTORY_MSG_30;Dekonvolution Radius +HISTORY_MSG_31;Dekonvolution Menge +HISTORY_MSG_32;Dekonvolution Dämpfung +HISTORY_MSG_33;Dekonvolution Iterationen +HISTORY_MSG_34;Verhindere Farbbeschneidungen +HISTORY_MSG_35;Begrenzung der Sättigung +HISTORY_MSG_36;Sättigungsgrenzwert +HISTORY_MSG_37;Farbverstärkung +HISTORY_MSG_38;Weißabgleich Methode +HISTORY_MSG_39;Farbtemperatur +HISTORY_MSG_3;Profil geändert +HISTORY_MSG_40;Weißabgleich Farbton +HISTORY_MSG_41;Farbkorrektur "A" +HISTORY_MSG_42;Farbkorrektur "B" +HISTORY_MSG_43;Luminanz-Rauschfilter +HISTORY_MSG_44;Luminanz-Rauschfilter Radius +HISTORY_MSG_45;Luminanz-Rauschfilter Kantentoleranz +HISTORY_MSG_46;Farb-Rauschfilter +HISTORY_MSG_47;Farb-Rauschfilter Radius +HISTORY_MSG_48;Farb-Rauschfilter Kantentoleranz +HISTORY_MSG_49;Farb-Rauschfilter Kantensuche +HISTORY_MSG_4;Abfolge der Änderungen durchsehen +HISTORY_MSG_50;Schatten/Lichter-Werkzeug +HISTORY_MSG_51;Abschwächen der Lichter +HISTORY_MSG_52;Verstärken der Schatten +HISTORY_MSG_53;Tonweite Lichter +HISTORY_MSG_54;Tonweite Schatten +HISTORY_MSG_55;Lokaler Kontrast +HISTORY_MSG_56;Schatten/Lichter-Radius +HISTORY_MSG_57;grobe Drehung +HISTORY_MSG_58;Horizontal spiegeln +HISTORY_MSG_59;Vertikal spiegeln +HISTORY_MSG_5;Helligkeit +HISTORY_MSG_60;Drehung +HISTORY_MSG_61;Drehung +HISTORY_MSG_62;Objektiv-Verzerrungskorrektur +HISTORY_MSG_63;Variante gewählt +HISTORY_MSG_64;Bild beschneiden +HISTORY_MSG_65;Farbsaum-Entfernung +HISTORY_MSG_66;Lichter wiederherstellen +HISTORY_MSG_67;Lichter wiederherstellen Menge +HISTORY_MSG_68;Lichter wiederherstellen Methode +HISTORY_MSG_69;Aktueller Farbraum +HISTORY_MSG_6;Kontrast +HISTORY_MSG_70;Farbraum für Ausgabe +HISTORY_MSG_71;Farbraum für Eingabe +HISTORY_MSG_72;Korrektur Randlichtabfall +HISTORY_MSG_73;Kanal-Mixer +HISTORY_MSG_74;Änderung Größe - Maßstab +HISTORY_MSG_75;Änderung Größe - Methode +HISTORY_MSG_76;Exif Metadaten +HISTORY_MSG_77;IPTC Metadaten +HISTORY_MSG_78;Angaben für Änderung Größe +HISTORY_MSG_79;Änderung Größe - Breite +HISTORY_MSG_7;Schwarz +HISTORY_MSG_80;Änderung Größe - Höhe +HISTORY_MSG_81;Änderung Größe - eingeschaltet +HISTORY_MSG_8;Belichtungskorrektur +HISTORY_MSG_9;Lichter-Kompression +HISTORY_NEWSNAPSHOT;Neue Variante +HISTORY_NEWSNAPSHOTAS;als... +HISTORY_NEWSSDIALOGLABEL;Name der Variante: +HISTORY_NEWSSDIALOGTITLE;Variante hinzufügen +HISTORY_SETTO;Setzen auf +HISTORY_SNAPSHOT;Variante +HISTORY_SNAPSHOTS;Varianten +ICMPANEL_FILEDLGFILTERANY;Alle Dateien +ICMPANEL_FILEDLGFILTERICM;ICC-Profildatei +ICMPANEL_GAMMABEFOREINPUT;Profil enthält Gammaanpassung +ICMPANEL_INPUTCAMERA;Kamera-Standard +ICMPANEL_INPUTCUSTOM;Benutzerdefiniert +ICMPANEL_INPUTDLGLABEL;Wähle Eingabe-ICC-Profil... +ICMPANEL_INPUTEMBEDDED;Verwende eingebettetes, wenn möglich +ICMPANEL_INPUTPROFILE;Eingabeprofil +ICMPANEL_NOICM;Kein ICM: sRGB-Ausgabe +ICMPANEL_OUTPUTDLGLABEL;Wähle Ausgabe-ICC-Profil... +ICMPANEL_OUTPUTPROFILE;Ausgabeprofil +ICMPANEL_SAVEREFERENCE;Speichere Referenzbild für die Profilierung +ICMPANEL_WORKINGPROFILE;Arbeitsfarbraum +IMAGEAREA_DETAILVIEW;Detailansicht +IPTCPANEL_AUTHOR;Autor +IPTCPANEL_AUTHORHINT;Name des Autors, z.B. Name des Fotografen oder des Künstlers (By-line). +IPTCPANEL_AUTHORSPOSITION;Position des Autors +IPTCPANEL_AUTHORSPOSITIONHINT;Titel des Autors oder der Autoren (By-line Title). +IPTCPANEL_CAPTION;Bildbeschreibung +IPTCPANEL_CAPTIONHINT;Beschreibung des Bildinhaltes (Caption - Abstract) +IPTCPANEL_CAPTIONWRITER;Autor der Bildbeschreibung +IPTCPANEL_CAPTIONWRITERHINT;Name der beim Schreiben, Editieren oder Korrigieren des Bildes oder der Bildbeschreibung beteiligten Person (Writer - Editor). +IPTCPANEL_CATEGORY;Kategorie +IPTCPANEL_CATEGORYHINT;3-stelliger Code, der die Kategorie des Bildes beschreibt (Category). +IPTCPANEL_CITY;Stadt +IPTCPANEL_CITYHINT;Aufnahmeort: Stadt (City). +IPTCPANEL_COPYHINT;IPTC Werte in die Zwischenablage kopieren +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COPYRIGHTHINT;Alle nötigen Hinweise über Urheberrechte (Copyright Notice). +IPTCPANEL_COUNTRY;Land +IPTCPANEL_COUNTRYHINT;Aufnahmeort: Land (Country - Primary Location Name). +IPTCPANEL_CREDIT;Bildrechte +IPTCPANEL_CREDITHINT;Identifiziert den Anbieter des Bildes, es muss nicht der Eigentümer sein (Credit). +IPTCPANEL_DATECREATED;Erstellt am +IPTCPANEL_DATECREATEDHINT;Das Datum an dem der Inhalt des Bildes kreiert wurde; Format: JJJJMMTT (Date Created). +IPTCPANEL_EMBEDDED;Eingebettete +IPTCPANEL_EMBEDDEDHINT;Zu den im Bild eingebetteten Werten zurücksetzen. +IPTCPANEL_HEADLINE;Bildtitel +IPTCPANEL_HEADLINEHINT;Kurzform der Bildbeschreibung, könnte als Überschrift an das Bild geklebt werden (Headline). +IPTCPANEL_INSTRUCTIONS;Hinweise +IPTCPANEL_INSTRUCTIONSHINT;Besondere Hinweise bezüglich der Verwendung des Bildes (Special Instructions). +IPTCPANEL_KEYWORDS;Schlagwörter +IPTCPANEL_KEYWORDSHINT;Stichwörter für das spätere Wiederfinden der Bilder (Keywords). +IPTCPANEL_PASTEHINT;Einfügen der IPTC Werte aus der Zwischenablage +IPTCPANEL_PROVINCE;Provinz +IPTCPANEL_PROVINCEHINT;Aufnahmeort: Provinz (Province-State). +IPTCPANEL_RESET;Zurücksetzen +IPTCPANEL_RESETHINT;Zu den im Profil gesetzten Werten zurücksetzen. +IPTCPANEL_SOURCE;Quelle +IPTCPANEL_SOURCEHINT;Der ursprüngliche Eigentümer des Werkes auf dem Bild (Source). +IPTCPANEL_SUPPCATEGORIES;Zusätz. Kategorien +IPTCPANEL_SUPPCATEGORIESHINT;Frei wählbare zusätzliche Kategorien (Supplemental Categories). +IPTCPANEL_TITLE;Titel +IPTCPANEL_TITLEHINT;Kurztitel des Bildes (Object Name). +IPTCPANEL_TRANSREFERENCE;Übertragungs Referenz +IPTCPANEL_TRANSREFERENCEHINT;Ein Code, der den ursprünglichen Ort der Übertragung definiert (Original Transmission Reference). +MAIN_BUTTON_EXIT;Verlassen +MAIN_BUTTON_EXIT;Verlassen +MAIN_BUTTON_PREFERENCES;Einstellungen +MAIN_BUTTON_QUEUE;Auf die Warteschlange +MAIN_BUTTON_SAVE;Bild speichern +MAIN_BUTTON_SAVEAS;unter... +MAIN_BUTTON_SENDTOEDITOR;Im Editor laden +MAIN_FRAME_BATCHQUEUE;Warteschlange +MAIN_FRAME_FILEBROWSER;Dateiverwaltung +MAIN_FRAME_PLACES;Orte +MAIN_FRAME_PLACES_ADD;Hinzu +MAIN_FRAME_PLACES_DEL;Löschen +MAIN_FRAME_RECENT;Verwendete Ordner +MAIN_MSG_ALREADYEXISTS;Diese Datei existiert schon. +MAIN_MSG_CANNOTLOAD;Bild kann nicht geladen werden +MAIN_MSG_CANNOTSAVE;Fehler beim Speichern +MAIN_MSG_CANNOTSTARTEDITOR;Der Editor kann nicht gestartet werden. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Setzen Sie bitte den richtigen Pfad in den Einstellungen. +MAIN_MSG_EXITJOBSINQUEUEINFO;Unverarbeitete Bilder in der Warteschlange gehen beim Verlassen der Anwendung verloren. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Wollen Sie die Anwendung wirklich schliessen ? Es hat noch unverarbeitete Bilder in der Warteschlange. +MAIN_MSG_JOBSINQUEUE;Job in Bearbeitung +MAIN_MSG_QOVERWRITE;Wollen sie die Datei überschreiben ? +MAIN_TAB_BASIC;Basis +MAIN_TAB_COLOR;Farbe +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DEVELOP;Entwickeln +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Belichtung +MAIN_TAB_FILTER;Metadaten-Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Verändern +MAIN_TOOLTIP_HIDEFP;Zeigen/Verstecken von Verzeichnis- und Datei-Browser (Taste F) +MAIN_TOOLTIP_HIDEHP;Zeigen/Verstecken linke Seite (Abfolge der Änderungen, Taste H) +MAIN_TOOLTIP_INDCLIPPEDH;zu helle Bereiche blinken +MAIN_TOOLTIP_INDCLIPPEDS;zu dunkle Bereiche blinken +MAIN_TOOLTIP_PREFERENCES;Einstellungen ändern +MAIN_TOOLTIP_QINFO;Kurze Info über das Bild +MAIN_TOOLTIP_SAVE;Speichere Bild im Standard-Verzeichnis +MAIN_TOOLTIP_SAVEAS;Speichere Bild in anderem Verzeichnis +PARTIALPASTE_BASICGROUP;Gruppe Basiseinstellungen +PARTIALPASTE_CACORRECTION;Farbsaum-Entfernung +PARTIALPASTE_COARSETRANS;90 Grad Rotieren / Spiegeln +PARTIALPASTE_COLORBOOST;Farbverstärkung +PARTIALPASTE_COLORDENOISE;Farb-Rauschfilter +PARTIALPASTE_COLORGROUP;Gruppe Farbeinstellungen +PARTIALPASTE_COLORMIXER;Kanal-Mixer +PARTIALPASTE_COLORSHIFT;Farbverschiebung +PARTIALPASTE_COMPOSITIONGROUP;Gruppe Gestaltungseinstellungen +PARTIALPASTE_CROP;Ausschnitt +PARTIALPASTE_DIALOGLABEL;Selektives Einfügen des Bearbeitungsprofiles +PARTIALPASTE_DISTORTION;Entzerrung +PARTIALPASTE_EXIFCHANGES;Exifdaten Änderungen +PARTIALPASTE_EXPOSURE;Belichtung +PARTIALPASTE_HLRECOVERY;Lichter wiederherstellen +PARTIALPASTE_ICMSETTINGS;Einstellungen ICM +PARTIALPASTE_IPTCINFO;IPTC Informationen +PARTIALPASTE_LENSGROUP;Gruppe Farbeinstellungen +PARTIALPASTE_LUMACURVE;Luminanzkurve +PARTIALPASTE_LUMADENOISE;Luminanz-Rauschfilter +PARTIALPASTE_LUMINANCEGROUP;Gruppe Luminanzeinstellungen +PARTIALPASTE_METAICMGROUP;Gruppe Einstellungen Metadaten/ICM +PARTIALPASTE_RESIZE;Grösse ändern +PARTIALPASTE_ROTATION;Drehen +PARTIALPASTE_SHADOWSHIGHLIGHTS;Schatten/Lichter +PARTIALPASTE_SHARPENING;Schärfen +PARTIALPASTE_VIGNETTING;Korrektur Randlichtabfall +PARTIALPASTE_WHITEBALANCE;Weissabgleich +PREFERENCES_APPLNEXTSTARTUP;beim nächsten Programmstart aktiv +PREFERENCES_BLINKCLIPPED;Zu helle/zu dunkle Bereiche blinken +PREFERENCES_CACHECLEARALL;Alles Löschen +PREFERENCES_CACHECLEARPROFILES;Löschen der Profile +PREFERENCES_CACHECLEARTHUMBS;Löschen der Voransichten +PREFERENCES_CACHEFORMAT1;Proprietär (schneller und höhere Qualität) +PREFERENCES_CACHEFORMAT2;JPEG (geringerer Diskplatz) +PREFERENCES_CACHEMAXENTRIES;Maximale Anzahl der Einträge im Zwischenspeicher +PREFERENCES_CACHEOPTS;Einstellungen des Zwischenspeichers für die Voransichten (Cache) +PREFERENCES_CACHESTRAT1;Priorität auf Geschwindigkeit (erhöhter Speicherverbrauch) +PREFERENCES_CACHESTRAT2;Priorität auf minimierten Speicherverbrauch (geringere Geschwindigkeit) +PREFERENCES_CACHESTRAT;Strategie des Zwischenspeichers +PREFERENCES_CACHETHUMBFORM;Format des Zwischenspeichers +PREFERENCES_CACHETHUMBHEIGHT;Maximale Höhe der Voransichten +PREFERENCES_CLEARDLG_LINE1;Löschen des Zwischenspeichers +PREFERENCES_CLEARDLG_LINE2;Das kann einige Sekunden dauern. +PREFERENCES_CLEARDLG_TITLE;Bitte warten +PREFERENCES_CLIPPINGIND;Anzeige zu helle/zu dunkle Bereiche +PREFERENCES_CMETRICINTENT;Farbraumtransformation +PREFERENCES_DATEFORMAT;Datumsformat +PREFERENCES_DATEFORMATHINT;Die folgenden Variablen können verwendet werden:\n%y : Jahr\n%m : Monat\n%d : Tag\n\nDas Deutsche Datumsformat zum Beispiel ist:\n%d/%m/%y +PREFERENCES_DCBENHANCE;DCB Verfeinerungsschritt durchführen +PREFERENCES_DCBITERATIONS;Anzahl der DCB Iterationen +PREFERENCES_DEFAULTLANG;Sprache für die Menüs und Dialoge +PREFERENCES_DEFAULTTHEME;Standard Oberflächendesign +PREFERENCES_DEMOSAICINGALGO;Algorithmus zur Entrasterung +PREFERENCES_DIRHOME;Benutzer-Verzeichnis +PREFERENCES_DIRLAST;Zuletzt geöffnetes Verzeichnis +PREFERENCES_DIROTHER;Anderes +PREFERENCES_DIRSELECTDLG;Wähle das Bild-Verzeichnis beim Programmstart... +PREFERENCES_DIRSOFTWARE;Installationsverzeichnis +PREFERENCES_DMETHOD;Methode +PREFERENCES_EDITORCMDLINE;Andere Befehlszeile +PREFERENCES_EXTERNALEDITOR;Externer Editor +PREFERENCES_FALSECOLOR;Stufen zur Unterdrückung von Falschfarben +PREFERENCES_FBROWSEROPTS;Datei-Browser-Einstellungen +PREFERENCES_FILEFORMAT;Datei-Format +PREFERENCES_FORIMAGE;Für Bild-Dateien +PREFERENCES_FORRAW;Für RAW-Dateien +PREFERENCES_GIMPPATH;GIMP Installations Verzeichnis +PREFERENCES_GTKTHEME;Standard GTK +PREFERENCES_HINT;Erklärungen +PREFERENCES_HLTHRESHOLD;Schwellwert - zu hell +PREFERENCES_ICCDIR;ICC-Profile-Verzeichnis +PREFERENCES_IMPROCPARAMS;Standard-Bildbearbeitungsparameter +PREFERENCES_INTENT_ABSOLUTE;Absolut farbmetrisch +PREFERENCES_INTENT_PERCEPTUAL;Wahrnehmungsabhängig +PREFERENCES_INTENT_RELATIVE;Relative farbmetrisch +PREFERENCES_INTENT_SATURATION;Sättigung +PREFERENCES_LIVETHUMBNAILS;Live Voransichten (langsamer) +PREFERENCES_MONITORICC;Monitor-Profil +PREFERENCES_OUTDIR;Ausgabe-Verzeichnis +PREFERENCES_OUTDIRFOLDER;Speichern in Verzeichnis +PREFERENCES_OUTDIRFOLDERHINT;Ablegen der gespeicherten Bilder in ein ausgewähltes Verzeichnis +PREFERENCES_OUTDIRHINT;Die folgenden Variablen können verwendet werden:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nDiese Variablen referenzieren die Verzeichnisse und Unterverzeichnisse des Pfades in dem das RAW liegt.\n\nWenn zum Beispiele /home/tom/image/02-09-2006/dsc0012.nefgeöffnet wurde, dann haben die Variablen den folgenden Inhalt:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nWenn Sie die Ausgabedatei in das selbe Verzeichnis wie das RAW speichern wollen, dann wählen Sie:\n%p1/%f\n\nWenn sie die Ausgabedatei in ein Unterverzeichnis mit dem Namen 'konvertiert' schreiben wollen, wählen sie:\n%p1/konvertiert/%f\n\nWenn Sie die Ausgabedatei im Verzeichnis '/home/tom/converted' unter beibehaltung des letzen Verzeichnisses wo das RAW lag, dann wählen sie:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Verwenden einer Vorlage +PREFERENCES_OUTDIRTEMPLATEHINT;Die folgenden Variablen können verwendet werden:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nDiese Variablen referenzieren die Verzeichnisse und Unterverzeichnisse des Pfades in dem das RAW liegt.\n\nWenn zum Beispiele /home/tom/image/02-09-2006/dsc0012.nefgeöffnet wurde, dann haben die Variablen den folgenden Inhalt:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nWenn Sie die Ausgabedatei in das selbe Verzeichnis wie das RAW speichern wollen, dann wählen Sie:\n%p1/%f\n\nWenn sie die Ausgabedatei in ein Unterverzeichnis mit dem Namen 'konvertiert' schreiben wollen, wählen sie:\n%p1/konvertiert/%f\n\nWenn Sie die Ausgabedatei im Verzeichnis '/home/tom/converted' unter beibehaltung des letzen Verzeichnisses wo das RAW lag, dann wählen sie:\n%p2/converted/%d1/%f +PREFERENCES_PARSEDEXT;Im Datei-Browser angezeigte Datei-Typen +PREFERENCES_PARSEDEXTADD;Datei-Typ hinzufügen +PREFERENCES_PARSEDEXTADDHINT;Gebe einen Datei-Typ (Extension) ein und drücke diesen Knopf um diesen Typ hinzuzufügen +PREFERENCES_PARSEDEXTDELHINT;Lösche den ausgewählten Datei-Typ von der Liste +PREFERENCES_PROFILEHANDLING;Behandlung der Bearbeitungsprofile +PREFERENCES_PROFILELOADPR;Priorität der Profile beim Laden +PREFERENCES_PROFILEPRCACHE;Bearbeitungsprofil im Zwischenspeicher (Cache) +PREFERENCES_PROFILEPRFILE;Bearbeitungsprofile bei der urpsrünglich geladenen Datei +PREFERENCES_PROFILESAVECACHE;Speichern der Verarbeitungsparameter im Zwischenspeicher (Cache) +PREFERENCES_PROFILESAVEINPUT;Speichern der Verarbeitungsparameter zusammen mit der ursprünglich geladenen Datei +PREFERENCES_PSPATH;Adobe Photoshop Installations Verzeichnis +PREFERENCES_SELECTICCDIRDLG;Wähle ICC-Profile-Verzeichnis... +PREFERENCES_SELECTLANG;Sprache +PREFERENCES_SELECTMONITORPROFDLG;Wähle ICC-Profil für den Monitor... +PREFERENCES_SELECTTHEME;Wähle Oberflächendesign +PREFERENCES_SHOWBASICEXIF;Zeige grundlegende Exif-Informationen +PREFERENCES_SHOWDATETIME;Zeige Datum und Zeit +PREFERENCES_SHOWONLYRAW;Zeige nur Rohdateien (RAW) +PREFERENCES_SHTHRESHOLD;Schwellwert - zu dunkel +PREFERENCES_STARTUPIMDIR;Bild-Verzeichnis beim Programmstart +PREFERENCES_TAB_BROWSER;Datei-Browser +PREFERENCES_TAB_COLORMGR;Farbmanagement +PREFERENCES_TAB_GENERAL;Allgemein +PREFERENCES_TAB_IMPROC;Bildbearbeitung +PREFERENCES_TAB_OUTPUT;Ausgabe +PREFERENCES_THUMBSIZE;Größe der Vorschau +PROFILEPANEL_FILEDLGFILTERANY;Alle Dateien +PROFILEPANEL_FILEDLGFILTERPP;Bearbeitungsprofile +PROFILEPANEL_LABEL;Bearbeitungsprofile +PROFILEPANEL_LOADDLGLABEL;Lade Bearbeitungsprofil... +PROFILEPANEL_PCUSTOM;Benutzerdefiniert +PROFILEPANEL_PFILE;Aus Datei +PROFILEPANEL_PLASTPHOTO;Letztes Bild +PROFILEPANEL_PLASTSAVED;Zuletzt gespeichert +PROFILEPANEL_PROFILE;Profil +PROFILEPANEL_SAVEDLGLABEL;Speichere Bearbeitungsprofil... +PROFILEPANEL_TOOLTIPCOPY;Kopiere aktuelles Profil in Zwischenablage +PROFILEPANEL_TOOLTIPLOAD;Lade Profil aus Datei +PROFILEPANEL_TOOLTIPPASTE; Einfügen von Profil aus Zwischenablage +PROFILEPANEL_TOOLTIPSAVE;Speichere aktuelles Profil +PROGRESSBAR_DECODING;Dekodierung der Rohdatei (RAW)... +PROGRESSBAR_DEMOSAICING;Entrasterung... +PROGRESSBAR_LOADING;Laden des Bildes... +PROGRESSBAR_LOADJPEG;Laden der JPEG Datei... +PROGRESSBAR_LOADPNG;Laden der PNG Datei... +PROGRESSBAR_LOADTIFF;Laden der TIFF Datei... +PROGRESSBAR_PROCESSING;Berechnen des Bildes... +PROGRESSBAR_READY;Bereit. +PROGRESSBAR_SAVEJPEG;Speichern der JPEG Datei... +PROGRESSBAR_SAVEPNG;Speichern der PNG Datei... +PROGRESSBAR_SAVETIFF;Speichern der TIFF Datei... +PROGRESSDLG_LOADING;Laden der Datei... +PROGRESSDLG_PROCESSING;Berechnen des Bildes... +PROGRESSDLG_SAVING;Speichern der Datei... +QINFO_FOCALLENGTH;Brennweite +QINFO_ISO;ISO +QINFO_LENS;Objektiv +QINFO_NOEXIF;Keine Exif-Daten vorhanden. +SAVEDLG_FILEFORMAT;Dateiformat +SAVEDLG_JPEGQUAL;JPEG-Qualität +SAVEDLG_JPGFILTER;JPEG-Datei +SAVEDLG_PNGCOMPR;PNG-Kompression +SAVEDLG_PNGFILTER;PNG-Datei +SAVEDLG_PUTTOQUEUE;In Warteschlange für Verarbeitung legen +SAVEDLG_PUTTOQUEUEHEAD;An Anfang der Warteschlange für Verarbeitung legen +SAVEDLG_PUTTOQUEUETAIL;Ans Ende der Warteschlange für Verarbeitung legen +SAVEDLG_SAVEIMMEDIATELY;Sofort Speichern +SAVEDLG_SAVESPP;Speichere die Prozessparameter mit dem Bild +SAVEDLG_TIFFFILTER;TIFF-Datei +TOOLBAR_TOOLTIP_CROP;Auswahl des Ausschnitts (Taste C) +TOOLBAR_TOOLTIP_HAND;Hand-Werkzeug (Taste N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Auswahl einer Leitlinie (Taste S) +TOOLBAR_TOOLTIP_WB;Weißabgleich manuel setzen (Taste W) +TP_CACORRECTION_BLUE;Blau +TP_CACORRECTION_LABEL;Farbsaum-Entfernung +TP_CACORRECTION_RED;Rot +TP_CHMIXER_BLUE;Blau +TP_CHMIXER_GREEN;Grün +TP_CHMIXER_LABEL;Kanal-Mixer +TP_CHMIXER_RED;Rot +TP_COARSETRAF_DEGREE;Grad: +TP_COARSETRAF_TOOLTIP_HFLIP;horizontal spiegeln +TP_COARSETRAF_TOOLTIP_ROTLEFT;nach links drehen +TP_COARSETRAF_TOOLTIP_ROTRIGHT;nach rechts drehen +TP_COARSETRAF_TOOLTIP_VFLIP;vertikal spiegeln +TP_COLORBOOST_ACHANNEL;Kanal "a" +TP_COLORBOOST_AMOUNT;Menge +TP_COLORBOOST_AVOIDCOLORCLIP;Verhindere Übersättigung +TP_COLORBOOST_BCHANNEL;Kanal "b" +TP_COLORBOOST_CHAB;a & b +TP_COLORBOOST_CHANNEL;Kanal +TP_COLORBOOST_CHSEPARATE;separat +TP_COLORBOOST_ENABLESATLIMITER;Sättigungsbegrenzung aktivieren +TP_COLORBOOST_LABEL;Farbverstärkung +TP_COLORBOOST_SATLIMIT;Sättigungsgrenze +TP_COLORDENOISE_EDGESENSITIVE;Kanten-Empfindlichkeit +TP_COLORDENOISE_EDGETOLERANCE;Kanten-Toleranz +TP_COLORDENOISE_LABEL;Farb-Rauschfilter +TP_COLORDENOISE_RADIUS;Radius +TP_COLORSHIFT_BLUEYELLOW;Blau-Gelb +TP_COLORSHIFT_GREENMAGENTA;Grün-Magenta +TP_COLORSHIFT_LABEL;Farbverschiebung +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Festes Format: +TP_CROP_GTDIAGONALS;Diagonale +TP_CROP_GTHARMMEANS1;Harmonischer Schnitt 1 +TP_CROP_GTHARMMEANS2;Harmonischer Schnitt 2 +TP_CROP_GTHARMMEANS3;Harmonischer Schnitt 3 +TP_CROP_GTHARMMEANS4;Harmonischer Schnitt 4 +TP_CROP_GTNONE;Keine +TP_CROP_GTRULETHIRDS;Goldener Schnitt +TP_CROP_GUIDETYPE;Hilfslinien: +TP_CROP_H;H +TP_CROP_LABEL;Ausschnitt +TP_CROP_SELECTCROP; Wähle Ausschnitt +TP_CROP_W;W +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Menge +TP_DISTORTION_LABEL;Entzerrung +TP_EXPOSURE_AUTOLEVELS;autom. +TP_EXPOSURE_BLACKLEVEL;schwarz +TP_EXPOSURE_BRIGHTNESS;Helligkeit +TP_EXPOSURE_CLIP;beschneiden +TP_EXPOSURE_COMPRHIGHLIGHTS;Lichter-Kompression +TP_EXPOSURE_COMPRSHADOWS;Schatten-Kompression +TP_EXPOSURE_CONTRAST;Kontrast +TP_EXPOSURE_CURVEEDITOR;Tonwertkurve +TP_EXPOSURE_EXPCOMP;Bel.Korrektur +TP_EXPOSURE_LABEL;Belichtung +TP_HLREC_CIELAB;CIELab Überlagerung +TP_HLREC_COLOR;Farbübertragung +TP_HLREC_LABEL;Lichter wiederherstellen +TP_HLREC_LUMINANCE;Luminanz herstellen +TP_HLREC_METHOD;Methode: +TP_ICM_FILEDLGFILTERANY;Alle Dateien +TP_ICM_FILEDLGFILTERICM;ICC-Profildateien +TP_ICM_GAMMABEFOREINPUT;Profil enthält Gammaanpassung +TP_ICM_INPUTCAMERA;Kamera-Standard +TP_ICM_INPUTCUSTOM;Benutzerdefiniert +TP_ICM_INPUTDLGLABEL;Wähle Eingabe-ICC-Profil... +TP_ICM_INPUTEMBEDDED;Verwende eingebettetes, wenn möglich +TP_ICM_INPUTPROFILE;Eingabeprofil +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Kein ICM: sRGB-Ausgabe +TP_ICM_OUTPUTDLGLABEL;Wähle Ausgabe-ICC-Profil... +TP_ICM_OUTPUTPROFILE;Ausgabeprofil +TP_ICM_SAVEREFERENCE;Speichere Referenzbild für die Profilierung +TP_ICM_WORKINGPROFILE;Arbeitsfarbraum +TP_LUMACURVE_BLACKLEVEL;schwarz +TP_LUMACURVE_BRIGHTNESS;Helligkeit +TP_LUMACURVE_COMPRHIGHLIGHTS;Lichter-Kompression +TP_LUMACURVE_COMPRSHADOWS;Schatten-Kompression +TP_LUMACURVE_CONTRAST;Kontrast +TP_LUMACURVE_CURVEEDITOR;Luminanzkurve +TP_LUMACURVE_LABEL;Luminanzkurve +TP_LUMADENOISE_EDGETOLERANCE;Kanten-Toleranz +TP_LUMADENOISE_LABEL;Luminanz-Rauschfilter +TP_LUMADENOISE_RADIUS;Radius +TP_RESIZE_BICUBIC;Bikubisch +TP_RESIZE_BICUBICSF;Bikubisch (Weicher) +TP_RESIZE_BICUBICSH;Bikubisch (Schärfer) +TP_RESIZE_BILINEAR;Bilinear +TP_RESIZE_FULLSIZE;Volle Bildgröße: +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Größe ändern +TP_RESIZE_METHOD;Methode: +TP_RESIZE_NEAREST;Nächste +TP_RESIZE_SCALE;Maßstab +TP_RESIZE_W;W: +TP_ROTATE_AUTOCROP;Auto Ausschnitt +TP_ROTATE_DEGREE;Grad +TP_ROTATE_FILL;Füllen +TP_ROTATE_LABEL;Drehen +TP_ROTATE_SELECTLINE;Wähle Leitlinie +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Lichter +TP_SHADOWSHLIGHTS_HLTONALW;Farbtonbereich +TP_SHADOWSHLIGHTS_LABEL;Schatten/Lichter +TP_SHADOWSHLIGHTS_LOCALCONTR;Lokaler Kontrast +TP_SHADOWSHLIGHTS_RADIUS;Radius +TP_SHADOWSHLIGHTS_SHADOWS;Schatten +TP_SHADOWSHLIGHTS_SHTONALW;Farbtonbereich +TP_SHARPENING_AMOUNT;Menge +TP_SHARPENING_EDRADIUS;Radius +TP_SHARPENING_EDTOLERANCE;Kanten-Toleranz +TP_SHARPENING_HALOCONTROL;Halo-Kontrolle +TP_SHARPENING_HCAMOUNT;Menge +TP_SHARPENING_LABEL;Schärfen +TP_SHARPENING_METHOD;Methode +TP_SHARPENING_ONLYEDGES;nur Kanten schärfen +TP_SHARPENING_RADIUS;Radius +TP_SHARPENING_RLD;R-L Bildrestaurierung +TP_SHARPENING_RLD_AMOUNT;Menge +TP_SHARPENING_RLD_DAMPING;Dämpfung +TP_SHARPENING_RLD_ITERATIONS;Iterationen +TP_SHARPENING_THRESHOLD;Schwellwert +TP_SHARPENING_USM;Unscharf maskieren +TP_VIGNETTING_AMOUNT;Menge +TP_VIGNETTING_LABEL;Korrektur Randlichtabfall +TP_VIGNETTING_RADIUS;Radius +TP_WBALANCE_AUTO;Automatisch +TP_WBALANCE_CAMERA;Kamera +TP_WBALANCE_CUSTOM;Benutzerdefiniert +TP_WBALANCE_GREEN;Farbton +TP_WBALANCE_LABEL;Weißabgleich +TP_WBALANCE_METHOD;Methode +TP_WBALANCE_SIZE;Größe: +TP_WBALANCE_SPOTWB;manuel setzen +TP_WBALANCE_TEMPERATURE;Farbtemperatur +ZOOMBAR_DETAIL;Detail +ZOOMBAR_HUGE;riesig +ZOOMBAR_LARGE;groß +ZOOMBAR_NORMAL;normal +ZOOMBAR_PREVIEW;Voransicht +ZOOMBAR_SCALE;Vergrößerung +ZOOMBAR_SMALL;klein + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) new file mode 100644 index 000000000..c0dc87538 --- /dev/null +++ b/rtdata/languages/English (UK) @@ -0,0 +1,705 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# British english +# +# 16.01.2009: Richard Regal +ADJUSTER_RESET_TO_DEFAULT;Reset to default +CURVEEDITOR_FILEDLGFILTERANY;Any files +CURVEEDITOR_FILEDLGFILTERCURVE;Curve files +CURVEEDITOR_LINEAR;Linear +CURVEEDITOR_LOADDLGLABEL;Load Curve... +CURVEEDITOR_SAVEDLGLABEL;Save Curve... +CURVEEDITOR_TOOLTIPLINEAR;Reset curve to linear +CURVEEDITOR_TOOLTIPLOAD;Load a curve from file +CURVEEDITOR_TOOLTIPSAVE;Save current curve +EXIFFILTER_APERTURE;Aperture +EXIFFILTER_CAMERA;Camera +EXIFFILTER_DIALOGLABEL;Exif Filter +EXIFFILTER_FOCALLEN;Focal Length +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Lens +EXIFFILTER_SHUTTER;Shutter +EXIFPANEL_ADDEDIT;Add/Edit +EXIFPANEL_ADDEDITHINT;Add new tag or edit tag +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Enter value +EXIFPANEL_ADDTAGDLG_SELECTTAG;Select tag +EXIFPANEL_ADDTAGDLG_TITLE;Add/Edit Tag +EXIFPANEL_KEEP;Keep +EXIFPANEL_KEEPHINT;Keep the selected tags when writing output file +EXIFPANEL_REMOVE;Remove +EXIFPANEL_REMOVEHINT;Remove the selected tags when writing output file +EXIFPANEL_RESET;Reset +EXIFPANEL_RESETALL;Reset All +EXIFPANEL_RESETALLHINT;Reset all tags to their original values +EXIFPANEL_RESETHINT;Reset the selected tags to their original values +EXIFPANEL_SUBDIRECTORY;Subdirectory +FILEBROWSER_APPLYPROFILE;Apply profile +FILEBROWSER_ARRANGEMENTHINT;Change between vertical/horizontal alignment of thumbnails +FILEBROWSER_CLEARPROFILE;Clear profile +FILEBROWSER_COPYPROFILE;Copy profile +FILEBROWSER_DELETEDLGLABEL;File delete confirmation +FILEBROWSER_DELETEDLGMSG;Are you sure you want to delete the selected %1 files? +FILEBROWSER_EMPTYTRASH;Empty Trash +FILEBROWSER_EMPTYTRASHHINT;Permanently delete the files of the trash +FILEBROWSER_EXIFFILTERAPPLY;Apply +FILEBROWSER_EXIFFILTERAPPLYHINT;Switch on/off exif filter of the file browser +FILEBROWSER_EXIFFILTERLABEL;Exif Filter +FILEBROWSER_EXIFFILTERSETTINGS;Setup +FILEBROWSER_EXIFFILTERSETTINGSHINT;Change settings of the exif filter +FILEBROWSER_PARTIALPASTEPROFILE;Partial paste +FILEBROWSER_PASTEPROFILE;Paste profile +FILEBROWSER_POPUPCANCELJOB;Cancel job +FILEBROWSER_POPUPMOVEEND;Move to end of queue +FILEBROWSER_POPUPMOVEHEAD;Move to head of queue +FILEBROWSER_POPUPOPEN;Open +FILEBROWSER_POPUPPROCESS;Put to processing queue +FILEBROWSER_POPUPRANK1;Rank 1 +FILEBROWSER_POPUPRANK2;Rank 2 +FILEBROWSER_POPUPRANK3;Rank 3 +FILEBROWSER_POPUPRANK4;Rank 4 +FILEBROWSER_POPUPRANK5;Rank 5 +FILEBROWSER_POPUPREMOVE;Remove from filesystem +FILEBROWSER_POPUPRENAME;Rename +FILEBROWSER_POPUPSELECTALL;Select all +FILEBROWSER_POPUPTRASH;Move to trash +FILEBROWSER_POPUPUNRANK;Unrank +FILEBROWSER_POPUPUNTRASH;Remove from trash +FILEBROWSER_PROCESSINGSETTINGS;Settings +FILEBROWSER_PROCESSINGSETTINGSHINT;Set the file format and output directory +FILEBROWSER_RENAMEDLGLABEL;Rename file +FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +FILEBROWSER_SHOWDIRHINT;Show all images of the directory +FILEBROWSER_SHOWQUEUEHINT;Show content of the processing queue +FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1 star +FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2 star +FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3 star +FILEBROWSER_SHOWRANK4HINT;Show images ranked as 4 star +FILEBROWSER_SHOWRANK5HINT;Show images ranked as 5 star +FILEBROWSER_SHOWTRASHHINT;Show content of the trash +FILEBROWSER_SHOWUNRANKHINT;Show unranked images +FILEBROWSER_STARTPROCESSING;Start processing +FILEBROWSER_STARTPROCESSINGHINT;Start processing/saving of images in the queue +FILEBROWSER_STOPPROCESSING;Stop processing +FILEBROWSER_STOPPROCESSINGHINT;Stop processing of images +FILEBROWSER_THUMBSIZE;Thumb. size +FILEBROWSER_ZOOMINHINT;Increase thumbnail size +FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size +GENERAL_ABOUT;About +GENERAL_CANCEL;Cancel +GENERAL_DISABLE;Disable +GENERAL_DISABLED;Disabled +GENERAL_ENABLE;Enable +GENERAL_ENABLED;Enabled +GENERAL_LANDSCAPE;Landscape +GENERAL_LOAD;Load +GENERAL_NA;n/a +GENERAL_NO;No +GENERAL_OK;OK +GENERAL_PORTRAIT;Portrait +GENERAL_SAVE;Save +GENERAL_YES;Yes +HISTOGRAM_LABEL;Histogram +HISTOGRAM_TOOLTIP_B;Show/Hide BLUE histogram +HISTOGRAM_TOOLTIP_G;Show/Hide GREEN histogram +HISTOGRAM_TOOLTIP_L;Show/Hide CIELAB Luminance histogram +HISTOGRAM_TOOLTIP_R;Show/Hide RED histogram +HISTORY_CHANGED;Changed +HISTORY_CUSTOMCURVE;Custom Curve +HISTORY_DELSNAPSHOT;Del +HISTORY_FROMCLIPBOARD;From clipboard +HISTORY_LABEL;History +HISTORY_MSG_10;Shadow Compression +HISTORY_MSG_11;Tone Curve +HISTORY_MSG_12;Auto Exposure +HISTORY_MSG_13;Exposure Clipping +HISTORY_MSG_14;Luminance Brightness +HISTORY_MSG_15;Luminance Contrast +HISTORY_MSG_16;Luminance Black +HISTORY_MSG_17;Luminance Highlight Compr. +HISTORY_MSG_18;Luminance Shadow Compr. +HISTORY_MSG_19;Luminance Curve +HISTORY_MSG_1;Photo Loaded +HISTORY_MSG_20;Sharpening +HISTORY_MSG_21;Sharpening Radius +HISTORY_MSG_22;Sharpening Amount +HISTORY_MSG_23;Sharpening Threshold +HISTORY_MSG_24;Sharpen Only Edges +HISTORY_MSG_25;Sharpening Edge Detection Radius +HISTORY_MSG_26;Sharpening Edge Tolerance +HISTORY_MSG_27;Sharpening Halo Control +HISTORY_MSG_28;Halo Control Amount +HISTORY_MSG_29;Sharpening Method +HISTORY_MSG_2;Profile Loaded +HISTORY_MSG_30;Deconvolution Radius +HISTORY_MSG_31;Deconvolution Amount +HISTORY_MSG_32;Deconvolution Damping +HISTORY_MSG_33;Deconvolution Iterations +HISTORY_MSG_34;Avoid Colour Clipping +HISTORY_MSG_35;Saturation Limiter +HISTORY_MSG_36;Saturation Limit +HISTORY_MSG_37;Colour Boost +HISTORY_MSG_38;White Balance Method +HISTORY_MSG_39;Colour Temperature +HISTORY_MSG_3;Profile Changed +HISTORY_MSG_40;White Balance Tint +HISTORY_MSG_41;Colour Shift "A" +HISTORY_MSG_42;Colour Shift "B" +HISTORY_MSG_43;Luminance Denoising +HISTORY_MSG_44;Lum. Denoising Radius +HISTORY_MSG_45;Lum. Denoising Edge Tolerance +HISTORY_MSG_46;Colour Denoising +HISTORY_MSG_47;Colour Denoising Radius +HISTORY_MSG_48;Colour Denoising Edge Tolerance +HISTORY_MSG_49;Edge Sensitive Colour Denoising +HISTORY_MSG_4;History Browsing +HISTORY_MSG_50;Shadow/Highlight tool +HISTORY_MSG_51;Highlight boost +HISTORY_MSG_52;Shadow Boost +HISTORY_MSG_53;Highlight Tonal Width +HISTORY_MSG_54;Shadow Tonal Width +HISTORY_MSG_55;Local Contrast +HISTORY_MSG_56;Shadow/Highlight Radius +HISTORY_MSG_57;Coarse Rotation +HISTORY_MSG_58;Horizontal Flipping +HISTORY_MSG_59;Vertical Flipping +HISTORY_MSG_5;Brightness +HISTORY_MSG_60;Rotation +HISTORY_MSG_61;Rotation +HISTORY_MSG_62;Lens Distortion Correction +HISTORY_MSG_63;Snapshot Selected +HISTORY_MSG_64;Crop Photo +HISTORY_MSG_65;C/A Correction +HISTORY_MSG_66;Highlight Recovery +HISTORY_MSG_67;Highlight Recovery Amount +HISTORY_MSG_68;Highlight Recovery Method +HISTORY_MSG_69;Working Colour Space +HISTORY_MSG_6;Contrast +HISTORY_MSG_70;Output Colour Space +HISTORY_MSG_71;Input Colour Space +HISTORY_MSG_72;Vignetting Correction +HISTORY_MSG_73;Channel Mixer +HISTORY_MSG_74;Resize Scale +HISTORY_MSG_75;Resize Method +HISTORY_MSG_76;Exif Metadata +HISTORY_MSG_77;IPTC Metadata +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;Black +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;Exposure Compensation +HISTORY_MSG_9;Highlight Compression +HISTORY_NEWSNAPSHOT;Add +HISTORY_NEWSNAPSHOTAS;As... +HISTORY_NEWSSDIALOGLABEL;Label of the snapshot: +HISTORY_NEWSSDIALOGTITLE;Add new snapshot +HISTORY_SETTO;Set to +HISTORY_SNAPSHOT;Snapshot +HISTORY_SNAPSHOTS;Snapshots +ICMPANEL_FILEDLGFILTERANY;Any files +ICMPANEL_FILEDLGFILTERICM;ICC Profile Files +ICMPANEL_GAMMABEFOREINPUT;Profile applies Gamma +ICMPANEL_INPUTCAMERA;Camera default +ICMPANEL_INPUTCUSTOM;Custom +ICMPANEL_INPUTDLGLABEL;Select Input ICC Profile... +ICMPANEL_INPUTEMBEDDED;Use Embedded, if possible +ICMPANEL_INPUTPROFILE;Input Profile +ICMPANEL_NOICM;No ICM: sRGB output +ICMPANEL_OUTPUTDLGLABEL;Select Output ICC Profile... +ICMPANEL_OUTPUTPROFILE;Output Profile +ICMPANEL_SAVEREFERENCE;Save reference image for profiling +ICMPANEL_WORKINGPROFILE;Working Profile +IMAGEAREA_DETAILVIEW;Detail view +IPTCPANEL_AUTHOR;Author +IPTCPANEL_AUTHORHINT;Name of the creator of the object, e.g. writer, photographer or graphic artist (By-line). +IPTCPANEL_AUTHORSPOSITION;Author's position +IPTCPANEL_AUTHORSPOSITIONHINT;Title of the creator or creators of the object (By-line Title). +IPTCPANEL_CAPTION;Caption +IPTCPANEL_CAPTIONHINT;A textual description of the data (Caption - Abstract). +IPTCPANEL_CAPTIONWRITER;Caption Writer +IPTCPANEL_CAPTIONWRITERHINT;The name of the person involved in the writing, editing or correcting the image or caption/abstract (Writer - Editor). +IPTCPANEL_CATEGORY;Category +IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider (Category). +IPTCPANEL_CITY;City +IPTCPANEL_CITYHINT;City of image origin (City). +IPTCPANEL_COPYHINT;Copy IPTC settings to clipboard +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COPYRIGHTHINT;Any necessary copyright notice (Copyright Notice). +IPTCPANEL_COUNTRY;Country +IPTCPANEL_COUNTRYHINT;The name of the country/primary location where the image was created (Country - Primary Location Name). +IPTCPANEL_CREDIT;Credit +IPTCPANEL_CREDITHINT;Identifies the provider of the image, not necessarily the owner/creator (Credit). +IPTCPANEL_DATECREATED;Date Created +IPTCPANEL_DATECREATEDHINT;The date the intellectual content of the image was created; Format: JJJJMMTT (Date Created). +IPTCPANEL_EMBEDDED;Embedded +IPTCPANEL_EMBEDDEDHINT;Reset to IPTC data embedded in the image file +IPTCPANEL_HEADLINE;Headline +IPTCPANEL_HEADLINEHINT;A publishable entry providing a synopsis of the contents of the image (Headline). +IPTCPANEL_INSTRUCTIONS;Instructions +IPTCPANEL_INSTRUCTIONSHINT;Other editorial instructions concerning the use of the image (Special Instructions). +IPTCPANEL_KEYWORDS;Keywords +IPTCPANEL_KEYWORDSHINT;Used to indicate specific information retrieval words (Keywords). +IPTCPANEL_PASTEHINT;Paste IPTC settings from clipboard +IPTCPANEL_PROVINCE;Province +IPTCPANEL_PROVINCEHINT;The Province/State where the image originates (Province-State). +IPTCPANEL_RESET;Reset +IPTCPANEL_RESETHINT;Reset to profile default +IPTCPANEL_SOURCE;Source +IPTCPANEL_SOURCEHINT;The original owner of the intellectual content of the image (Source). +IPTCPANEL_SUPPCATEGORIES;Suppl. Categories +IPTCPANEL_SUPPCATEGORIESHINT;Further refines the subject of the image (Supplemental Categories). +IPTCPANEL_TITLE;Title +IPTCPANEL_TITLEHINT;A shorthand reference for the image (Object Name). +IPTCPANEL_TRANSREFERENCE;Trans. Reference +IPTCPANEL_TRANSREFERENCEHINT;A code representing the location of original transmission (Original Transmission Reference). +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Preferences +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVE;Save Image +MAIN_BUTTON_SAVEAS;As... +MAIN_BUTTON_SENDTOEDITOR;Send to editor +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES;Places +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;File already exists. +MAIN_MSG_CANNOTLOAD;Cannot load image +MAIN_MSG_CANNOTSAVE;File saving error +MAIN_MSG_CANNOTSTARTEDITOR;Can not start editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Please set the correct path in the "Preferences" dialog. +MAIN_MSG_EXITJOBSINQUEUEINFO;Unprocessed images in the queue will be lost on exit. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Are you sure you want to exit? There are unprocessed images waiting in the queue. +MAIN_MSG_JOBSINQUEUE;job(s) in the queue +MAIN_MSG_QOVERWRITE;Do you want to overwrite it? +MAIN_TAB_BASIC;Basic +MAIN_TAB_COLOR;Colour +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Exposure +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Transform +MAIN_TOOLTIP_HIDEFP;Show/hide the bottom panel (directory and file browser, shortcut key: F) +MAIN_TOOLTIP_HIDEHP;Show/hide the left panel (including the history, shortcut key: H) +MAIN_TOOLTIP_INDCLIPPEDH;Clipped highlight indication +MAIN_TOOLTIP_INDCLIPPEDS;Clipped shadow indication +MAIN_TOOLTIP_PREFERENCES;Set preferences +MAIN_TOOLTIP_QINFO;Quick info on the image +MAIN_TOOLTIP_SAVE;Save image to the default folder +MAIN_TOOLTIP_SAVEAS;Save image to a selected folder +PARTIALPASTE_BASICGROUP;Basic settings +PARTIALPASTE_CACORRECTION;C/A correction +PARTIALPASTE_COARSETRANS;90 deg rotation / flipping +PARTIALPASTE_COLORBOOST;Colour boost +PARTIALPASTE_COLORDENOISE;Colour denoise +PARTIALPASTE_COLORGROUP;Colour related settings +PARTIALPASTE_COLORMIXER;Colour mixer +PARTIALPASTE_COLORSHIFT;Colour shift +PARTIALPASTE_COMPOSITIONGROUP;Composition settings +PARTIALPASTE_CROP;Crop +PARTIALPASTE_DIALOGLABEL;Partial paste processing profile +PARTIALPASTE_DISTORTION;Distortion correction +PARTIALPASTE_EXIFCHANGES;Changes to exif data +PARTIALPASTE_EXPOSURE;Exposure +PARTIALPASTE_HLRECOVERY;Highlight recovery +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Lens related settings +PARTIALPASTE_LUMACURVE;Luminance curve +PARTIALPASTE_LUMADENOISE;Luminance noise reduction +PARTIALPASTE_LUMINANCEGROUP;Luminance related settings +PARTIALPASTE_METAICMGROUP;Metadata/ICM settings +PARTIALPASTE_RESIZE;Resize +PARTIALPASTE_ROTATION;Rotation +PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights +PARTIALPASTE_SHARPENING;Sharpening +PARTIALPASTE_VIGNETTING;Vignetting correction +PARTIALPASTE_WHITEBALANCE;White balance +PREFERENCES_APPLNEXTSTARTUP;applied at next startup +PREFERENCES_BLINKCLIPPED;Blink clipped areas +PREFERENCES_CACHECLEARALL;Clear All +PREFERENCES_CACHECLEARPROFILES;Clear Profiles +PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +PREFERENCES_CACHEFORMAT1;Proprietary (faster and better quality) +PREFERENCES_CACHEFORMAT2;JPEG (smaller disk footprint) +PREFERENCES_CACHEMAXENTRIES;Maximal Number of Cache Entries +PREFERENCES_CACHEOPTS;Cache Options +PREFERENCES_CACHESTRAT1;Prefer Speed to Low Memory Consumption +PREFERENCES_CACHESTRAT2;Prefer Low Memory Consumption to Speed +PREFERENCES_CACHESTRAT;Cache Strategy +PREFERENCES_CACHETHUMBFORM;Cache Thumbnail Format +PREFERENCES_CACHETHUMBHEIGHT;Maximal Thumbnail Height +PREFERENCES_CLEARDLG_LINE1;Clearing cache +PREFERENCES_CLEARDLG_LINE2;This may take a few seconds. +PREFERENCES_CLEARDLG_TITLE;Please wait +PREFERENCES_CLIPPINGIND;Clipping indication +PREFERENCES_CMETRICINTENT;Colorimetric Intent +PREFERENCES_DATEFORMAT;Date Format +PREFERENCES_DATEFORMATHINT;You can use the following formatting strings:\n%y : year\n%m : month\n%d : day\n\nFor example, the hungarian date format is:\n%y/%m/%d +PREFERENCES_DCBENHANCE;Apply DCB enhancment step +PREFERENCES_DCBITERATIONS;Number of DCB iterations +PREFERENCES_DEFAULTLANG;Default language +PREFERENCES_DEFAULTTHEME;Default theme +PREFERENCES_DEMOSAICINGALGO;Demosaicing Algorithm +PREFERENCES_DIRHOME;Home directory +PREFERENCES_DIRLAST;Last visited directory +PREFERENCES_DIROTHER;Other +PREFERENCES_DIRSELECTDLG;Select Image Directory at Startup... +PREFERENCES_DIRSOFTWARE;Installation directory +PREFERENCES_DMETHOD;Method +PREFERENCES_EDITORCMDLINE;Other command line +PREFERENCES_EXTERNALEDITOR;External editor +PREFERENCES_FALSECOLOR;False colour suppression steps +PREFERENCES_FBROWSEROPTS;File Browser Options +PREFERENCES_FILEFORMAT;File format +PREFERENCES_FORIMAGE;For image files +PREFERENCES_FORRAW;For RAW files +PREFERENCES_GIMPPATH;GIMP installation directory +PREFERENCES_GTKTHEME;GTK default +PREFERENCES_HINT;Hint +PREFERENCES_HLTHRESHOLD;Threshold for clipped highlights +PREFERENCES_ICCDIR;Directory of ICC profiles +PREFERENCES_IMPROCPARAMS;Default image processing parameters +PREFERENCES_INTENT_ABSOLUTE;Absolute Colorimetric +PREFERENCES_INTENT_PERCEPTUAL;Perceptual +PREFERENCES_INTENT_RELATIVE;Relative Colorimetric +PREFERENCES_INTENT_SATURATION;Saturation +PREFERENCES_LIVETHUMBNAILS;Live Thumbnails (slower) +PREFERENCES_MONITORICC;Monitor Profile +PREFERENCES_OUTDIR;Output Directory +PREFERENCES_OUTDIRFOLDER;Save to folder +PREFERENCES_OUTDIRFOLDERHINT;Put the saved images to the selected folder +PREFERENCES_OUTDIRHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, %p3=/home/tom, ...\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Use Template +PREFERENCES_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, %p3=/home/tom, ...\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_PARSEDEXT;Parsed Extensions +PREFERENCES_PARSEDEXTADD;Add Extension +PREFERENCES_PARSEDEXTADDHINT;Type an extension and press this button to append list +PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list +PREFERENCES_PROFILEHANDLING;Processing Profile Handling +PREFERENCES_PROFILELOADPR;Profile Loading Priority +PREFERENCES_PROFILEPRCACHE;Profile in Cache +PREFERENCES_PROFILEPRFILE;Profile Next to the Input File +PREFERENCES_PROFILESAVECACHE;Save Processing Parameters to the Cache +PREFERENCES_PROFILESAVEINPUT;Save Processing Parameters Next to the Input File +PREFERENCES_PSPATH;Adobe Photoshop installation directory +PREFERENCES_SELECTICCDIRDLG;Select ICC Profile Directory... +PREFERENCES_SELECTLANG;Select language +PREFERENCES_SELECTMONITORPROFDLG;Select ICC Profile of the Display... +PREFERENCES_SELECTTHEME;Select theme +PREFERENCES_SHOWBASICEXIF;Show basic Exif info +PREFERENCES_SHOWDATETIME;Show date and time +PREFERENCES_SHOWONLYRAW;Show only RAW files +PREFERENCES_SHTHRESHOLD;Threshold for clipped shadows +PREFERENCES_STARTUPIMDIR;Image directory at startup +PREFERENCES_TAB_BROWSER;File Browser +PREFERENCES_TAB_COLORMGR;Colour Management +PREFERENCES_TAB_GENERAL;General +PREFERENCES_TAB_IMPROC;Image Processing +PREFERENCES_TAB_OUTPUT;Output Options +PREFERENCES_THUMBSIZE;Thumbnail Size +PROFILEPANEL_FILEDLGFILTERANY;Any files +PROFILEPANEL_FILEDLGFILTERPP;Postprocessing profiles +PROFILEPANEL_LABEL;Postprocessing Profiles +PROFILEPANEL_LOADDLGLABEL;Load Postprocessing Parameters... +PROFILEPANEL_PCUSTOM;Custom +PROFILEPANEL_PFILE;From file +PROFILEPANEL_PLASTPHOTO;Last Photo +PROFILEPANEL_PLASTSAVED;Last Saved +PROFILEPANEL_PROFILE;Profile +PROFILEPANEL_SAVEDLGLABEL;Save Postprocessing Parameters... +PROFILEPANEL_TOOLTIPCOPY;Copy current profile to clipboard +PROFILEPANEL_TOOLTIPLOAD;Load a profile from file +PROFILEPANEL_TOOLTIPPASTE; Paste profile from clipboard +PROFILEPANEL_TOOLTIPSAVE;Save current profile +PROGRESSBAR_DECODING;Decoding raw file... +PROGRESSBAR_DEMOSAICING;Demosaicing... +PROGRESSBAR_LOADING;Loading Image... +PROGRESSBAR_LOADJPEG;Loading JPEG file... +PROGRESSBAR_LOADPNG;Loading PNG file... +PROGRESSBAR_LOADTIFF;Loading TIFF file... +PROGRESSBAR_PROCESSING;Processing Image... +PROGRESSBAR_READY;Ready. +PROGRESSBAR_SAVEJPEG;Saving JPEG file... +PROGRESSBAR_SAVEPNG;Saving PNG file... +PROGRESSBAR_SAVETIFF;Saving TIFF file... +PROGRESSDLG_LOADING;Loading file... +PROGRESSDLG_PROCESSING;Processing image... +PROGRESSDLG_SAVING;Saving file... +QINFO_FOCALLENGTH;Focal length +QINFO_ISO;ISO +QINFO_LENS;Lens +QINFO_NOEXIF;Exif data not available. +SAVEDLG_FILEFORMAT;File format +SAVEDLG_JPEGQUAL;JPEG Quality +SAVEDLG_JPGFILTER;JPEG files +SAVEDLG_PNGCOMPR;PNG Compression +SAVEDLG_PNGFILTER;PNG files +SAVEDLG_PUTTOQUEUE;Put into processing queue +SAVEDLG_PUTTOQUEUEHEAD;Put to the head of the processing queue +SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue +SAVEDLG_SAVEIMMEDIATELY;Save immediately +SAVEDLG_SAVESPP;Save processing parameters with image +SAVEDLG_TIFFFILTER;TIFF files +TOOLBAR_TOOLTIP_CROP;Crop selection (Shortcut key: C) +TOOLBAR_TOOLTIP_HAND;Hand tool (Shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Straight line selection (Shortcut key: S) +TOOLBAR_TOOLTIP_WB;Spot white balance (Shortcut key: W) +TP_CACORRECTION_BLUE;Blue +TP_CACORRECTION_LABEL;C/A Correction +TP_CACORRECTION_RED;Red +TP_CHMIXER_BLUE;Blue +TP_CHMIXER_GREEN;Green +TP_CHMIXER_LABEL;Channel Mixer +TP_CHMIXER_RED;Red +TP_COARSETRAF_DEGREE;degree: +TP_COARSETRAF_TOOLTIP_HFLIP;Flip horizontally +TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotate left +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotate right +TP_COARSETRAF_TOOLTIP_VFLIP;Flip vertically +TP_COLORBOOST_ACHANNEL;Channel "a" +TP_COLORBOOST_AMOUNT;Amount +TP_COLORBOOST_AVOIDCOLORCLIP;Avoid colour clipping +TP_COLORBOOST_BCHANNEL;Channel "b" +TP_COLORBOOST_CHAB;a & b +TP_COLORBOOST_CHANNEL;Channel +TP_COLORBOOST_CHSEPARATE;separate +TP_COLORBOOST_ENABLESATLIMITER;Enable saturation limiter +TP_COLORBOOST_LABEL;Colour Boost +TP_COLORBOOST_SATLIMIT;Saturation limit +TP_COLORDENOISE_EDGESENSITIVE;Edge Sensitive +TP_COLORDENOISE_EDGETOLERANCE;Edge Tolerance +TP_COLORDENOISE_LABEL;Colour Noise Reduction +TP_COLORDENOISE_RADIUS;Radius +TP_COLORSHIFT_BLUEYELLOW;Blue-Yellow +TP_COLORSHIFT_GREENMAGENTA;Green-Magenta +TP_COLORSHIFT_LABEL;Colour Shift +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Fix Ratio: +TP_CROP_GTDIAGONALS;Rule of diagonals +TP_CROP_GTHARMMEANS1;Harmonic means 1 +TP_CROP_GTHARMMEANS2;Harmonic means 2 +TP_CROP_GTHARMMEANS3;Harmonic means 3 +TP_CROP_GTHARMMEANS4;Harmonic means 4 +TP_CROP_GTNONE;None +TP_CROP_GTRULETHIRDS;Rule of thirds +TP_CROP_GUIDETYPE;Guide Type: +TP_CROP_H;H +TP_CROP_LABEL;Crop +TP_CROP_SELECTCROP; Select Crop +TP_CROP_W;W +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Amount +TP_DISTORTION_LABEL;Distortion +TP_EXPOSURE_AUTOLEVELS;Auto Levels +TP_EXPOSURE_BLACKLEVEL;Black +TP_EXPOSURE_BRIGHTNESS;Brightness +TP_EXPOSURE_CLIP;Clip +TP_EXPOSURE_COMPRHIGHLIGHTS;Highlight compression +TP_EXPOSURE_COMPRSHADOWS;Shadow compression +TP_EXPOSURE_CONTRAST;Contrast +TP_EXPOSURE_CURVEEDITOR;Tone Curve +TP_EXPOSURE_EXPCOMP;Exp. Comp. +TP_EXPOSURE_LABEL;Exposure +TP_HLREC_CIELAB;CIELab Blending +TP_HLREC_COLOR;Colour Propagation +TP_HLREC_LABEL;Highlight Recovery +TP_HLREC_LUMINANCE;Luminance Recovery +TP_HLREC_METHOD;Method: +TP_ICM_FILEDLGFILTERANY;Any files +TP_ICM_FILEDLGFILTERICM;ICC Profile Files +TP_ICM_GAMMABEFOREINPUT;Profile applies Gamma +TP_ICM_INPUTCAMERA;Camera default +TP_ICM_INPUTCUSTOM;Custom +TP_ICM_INPUTDLGLABEL;Select Input ICC Profile... +TP_ICM_INPUTEMBEDDED;Use Embedded, if possible +TP_ICM_INPUTPROFILE;Input Profile +TP_ICM_LABEL;ICM +TP_ICM_NOICM;No ICM: sRGB output +TP_ICM_OUTPUTDLGLABEL;Select Output ICC Profile... +TP_ICM_OUTPUTPROFILE;Output Profile +TP_ICM_SAVEREFERENCE;Save reference image for profiling +TP_ICM_WORKINGPROFILE;Working Profile +TP_LUMACURVE_BLACKLEVEL;Black +TP_LUMACURVE_BRIGHTNESS;Brightness +TP_LUMACURVE_COMPRHIGHLIGHTS;Highlight compression +TP_LUMACURVE_COMPRSHADOWS;Shadow compression +TP_LUMACURVE_CONTRAST;Contrast +TP_LUMACURVE_CURVEEDITOR;Luminance Curve +TP_LUMACURVE_LABEL;Luminance Curve +TP_LUMADENOISE_EDGETOLERANCE;Edge Tolerance +TP_LUMADENOISE_LABEL;Luminance Noise Reduction +TP_LUMADENOISE_RADIUS;Radius +TP_RESIZE_BICUBIC;Bicubic +TP_RESIZE_BICUBICSF;Bicubic (Softer) +TP_RESIZE_BICUBICSH;Bicubic (Sharper) +TP_RESIZE_BILINEAR;Bilinear +TP_RESIZE_FULLSIZE;Full Image Size: +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Resize +TP_RESIZE_METHOD;Method: +TP_RESIZE_NEAREST;Nearest +TP_RESIZE_SCALE;Scale +TP_RESIZE_W;W: +TP_ROTATE_AUTOCROP;Auto Crop +TP_ROTATE_DEGREE;Degree +TP_ROTATE_FILL;Fill +TP_ROTATE_LABEL;Rotate +TP_ROTATE_SELECTLINE; Select Straight Line +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Highlights +TP_SHADOWSHLIGHTS_HLTONALW;Tonal Width +TP_SHADOWSHLIGHTS_LABEL;Shadows/Highlights +TP_SHADOWSHLIGHTS_LOCALCONTR;Local Contrast +TP_SHADOWSHLIGHTS_RADIUS;Radius +TP_SHADOWSHLIGHTS_SHADOWS;Shadows +TP_SHADOWSHLIGHTS_SHTONALW;Tonal Width +TP_SHARPENING_AMOUNT;Amount +TP_SHARPENING_EDRADIUS;Radius +TP_SHARPENING_EDTOLERANCE;Edge tolerance +TP_SHARPENING_HALOCONTROL;Halo control +TP_SHARPENING_HCAMOUNT;Amount +TP_SHARPENING_LABEL;Sharpening +TP_SHARPENING_METHOD;Method +TP_SHARPENING_ONLYEDGES;Sharpen only edges +TP_SHARPENING_RADIUS;Radius +TP_SHARPENING_RLD;RL Deconvolution +TP_SHARPENING_RLD_AMOUNT;Amount +TP_SHARPENING_RLD_DAMPING;Damping +TP_SHARPENING_RLD_ITERATIONS;Iterations +TP_SHARPENING_THRESHOLD;Threshold +TP_SHARPENING_USM;Unsharp Mask +TP_VIGNETTING_AMOUNT;Amount +TP_VIGNETTING_LABEL;Vignetting Correction +TP_VIGNETTING_RADIUS;Radius +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Camera +TP_WBALANCE_CUSTOM;Custom +TP_WBALANCE_GREEN;Tint +TP_WBALANCE_LABEL;White Balance +TP_WBALANCE_METHOD;Method +TP_WBALANCE_SIZE;Size: +TP_WBALANCE_SPOTWB;Spot WB +TP_WBALANCE_TEMPERATURE;Temperature +ZOOMBAR_DETAIL;Detail +ZOOMBAR_HUGE;Huge +ZOOMBAR_LARGE;Large +ZOOMBAR_NORMAL;Normal +ZOOMBAR_PREVIEW;Preview +ZOOMBAR_SCALE;Scale +ZOOMBAR_SMALL;Small + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US) new file mode 100644 index 000000000..0e9e3eefe --- /dev/null +++ b/rtdata/languages/English (US) @@ -0,0 +1,704 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# +# +# +ADJUSTER_RESET_TO_DEFAULT;Reset to default +CURVEEDITOR_FILEDLGFILTERANY;Any files +CURVEEDITOR_FILEDLGFILTERCURVE;Curve files +CURVEEDITOR_LINEAR;Linear +CURVEEDITOR_LOADDLGLABEL;Load Curve... +CURVEEDITOR_SAVEDLGLABEL;Save Curve... +CURVEEDITOR_TOOLTIPLINEAR;Reset curve to linear +CURVEEDITOR_TOOLTIPLOAD;Load a curve from file +CURVEEDITOR_TOOLTIPSAVE;Save current curve +EXIFFILTER_APERTURE;Aperture +EXIFFILTER_CAMERA;Camera +EXIFFILTER_DIALOGLABEL;Exif Filter +EXIFFILTER_FOCALLEN;Focal Length +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Lens +EXIFFILTER_SHUTTER;Shutter +EXIFPANEL_ADDEDIT;Add/Edit +EXIFPANEL_ADDEDITHINT;Add new tag or edit tag +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Enter value +EXIFPANEL_ADDTAGDLG_SELECTTAG;Select tag +EXIFPANEL_ADDTAGDLG_TITLE;Add/Edit Tag +EXIFPANEL_KEEP;Keep +EXIFPANEL_KEEPHINT;Keep the selected tags when writing output file +EXIFPANEL_REMOVE;Remove +EXIFPANEL_REMOVEHINT;Remove the selected tags when writing output file +EXIFPANEL_RESET;Reset +EXIFPANEL_RESETALL;Reset All +EXIFPANEL_RESETALLHINT;Reset all tags to their original values +EXIFPANEL_RESETHINT;Reset the selected tags to their original values +EXIFPANEL_SUBDIRECTORY;Subdirectory +FILEBROWSER_APPLYPROFILE;Apply profile +FILEBROWSER_ARRANGEMENTHINT;Change between vertical/horizontal alignment of thumbnails +FILEBROWSER_CLEARPROFILE;Clear profile +FILEBROWSER_COPYPROFILE;Copy profile +FILEBROWSER_DELETEDLGLABEL;File delete confirmation +FILEBROWSER_DELETEDLGMSG;Are you sure you want to delete the selected %1 files? +FILEBROWSER_EMPTYTRASH;Empty Trash +FILEBROWSER_EMPTYTRASHHINT;Permanently delete the files of the trash +FILEBROWSER_EXIFFILTERAPPLY;Apply +FILEBROWSER_EXIFFILTERAPPLYHINT;Switch on/off exif filter of the file browser +FILEBROWSER_EXIFFILTERLABEL;Exif Filter +FILEBROWSER_EXIFFILTERSETTINGS;Setup +FILEBROWSER_EXIFFILTERSETTINGSHINT;Change settings of the exif filter +FILEBROWSER_PARTIALPASTEPROFILE;Partial paste +FILEBROWSER_PASTEPROFILE;Paste profile +FILEBROWSER_POPUPCANCELJOB;Cancel job +FILEBROWSER_POPUPMOVEEND;Move to end of queue +FILEBROWSER_POPUPMOVEHEAD;Move to head of queue +FILEBROWSER_POPUPOPEN;Open +FILEBROWSER_POPUPPROCESS;Put to processing queue +FILEBROWSER_POPUPRANK1;Rank 1 +FILEBROWSER_POPUPRANK2;Rank 2 +FILEBROWSER_POPUPRANK3;Rank 3 +FILEBROWSER_POPUPRANK4;Rank 4 +FILEBROWSER_POPUPRANK5;Rank 5 +FILEBROWSER_POPUPREMOVE;Remove from filesystem +FILEBROWSER_POPUPRENAME;Rename +FILEBROWSER_POPUPSELECTALL;Select all +FILEBROWSER_POPUPTRASH;Move to trash +FILEBROWSER_POPUPUNRANK;Unrank +FILEBROWSER_POPUPUNTRASH;Remove from trash +FILEBROWSER_PROCESSINGSETTINGS;Settings +FILEBROWSER_PROCESSINGSETTINGSHINT;Set the file format and output directory +FILEBROWSER_RENAMEDLGLABEL;Rename file +FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +FILEBROWSER_SHOWDIRHINT;Show all images of the directory +FILEBROWSER_SHOWQUEUEHINT;Show content of the processing queue +FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1 star +FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2 star +FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3 star +FILEBROWSER_SHOWRANK4HINT;Show images ranked as 4 star +FILEBROWSER_SHOWRANK5HINT;Show images ranked as 5 star +FILEBROWSER_SHOWTRASHHINT;Show content of the trash +FILEBROWSER_SHOWUNRANKHINT;Show unranked images +FILEBROWSER_STARTPROCESSING;Start processing +FILEBROWSER_STARTPROCESSINGHINT;Start processing/saving of images in the queue +FILEBROWSER_STOPPROCESSING;Stop processing +FILEBROWSER_STOPPROCESSINGHINT;Stop processing of images +FILEBROWSER_THUMBSIZE;Thumb. size +FILEBROWSER_ZOOMINHINT;Increase thumbnail size +FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size +GENERAL_ABOUT;About +GENERAL_CANCEL;Cancel +GENERAL_DISABLE;Disable +GENERAL_DISABLED;Disabled +GENERAL_ENABLE;Enable +GENERAL_ENABLED;Enabled +GENERAL_LANDSCAPE;Landscape +GENERAL_LOAD;Load +GENERAL_NA;n/a +GENERAL_NO;No +GENERAL_OK;OK +GENERAL_PORTRAIT;Portrait +GENERAL_SAVE;Save +GENERAL_YES;Yes +HISTOGRAM_LABEL;Histogram +HISTOGRAM_TOOLTIP_B;Show/Hide BLUE histogram +HISTOGRAM_TOOLTIP_G;Show/Hide GREEN histogram +HISTOGRAM_TOOLTIP_L;Show/Hide CIELAB Luminance histogram +HISTOGRAM_TOOLTIP_R;Show/Hide RED histogram +HISTORY_CHANGED;Changed +HISTORY_CUSTOMCURVE;Custom Curve +HISTORY_DELSNAPSHOT;Del +HISTORY_FROMCLIPBOARD;From clipboard +HISTORY_LABEL;History +HISTORY_MSG_10;Shadow Compression +HISTORY_MSG_11;Tone Curve +HISTORY_MSG_12;Auto Exposure +HISTORY_MSG_13;Exposure Clipping +HISTORY_MSG_14;Luminance Brightness +HISTORY_MSG_15;Luminance Contrast +HISTORY_MSG_16;Luminance Black +HISTORY_MSG_17;Luminance Highlight Compr. +HISTORY_MSG_18;Luminance Shadow Compr. +HISTORY_MSG_19;Luminance Curve +HISTORY_MSG_1;Photo Loaded +HISTORY_MSG_20;Sharpening +HISTORY_MSG_21;Sharpening Radius +HISTORY_MSG_22;Sharpening Amount +HISTORY_MSG_23;Sharpening Threshold +HISTORY_MSG_24;Sharpen Only Edges +HISTORY_MSG_25;Sharpening Edge Detection Radius +HISTORY_MSG_26;Sharpening Edge Tolerance +HISTORY_MSG_27;Sharpening Halo Control +HISTORY_MSG_28;Halo Control Amount +HISTORY_MSG_29;Sharpening Method +HISTORY_MSG_2;Profile Loaded +HISTORY_MSG_30;Deconvolution Radius +HISTORY_MSG_31;Deconvolution Amount +HISTORY_MSG_32;Deconvolution Damping +HISTORY_MSG_33;Deconvolution Iterations +HISTORY_MSG_34;Avoid Color Clipping +HISTORY_MSG_35;Saturation Limiter +HISTORY_MSG_36;Saturation Limit +HISTORY_MSG_37;Color Boost +HISTORY_MSG_38;White Balance Method +HISTORY_MSG_39;Color Temperature +HISTORY_MSG_3;Profile Changed +HISTORY_MSG_40;White Balance Tint +HISTORY_MSG_41;Color Shift "A" +HISTORY_MSG_42;Color Shift "B" +HISTORY_MSG_43;Luminance Denoising +HISTORY_MSG_44;Lum. Denoising Radius +HISTORY_MSG_45;Lum. Denoising Edge Tolerance +HISTORY_MSG_46;Color Denoising +HISTORY_MSG_47;Color Denoising Radius +HISTORY_MSG_48;Color Denoising Edge Tolerance +HISTORY_MSG_49;Edge Sensitive Color Denoising +HISTORY_MSG_4;History Browsing +HISTORY_MSG_50;Shadow/Highlight tool +HISTORY_MSG_51;Highlight boost +HISTORY_MSG_52;Shadow Boost +HISTORY_MSG_53;Highlight Tonal Width +HISTORY_MSG_54;Shadow Tonal Width +HISTORY_MSG_55;Local Contrast +HISTORY_MSG_56;Shadow/Highlight Radius +HISTORY_MSG_57;Coarse Rotation +HISTORY_MSG_58;Horizontal Flipping +HISTORY_MSG_59;Vertical Flipping +HISTORY_MSG_5;Brightness +HISTORY_MSG_60;Rotation +HISTORY_MSG_61;Rotation +HISTORY_MSG_62;Lens Distortion Correction +HISTORY_MSG_63;Snapshot Selected +HISTORY_MSG_64;Crop Photo +HISTORY_MSG_65;C/A Correction +HISTORY_MSG_66;Highlight Recovery +HISTORY_MSG_67;Highlight Recovery Amount +HISTORY_MSG_68;Highlight Recovery Method +HISTORY_MSG_69;Working Color Space +HISTORY_MSG_6;Contrast +HISTORY_MSG_70;Output Color Space +HISTORY_MSG_71;Input Color Space +HISTORY_MSG_72;Vignetting Correction +HISTORY_MSG_73;Channel Mixer +HISTORY_MSG_74;Resize Scale +HISTORY_MSG_75;Resize Method +HISTORY_MSG_76;Exif Metadata +HISTORY_MSG_77;IPTC Metadata +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;Black +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;Exposure Compensation +HISTORY_MSG_9;Highlight Compression +HISTORY_NEWSNAPSHOT;Add +HISTORY_NEWSNAPSHOTAS;As... +HISTORY_NEWSSDIALOGLABEL;Label of the snapshot: +HISTORY_NEWSSDIALOGTITLE;Add new snapshot +HISTORY_SETTO;Set to +HISTORY_SNAPSHOT;Snapshot +HISTORY_SNAPSHOTS;Snapshots +ICMPANEL_FILEDLGFILTERANY;Any files +ICMPANEL_FILEDLGFILTERICM;ICC Profile Files +ICMPANEL_GAMMABEFOREINPUT;Profile applies Gamma +ICMPANEL_INPUTCAMERA;Camera default +ICMPANEL_INPUTCUSTOM;Custom +ICMPANEL_INPUTDLGLABEL;Select Input ICC Profile... +ICMPANEL_INPUTEMBEDDED;Use Embedded, if possible +ICMPANEL_INPUTPROFILE;Input Profile +ICMPANEL_NOICM;No ICM: sRGB output +ICMPANEL_OUTPUTDLGLABEL;Select Output ICC Profile... +ICMPANEL_OUTPUTPROFILE;Output Profile +ICMPANEL_SAVEREFERENCE;Save reference image for profiling +ICMPANEL_WORKINGPROFILE;Working Profile +IMAGEAREA_DETAILVIEW;Detail view +IPTCPANEL_AUTHOR;Author +IPTCPANEL_AUTHORHINT;Name of the creator of the object, e.g. writer, photographer or graphic artist (By-line). +IPTCPANEL_AUTHORSPOSITION;Author's position +IPTCPANEL_AUTHORSPOSITIONHINT;Title of the creator or creators of the object (By-line Title). +IPTCPANEL_CAPTION;Caption +IPTCPANEL_CAPTIONHINT;A textual description of the data (Caption - Abstract). +IPTCPANEL_CAPTIONWRITER;Caption Writer +IPTCPANEL_CAPTIONWRITERHINT;The name of the person involved in the writing, editing or correcting the image or caption/abstract (Writer - Editor). +IPTCPANEL_CATEGORY;Category +IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider (Category). +IPTCPANEL_CITY;City +IPTCPANEL_CITYHINT;City of image origin (City). +IPTCPANEL_COPYHINT;Copy IPTC settings to clipboard +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COPYRIGHTHINT;Any necessary copyright notice (Copyright Notice). +IPTCPANEL_COUNTRY;Country +IPTCPANEL_COUNTRYHINT;The name of the country/primary location where the image was created (Country - Primary Location Name). +IPTCPANEL_CREDIT;Credit +IPTCPANEL_CREDITHINT;Identifies the provider of the image, not necessarily the owner/creator (Credit). +IPTCPANEL_DATECREATED;Date Created +IPTCPANEL_DATECREATEDHINT;The date the intellectual content of the image was created; Format: JJJJMMTT (Date Created). +IPTCPANEL_EMBEDDED;Embedded +IPTCPANEL_EMBEDDEDHINT;Reset to IPTC data embedded in the image file +IPTCPANEL_HEADLINE;Headline +IPTCPANEL_HEADLINEHINT;A publishable entry providing a synopsis of the contents of the image (Headline). +IPTCPANEL_INSTRUCTIONS;Instructions +IPTCPANEL_INSTRUCTIONSHINT;Other editorial instructions concerning the use of the image (Special Instructions). +IPTCPANEL_KEYWORDS;Keywords +IPTCPANEL_KEYWORDSHINT;Used to indicate specific information retrieval words (Keywords). +IPTCPANEL_PASTEHINT;Paste IPTC settings from clipboard +IPTCPANEL_PROVINCE;Province +IPTCPANEL_PROVINCEHINT;The Province/State where the image originates (Province-State). +IPTCPANEL_RESET;Reset +IPTCPANEL_RESETHINT;Reset to profile default +IPTCPANEL_SOURCE;Source +IPTCPANEL_SOURCEHINT;The original owner of the intellectual content of the image (Source). +IPTCPANEL_SUPPCATEGORIES;Suppl. Categories +IPTCPANEL_SUPPCATEGORIESHINT;Further refines the subject of the image (Supplemental Categories). +IPTCPANEL_TITLE;Title +IPTCPANEL_TITLEHINT;A shorthand reference for the image (Object Name). +IPTCPANEL_TRANSREFERENCE;Trans. Reference +IPTCPANEL_TRANSREFERENCEHINT;A code representing the location of original transmission (Original Transmission Reference). +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Preferences +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVE;Save Image +MAIN_BUTTON_SAVEAS;As... +MAIN_BUTTON_SENDTOEDITOR;Send to editor +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES;Places +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;File already exists. +MAIN_MSG_CANNOTLOAD;Cannot load image +MAIN_MSG_CANNOTSAVE;File saving error +MAIN_MSG_CANNOTSTARTEDITOR;Can not start editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Please set the correct path in the "Preferences" dialog. +MAIN_MSG_EXITJOBSINQUEUEINFO;Unprocessed images in the queue will be lost on exit. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Are you sure you want to exit? There are unprocessed images waiting in the queue. +MAIN_MSG_JOBSINQUEUE;job(s) in the queue +MAIN_MSG_QOVERWRITE;Do you want to overwrite it? +MAIN_TAB_BASIC;Basic +MAIN_TAB_COLOR;Color +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Exposure +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Transform +MAIN_TOOLTIP_HIDEFP;Show/hide the bottom panel (directory and file browser, shortcut key: F) +MAIN_TOOLTIP_HIDEHP;Show/hide the left panel (including the history, shortcut key: H) +MAIN_TOOLTIP_INDCLIPPEDH;Clipped highlight indication +MAIN_TOOLTIP_INDCLIPPEDS;Clipped shadow indication +MAIN_TOOLTIP_PREFERENCES;Set preferences +MAIN_TOOLTIP_QINFO;Quick info on the image +MAIN_TOOLTIP_SAVE;Save image to the default folder +MAIN_TOOLTIP_SAVEAS;Save image to a selected folder +PARTIALPASTE_BASICGROUP;Basic settings +PARTIALPASTE_CACORRECTION;C/A correction +PARTIALPASTE_COARSETRANS;90 deg rotation / flipping +PARTIALPASTE_COLORBOOST;Color boost +PARTIALPASTE_COLORDENOISE;Color denoise +PARTIALPASTE_COLORGROUP;Color related settings +PARTIALPASTE_COLORMIXER;Color mixer +PARTIALPASTE_COLORSHIFT;Color shift +PARTIALPASTE_COMPOSITIONGROUP;Composition settings +PARTIALPASTE_CROP;Crop +PARTIALPASTE_DIALOGLABEL;Partial paste processing profile +PARTIALPASTE_DISTORTION;Distortion correction +PARTIALPASTE_EXIFCHANGES;Changes to exif data +PARTIALPASTE_EXPOSURE;Exposure +PARTIALPASTE_HLRECOVERY;Highlight recovery +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Lens related settings +PARTIALPASTE_LUMACURVE;Luminance curve +PARTIALPASTE_LUMADENOISE;Luminance noise reduction +PARTIALPASTE_LUMINANCEGROUP;Luminance related settings +PARTIALPASTE_METAICMGROUP;Metadata/ICM settings +PARTIALPASTE_RESIZE;Resize +PARTIALPASTE_ROTATION;Rotation +PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights +PARTIALPASTE_SHARPENING;Sharpening +PARTIALPASTE_VIGNETTING;Vignetting correction +PARTIALPASTE_WHITEBALANCE;White balance +PREFERENCES_APPLNEXTSTARTUP;applied at next startup +PREFERENCES_BLINKCLIPPED;Blink clipped areas +PREFERENCES_CACHECLEARALL;Clear All +PREFERENCES_CACHECLEARPROFILES;Clear Profiles +PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +PREFERENCES_CACHEFORMAT1;Proprietary (faster and better quality) +PREFERENCES_CACHEFORMAT2;JPEG (smaller disk footprint) +PREFERENCES_CACHEMAXENTRIES;Maximal Number of Cache Entries +PREFERENCES_CACHEOPTS;Cache Options +PREFERENCES_CACHESTRAT1;Prefer Speed to Low Memory Consumption +PREFERENCES_CACHESTRAT2;Prefer Low Memory Consumption to Speed +PREFERENCES_CACHESTRAT;Cache Strategy +PREFERENCES_CACHETHUMBFORM;Cache Thumbnail Format +PREFERENCES_CACHETHUMBHEIGHT;Maximal Thumbnail Height +PREFERENCES_CLEARDLG_LINE1;Clearing cache +PREFERENCES_CLEARDLG_LINE2;This may take a few seconds. +PREFERENCES_CLEARDLG_TITLE;Please wait +PREFERENCES_CLIPPINGIND;Clipping indication +PREFERENCES_CMETRICINTENT;Colorimetric Intent +PREFERENCES_DATEFORMAT;Date Format +PREFERENCES_DATEFORMATHINT;You can use the following formatting strings:\n%y : year\n%m : month\n%d : day\n\nFor example, the hungarian date format is:\n%y/%m/%d +PREFERENCES_DCBENHANCE;Apply DCB enhancment step +PREFERENCES_DCBITERATIONS;Number of DCB iterations +PREFERENCES_DEFAULTLANG;Default language +PREFERENCES_DEFAULTTHEME;Default theme +PREFERENCES_DEMOSAICINGALGO;Demosaicing Algorithm +PREFERENCES_DIRHOME;Home directory +PREFERENCES_DIRLAST;Last visited directory +PREFERENCES_DIROTHER;Other +PREFERENCES_DIRSELECTDLG;Select Image Directory at Startup... +PREFERENCES_DIRSOFTWARE;Installation directory +PREFERENCES_DMETHOD;Method +PREFERENCES_EDITORCMDLINE;Other command line +PREFERENCES_EXTERNALEDITOR;External editor +PREFERENCES_FALSECOLOR;False color suppression steps +PREFERENCES_FBROWSEROPTS;File Browser Options +PREFERENCES_FILEFORMAT;File format +PREFERENCES_FORIMAGE;For image files +PREFERENCES_FORRAW;For RAW files +PREFERENCES_GIMPPATH;GIMP installation directory +PREFERENCES_GTKTHEME;GTK default +PREFERENCES_HINT;Hint +PREFERENCES_HLTHRESHOLD;Threshold for clipped highlights +PREFERENCES_ICCDIR;Directory of ICC profiles +PREFERENCES_IMPROCPARAMS;Default image processing parameters +PREFERENCES_INTENT_ABSOLUTE;Absolute Colorimetric +PREFERENCES_INTENT_PERCEPTUAL;Perceptual +PREFERENCES_INTENT_RELATIVE;Relative Colorimetric +PREFERENCES_INTENT_SATURATION;Saturation +PREFERENCES_LIVETHUMBNAILS;Live Thumbnails (slower) +PREFERENCES_MONITORICC;Monitor Profile +PREFERENCES_OUTDIR;Output Directory +PREFERENCES_OUTDIRFOLDER;Save to folder +PREFERENCES_OUTDIRFOLDERHINT;Put the saved images to the selected folder +PREFERENCES_OUTDIRHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, %p3=/home/tom, ...\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Use Template +PREFERENCES_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, %p3=/home/tom, ...\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_PARSEDEXT;Parsed Extensions +PREFERENCES_PARSEDEXTADD;Add Extension +PREFERENCES_PARSEDEXTADDHINT;Type an extension and press this button to append list +PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list +PREFERENCES_PROFILEHANDLING;Processing Profile Handling +PREFERENCES_PROFILELOADPR;Profile Loading Priority +PREFERENCES_PROFILEPRCACHE;Profile in Cache +PREFERENCES_PROFILEPRFILE;Profile Next to the Input File +PREFERENCES_PROFILESAVECACHE;Save Processing Parameters to the Cache +PREFERENCES_PROFILESAVEINPUT;Save Processing Parameters Next to the Input File +PREFERENCES_PSPATH;Adobe Photoshop installation directory +PREFERENCES_SELECTICCDIRDLG;Select ICC Profile Directory... +PREFERENCES_SELECTLANG;Select language +PREFERENCES_SELECTMONITORPROFDLG;Select ICC Profile of the Display... +PREFERENCES_SELECTTHEME;Select theme +PREFERENCES_SHOWBASICEXIF;Show basic Exif info +PREFERENCES_SHOWDATETIME;Show date and time +PREFERENCES_SHOWONLYRAW;Show only RAW files +PREFERENCES_SHTHRESHOLD;Threshold for clipped shadows +PREFERENCES_STARTUPIMDIR;Image directory at startup +PREFERENCES_TAB_BROWSER;File Browser +PREFERENCES_TAB_COLORMGR;Color Management +PREFERENCES_TAB_GENERAL;General +PREFERENCES_TAB_IMPROC;Image Processing +PREFERENCES_TAB_OUTPUT;Output Options +PREFERENCES_THUMBSIZE;Thumbnail Size +PROFILEPANEL_FILEDLGFILTERANY;Any files +PROFILEPANEL_FILEDLGFILTERPP;Postprocessing profiles +PROFILEPANEL_LABEL;Postprocessing Profiles +PROFILEPANEL_LOADDLGLABEL;Load Postprocessing Parameters... +PROFILEPANEL_PCUSTOM;Custom +PROFILEPANEL_PFILE;From file +PROFILEPANEL_PLASTPHOTO;Last Photo +PROFILEPANEL_PLASTSAVED;Last Saved +PROFILEPANEL_PROFILE;Profile +PROFILEPANEL_SAVEDLGLABEL;Save Postprocessing Parameters... +PROFILEPANEL_TOOLTIPCOPY;Copy current profile to clipboard +PROFILEPANEL_TOOLTIPLOAD;Load a profile from file +PROFILEPANEL_TOOLTIPPASTE; Paste profile from clipboard +PROFILEPANEL_TOOLTIPSAVE;Save current profile +PROGRESSBAR_DECODING;Decoding raw file... +PROGRESSBAR_DEMOSAICING;Demosaicing... +PROGRESSBAR_LOADING;Loading Image... +PROGRESSBAR_LOADJPEG;Loading JPEG file... +PROGRESSBAR_LOADPNG;Loading PNG file... +PROGRESSBAR_LOADTIFF;Loading TIFF file... +PROGRESSBAR_PROCESSING;Processing Image... +PROGRESSBAR_READY;Ready. +PROGRESSBAR_SAVEJPEG;Saving JPEG file... +PROGRESSBAR_SAVEPNG;Saving PNG file... +PROGRESSBAR_SAVETIFF;Saving TIFF file... +PROGRESSDLG_LOADING;Loading file... +PROGRESSDLG_PROCESSING;Processing image... +PROGRESSDLG_SAVING;Saving file... +QINFO_FOCALLENGTH;Focal length +QINFO_ISO;ISO +QINFO_LENS;Lens +QINFO_NOEXIF;Exif data not available. +SAVEDLG_FILEFORMAT;File format +SAVEDLG_JPEGQUAL;JPEG Quality +SAVEDLG_JPGFILTER;JPEG files +SAVEDLG_PNGCOMPR;PNG Compression +SAVEDLG_PNGFILTER;PNG files +SAVEDLG_PUTTOQUEUE;Put into processing queue +SAVEDLG_PUTTOQUEUEHEAD;Put to the head of the processing queue +SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue +SAVEDLG_SAVEIMMEDIATELY;Save immediately +SAVEDLG_SAVESPP;Save processing parameters with image +SAVEDLG_TIFFFILTER;TIFF files +TOOLBAR_TOOLTIP_CROP;Crop selection (Shortcut key: C) +TOOLBAR_TOOLTIP_HAND;Hand tool (Shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Straight line selection (Shortcut key: S) +TOOLBAR_TOOLTIP_WB;Spot white balance (Shortcut key: W) +TP_CACORRECTION_BLUE;Blue +TP_CACORRECTION_LABEL;C/A Correction +TP_CACORRECTION_RED;Red +TP_CHMIXER_BLUE;Blue +TP_CHMIXER_GREEN;Green +TP_CHMIXER_LABEL;Channel Mixer +TP_CHMIXER_RED;Red +TP_COARSETRAF_DEGREE;degree: +TP_COARSETRAF_TOOLTIP_HFLIP;Flip horizontally +TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotate left +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotate right +TP_COARSETRAF_TOOLTIP_VFLIP;Flip vertically +TP_COLORBOOST_ACHANNEL;Channel "a" +TP_COLORBOOST_AMOUNT;Amount +TP_COLORBOOST_AVOIDCOLORCLIP;Avoid color clipping +TP_COLORBOOST_BCHANNEL;Channel "b" +TP_COLORBOOST_CHAB;a & b +TP_COLORBOOST_CHANNEL;Channel +TP_COLORBOOST_CHSEPARATE;separate +TP_COLORBOOST_ENABLESATLIMITER;Enable saturation limiter +TP_COLORBOOST_LABEL;Color Boost +TP_COLORBOOST_SATLIMIT;Saturation limit +TP_COLORDENOISE_EDGESENSITIVE;Edge Sensitive +TP_COLORDENOISE_EDGETOLERANCE;Edge Tolerance +TP_COLORDENOISE_LABEL;Color Noise Reduction +TP_COLORDENOISE_RADIUS;Radius +TP_COLORSHIFT_BLUEYELLOW;Blue-Yellow +TP_COLORSHIFT_GREENMAGENTA;Green-Magenta +TP_COLORSHIFT_LABEL;Color Shift +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Fix Ratio: +TP_CROP_GTDIAGONALS;Rule of diagonals +TP_CROP_GTHARMMEANS1;Harmonic means 1 +TP_CROP_GTHARMMEANS2;Harmonic means 2 +TP_CROP_GTHARMMEANS3;Harmonic means 3 +TP_CROP_GTHARMMEANS4;Harmonic means 4 +TP_CROP_GTNONE;None +TP_CROP_GTRULETHIRDS;Rule of thirds +TP_CROP_GUIDETYPE;Guide Type: +TP_CROP_H;H +TP_CROP_LABEL;Crop +TP_CROP_SELECTCROP; Select Crop +TP_CROP_W;W +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Amount +TP_DISTORTION_LABEL;Distortion +TP_EXPOSURE_AUTOLEVELS;Auto Levels +TP_EXPOSURE_BLACKLEVEL;Black +TP_EXPOSURE_BRIGHTNESS;Brightness +TP_EXPOSURE_CLIP;Clip +TP_EXPOSURE_COMPRHIGHLIGHTS;Highlight compression +TP_EXPOSURE_COMPRSHADOWS;Shadow compression +TP_EXPOSURE_CONTRAST;Contrast +TP_EXPOSURE_CURVEEDITOR;Tone Curve +TP_EXPOSURE_EXPCOMP;Exp. Comp. +TP_EXPOSURE_LABEL;Exposure +TP_HLREC_CIELAB;CIELab Blending +TP_HLREC_COLOR;Color Propagation +TP_HLREC_LABEL;Highlight Recovery +TP_HLREC_LUMINANCE;Luminance Recovery +TP_HLREC_METHOD;Method: +TP_ICM_FILEDLGFILTERANY;Any files +TP_ICM_FILEDLGFILTERICM;ICC Profile Files +TP_ICM_GAMMABEFOREINPUT;Profile applies Gamma +TP_ICM_INPUTCAMERA;Camera default +TP_ICM_INPUTCUSTOM;Custom +TP_ICM_INPUTDLGLABEL;Select Input ICC Profile... +TP_ICM_INPUTEMBEDDED;Use Embedded, if possible +TP_ICM_INPUTPROFILE;Input Profile +TP_ICM_LABEL;ICM +TP_ICM_NOICM;No ICM: sRGB output +TP_ICM_OUTPUTDLGLABEL;Select Output ICC Profile... +TP_ICM_OUTPUTPROFILE;Output Profile +TP_ICM_SAVEREFERENCE;Save reference image for profiling +TP_ICM_WORKINGPROFILE;Working Profile +TP_LUMACURVE_BLACKLEVEL;Black +TP_LUMACURVE_BRIGHTNESS;Brightness +TP_LUMACURVE_COMPRHIGHLIGHTS;Highlight compression +TP_LUMACURVE_COMPRSHADOWS;Shadow compression +TP_LUMACURVE_CONTRAST;Contrast +TP_LUMACURVE_CURVEEDITOR;Luminance Curve +TP_LUMACURVE_LABEL;Luminance Curve +TP_LUMADENOISE_EDGETOLERANCE;Edge Tolerance +TP_LUMADENOISE_LABEL;Luminance Noise Reduction +TP_LUMADENOISE_RADIUS;Radius +TP_RESIZE_BICUBIC;Bicubic +TP_RESIZE_BICUBICSF;Bicubic (Softer) +TP_RESIZE_BICUBICSH;Bicubic (Sharper) +TP_RESIZE_BILINEAR;Bilinear +TP_RESIZE_DOWNSCALEB;Downscale (Better) +TP_RESIZE_DOWNSCALEF;Downscale (Faster) +TP_RESIZE_FULLSIZE;Full Image Size: +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Resize +TP_RESIZE_METHOD;Method: +TP_RESIZE_NEAREST;Nearest +TP_RESIZE_SCALE;Scale +TP_RESIZE_W;W: +TP_ROTATE_AUTOCROP;Auto Crop +TP_ROTATE_DEGREE;Degree +TP_ROTATE_FILL;Fill +TP_ROTATE_LABEL;Rotate +TP_ROTATE_SELECTLINE; Select Straight Line +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Highlights +TP_SHADOWSHLIGHTS_HLTONALW;Tonal Width +TP_SHADOWSHLIGHTS_LABEL;Shadows/Highlights +TP_SHADOWSHLIGHTS_LOCALCONTR;Local Contrast +TP_SHADOWSHLIGHTS_RADIUS;Radius +TP_SHADOWSHLIGHTS_SHADOWS;Shadows +TP_SHADOWSHLIGHTS_SHTONALW;Tonal Width +TP_SHARPENING_AMOUNT;Amount +TP_SHARPENING_EDRADIUS;Radius +TP_SHARPENING_EDTOLERANCE;Edge tolerance +TP_SHARPENING_HALOCONTROL;Halo control +TP_SHARPENING_HCAMOUNT;Amount +TP_SHARPENING_LABEL;Sharpening +TP_SHARPENING_METHOD;Method +TP_SHARPENING_ONLYEDGES;Sharpen only edges +TP_SHARPENING_RADIUS;Radius +TP_SHARPENING_RLD;RL Deconvolution +TP_SHARPENING_RLD_AMOUNT;Amount +TP_SHARPENING_RLD_DAMPING;Damping +TP_SHARPENING_RLD_ITERATIONS;Iterations +TP_SHARPENING_THRESHOLD;Threshold +TP_SHARPENING_USM;Unsharp Mask +TP_VIGNETTING_AMOUNT;Amount +TP_VIGNETTING_LABEL;Vignetting Correction +TP_VIGNETTING_RADIUS;Radius +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Camera +TP_WBALANCE_CUSTOM;Custom +TP_WBALANCE_GREEN;Tint +TP_WBALANCE_LABEL;White Balance +TP_WBALANCE_METHOD;Method +TP_WBALANCE_SIZE;Size: +TP_WBALANCE_SPOTWB;Spot WB +TP_WBALANCE_TEMPERATURE;Temperature +ZOOMBAR_DETAIL;Detail +ZOOMBAR_HUGE;Huge +ZOOMBAR_LARGE;Large +ZOOMBAR_NORMAL;Normal +ZOOMBAR_PREVIEW;Preview +ZOOMBAR_SCALE;Scale +ZOOMBAR_SMALL;Small + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Espanol b/rtdata/languages/Espanol new file mode 100644 index 000000000..d5eee426f --- /dev/null +++ b/rtdata/languages/Espanol @@ -0,0 +1,709 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# Espanol +# 15.1.2008: keenonkites, first translation +# 03.03.2008: Ioritz Ibarguren, corrections +# 05.04.2008: keenonkites, completed for 2.4m1 +# 09.04.2008: Ramon, partly corrected (part of 2.3) +# 29.04.2008: Ramon, small correction +# 09.06.2008: Ramon, Adaptions regarding 2.4m1 and others +# 20.09.2008: keenonkites, first version for 2.4m2 +# 19.12.2008: keenonkites, first version for 2.4beta4 +ADJUSTER_RESET_TO_DEFAULT;Restablece los valores predeterminados +CURVEEDITOR_FILEDLGFILTERANY;Cuaquier archivo +CURVEEDITOR_FILEDLGFILTERCURVE;Archivos de curvas +CURVEEDITOR_LINEAR;Lineal +CURVEEDITOR_LOADDLGLABEL;Cargar curva... +CURVEEDITOR_SAVEDLGLABEL;Guardar curva... +CURVEEDITOR_TOOLTIPLINEAR;Restablece la curva a lineal +CURVEEDITOR_TOOLTIPLOAD;Abre una curva desde un archivo +CURVEEDITOR_TOOLTIPSAVE;Guarda curva actual +EXIFFILTER_APERTURE;Diafragma +EXIFFILTER_CAMERA;Cámera +EXIFFILTER_DIALOGLABEL;Filtro Exif +EXIFFILTER_FOCALLEN;Distancia focal +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objectivo +EXIFFILTER_SHUTTER;tiempo de exposición +EXIFPANEL_ADDEDIT;Agregar/Cambiar +EXIFPANEL_ADDEDITHINT;Agregar atributo nuevo o cambiar atributo +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Entroducir valor +EXIFPANEL_ADDTAGDLG_SELECTTAG;Seleccionar atributo +EXIFPANEL_ADDTAGDLG_TITLE;Agregar/Cambiar atributo +EXIFPANEL_KEEP;Conservar +EXIFPANEL_KEEPHINT;Conserva las etiquetas seleccionadas al escribir el archivo de salida +EXIFPANEL_REMOVE;Borrar +EXIFPANEL_REMOVEHINT;Quita las etiquetas seleccionadas al escribir el archivo de salida +EXIFPANEL_RESETALLHINT;Reiniciar todos los atributos a los valores originales +EXIFPANEL_RESETALL;Reiniciar todo +EXIFPANEL_RESETHINT;Reiniciar atributos seleccionados a los valores originales +EXIFPANEL_RESET;Reiniciar +EXIFPANEL_SUBDIRECTORY;Subcarpeta +FILEBROWSER_APPLYPROFILE;Aplicar perfil +FILEBROWSER_ARRANGEMENTHINT;Cambiar disposición de las miniaturas entre horizontal y vertical +FILEBROWSER_CLEARPROFILE;Borrar perfil +FILEBROWSER_COPYPROFILE;Copiar perfil +FILEBROWSER_DELETEDLGLABEL;Confirmacion de borrar archivos +FILEBROWSER_DELETEDLGMSG;¿Seguro que quieres borrar los %1 archivos seleccionados? +FILEBROWSER_EMPTYTRASHHINT;Borrar archivos de la papelera definitivamente +FILEBROWSER_EMPTYTRASH;Vaciar papelera +FILEBROWSER_EXIFFILTERAPPLY;Aplicar +FILEBROWSER_EXIFFILTERAPPLYHINT;Activar/desactivar filtro exif en el explorador de archivos +FILEBROWSER_EXIFFILTERLABEL;Filtro Exif +FILEBROWSER_EXIFFILTERSETTINGS;Ajuste +FILEBROWSER_EXIFFILTERSETTINGSHINT;Cambiar ajustes del filtro exif +FILEBROWSER_PARTIALPASTEPROFILE;Pegar perfil parcialmente +FILEBROWSER_PASTEPROFILE;Pegar perfil +FILEBROWSER_POPUPCANCELJOB;Cancelar trabajo +FILEBROWSER_POPUPMOVEEND;Desplazar al fin de la cola +FILEBROWSER_POPUPMOVEHEAD;Desplazar al comienzo de la cola +FILEBROWSER_POPUPOPEN;Abrir +FILEBROWSER_POPUPPROCESS;Poner en la cola +FILEBROWSER_POPUPRANK1;Valorar con 1 estrella +FILEBROWSER_POPUPRANK2;Valorar con 2 estrella +FILEBROWSER_POPUPRANK3;Valorar con 3 estrella +FILEBROWSER_POPUPRANK4;Valorar con 4 estrella +FILEBROWSER_POPUPRANK5;Valorar con 5 estrella +FILEBROWSER_POPUPREMOVE;Borrar del systema +FILEBROWSER_POPUPRENAME;Renombrar +FILEBROWSER_POPUPSELECTALL;Seleccionar todo +FILEBROWSER_POPUPTRASH;Desplazar a la papelera +FILEBROWSER_POPUPUNRANK;Quitar valoración +FILEBROWSER_POPUPUNTRASH;Salvar de la papelera +FILEBROWSER_PROCESSINGSETTINGS;Ajustes +FILEBROWSER_PROCESSINGSETTINGSHINT;Ajustar formato de archivo y carpeta de salida +FILEBROWSER_RENAMEDLGLABEL;Renombrar archivo +FILEBROWSER_RENAMEDLGMSG;Renombrar archive "%1"a: +FILEBROWSER_SHOWDIRHINT;Mostrar todas imagenes de la carpeta +FILEBROWSER_SHOWQUEUEHINT;Mostrar contenido de la cola de procesamiento +FILEBROWSER_SHOWRANK1HINT;Mostrar imagenes con 1 estrella +FILEBROWSER_SHOWRANK2HINT;Mostrar imagenes con 2 estrellas +FILEBROWSER_SHOWRANK3HINT;Mostrar imagenes con 3 estrellas +FILEBROWSER_SHOWRANK4HINT;Mostrar imagenes con 4 estrellas +FILEBROWSER_SHOWRANK5HINT;Mostrar imagenes con 5 estrellas +FILEBROWSER_SHOWTRASHHINT;Mostrar contenido de la papelera +FILEBROWSER_SHOWUNRANKHINT;Mostrar imagenes sin valoración +FILEBROWSER_STARTPROCESSINGHINT;Iniciar procesamiento de imagenes en la cola +FILEBROWSER_STARTPROCESSING;Iniciar procesamiento +FILEBROWSER_STOPPROCESSINGHINT;Parar procesamiento de imagenes en la cola +FILEBROWSER_STOPPROCESSING;Parar procesamiento +FILEBROWSER_THUMBSIZE;Tamaño miniatura +FILEBROWSER_ZOOMINHINT;Agrandar miniatura +FILEBROWSER_ZOOMOUTHINT;Reducir miniatura +GENERAL_ABOUT;Acerca de +GENERAL_CANCEL;Cancelar +GENERAL_DISABLED;Desactivado +GENERAL_DISABLE;Desactivar +GENERAL_ENABLE;Activar +GENERAL_ENABLED;Activado +GENERAL_LANDSCAPE;Paisaje +GENERAL_LOAD;Abrir +GENERAL_NA;n/a +GENERAL_NO;No +GENERAL_OK;Aceptar +GENERAL_PORTRAIT;Retrato +GENERAL_SAVE;Guardar +GENERAL_YES;Sí +HISTOGRAM_LABEL;Histograma +HISTOGRAM_TOOLTIP_B;Mostrar/Ocultar histograma AZUL +HISTOGRAM_TOOLTIP_G;Mostrar/Ocultar histograma VERDE +HISTOGRAM_TOOLTIP_L;Mostrar/Ocultar histograma de Luminancia CIELAB +HISTOGRAM_TOOLTIP_R;Mostrar/Ocultar histograma ROJO +HISTORY_CHANGED;Cambiado +HISTORY_CUSTOMCURVE;Curva a medida +HISTORY_DELSNAPSHOT;Quitar Instantánea +HISTORY_FROMCLIPBOARD;Desde el portapapeles +HISTORY_LABEL;Historial +HISTORY_MSG_10;Compresión de Sombras +HISTORY_MSG_11;Curva de Tono +HISTORY_MSG_12;Exposición Automática +HISTORY_MSG_13;Recorte de Exposición +HISTORY_MSG_14;Luminancia Brillo +HISTORY_MSG_15;Luminancia Contraste +HISTORY_MSG_16;Luminancia Negro +HISTORY_MSG_17;Luminancia Compr. de Luces Altas +HISTORY_MSG_18;Luminancia Compr. de Sombras +HISTORY_MSG_19;Luminancia Curva +HISTORY_MSG_1;Foto Abierta +HISTORY_MSG_20;Enfoque +HISTORY_MSG_21;Enfoque Radio +HISTORY_MSG_22;Enfoque Cantidad +HISTORY_MSG_23;Enfoque Umbral +HISTORY_MSG_24;Enfocar solo Bordes +HISTORY_MSG_25;Enfoque Detección de Bordes Radio +HISTORY_MSG_26;Enfoque Tolerancia de bordes +HISTORY_MSG_27;Enfoque Control de Halo +HISTORY_MSG_28;Control de Halo Cantidad +HISTORY_MSG_29;Enfoque Método +HISTORY_MSG_2;Perfil Abierto +HISTORY_MSG_30;Deconvolución Radio +HISTORY_MSG_31;Deconvolución Cantidad +HISTORY_MSG_32;Deconvolución Amortiguación +HISTORY_MSG_33;Deconvolución Reiteraciones +HISTORY_MSG_34;Evitar Recorte de Colores +HISTORY_MSG_35;Limitador de Saturación +HISTORY_MSG_36;Límite de Saturación +HISTORY_MSG_37;Aumento de Colores +HISTORY_MSG_38;Equilibrio del Blancos Método +HISTORY_MSG_39;Temperatura de Color +HISTORY_MSG_3;Perfil Cambiado +HISTORY_MSG_40;Equilibrio del Blancos Tinte +HISTORY_MSG_41;Cambio de Colores "A" +HISTORY_MSG_42;Cambio de Colores "B" +HISTORY_MSG_43;Reducción Ruido de Luminancia +HISTORY_MSG_44;Red. Ruido de Lum. Radio +HISTORY_MSG_45;Red. Ruido de Lum. Tolerancia de Bordes +HISTORY_MSG_46;Red. Ruido de Color +HISTORY_MSG_47;Red. Ruido de Color Radio +HISTORY_MSG_48;Red. Ruido de Color Tolerancia de bordes +HISTORY_MSG_49;Red. Ruido de Color Sensible a bordes +HISTORY_MSG_4;Búsqueda de Historial +HISTORY_MSG_50;Herramienta Sombras/Luces Altas +HISTORY_MSG_51;Aumento de Luces altas +HISTORY_MSG_52;Aumento de Sombras +HISTORY_MSG_53;Luces altas Ancho Tonal +HISTORY_MSG_54;Sombras Ancho Tonal +HISTORY_MSG_55;Constraste local +HISTORY_MSG_56;Sombras/Luces altas Radio +HISTORY_MSG_57;Rotación basta +HISTORY_MSG_58;Volteo horizontal +HISTORY_MSG_59;Volteo vertical +HISTORY_MSG_5;Brillo +HISTORY_MSG_60;Rotación +HISTORY_MSG_61;Rotación +HISTORY_MSG_62;Corrección de Distorsión del Objectivo +HISTORY_MSG_63;Marcador seleccionado +HISTORY_MSG_64;Recortar Foto +HISTORY_MSG_65;Corrección Ab. Cr. +HISTORY_MSG_66;Recuperación de Luces Altas +HISTORY_MSG_67;Recuperación de Luces Altas Cantidad +HISTORY_MSG_68;Recuperación de Luces Altas Método +HISTORY_MSG_69;Espacio de Color de trabajo +HISTORY_MSG_6;Contraste +HISTORY_MSG_70;Espacio de Color de Salida +HISTORY_MSG_71;Espacio de Color de Entrada +HISTORY_MSG_72;Corrección de viñeteo +HISTORY_MSG_73;Mezclador de Canal +HISTORY_MSG_74;Cambiar Tamaño Escala +HISTORY_MSG_75;Cambiar Tamaño Método +HISTORY_MSG_76;Metadato de Exif +HISTORY_MSG_77;Metadato de IPTC +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;Negro +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;Compensación de Exposición +HISTORY_MSG_9;Compresión de Luces Altas +HISTORY_NEWSNAPSHOTAS;Como... +HISTORY_NEWSNAPSHOT;Instantánea nueva +HISTORY_NEWSSDIALOGLABEL;Etiqueta de la Instantánea: +HISTORY_NEWSSDIALOGTITLE;Añadir Instantánea Nueva +HISTORY_SETTO;Ajustado a +HISTORY_SNAPSHOT;Instantánea +HISTORY_SNAPSHOTS;Instantáneas +ICMPANEL_FILEDLGFILTERANY;Cualquier Archivo +ICMPANEL_FILEDLGFILTERICM;Archivos de Perfiles ICC +ICMPANEL_GAMMABEFOREINPUT;El Perfil aplica Gamma +ICMPANEL_INPUTCAMERA;Valores predeterminados de la cámara +ICMPANEL_INPUTCUSTOM;A Medida +ICMPANEL_INPUTDLGLABEL;Seleccionar perfil ICC de entrada... +ICMPANEL_INPUTEMBEDDED;Usar Incrustado, si es posible +ICMPANEL_INPUTPROFILE;Perfil de Entrada +ICMPANEL_NOICM;Ningún MIC: Salida sRGB +ICMPANEL_OUTPUTDLGLABEL;Seleccionar perfil ICC de salida... +ICMPANEL_OUTPUTPROFILE;Perfil de Salida +ICMPANEL_SAVEREFERENCE;Guardar imagen de referencia para el perfilado +ICMPANEL_WORKINGPROFILE;Perfil de Trabajo +IMAGEAREA_DETAILVIEW;Vista de detalle +IPTCPANEL_AUTHOR;Autor +IPTCPANEL_AUTHORHINT;Nombre del creador del objeto, por ejemplo el escritor, el fotótografo o el artista gráfico (By-line). +IPTCPANEL_AUTHORSPOSITIONHINT;Título del creador o de los creadores del objeto (By-line Title). +IPTCPANEL_AUTHORSPOSITION;Tratamiento o título del autor +IPTCPANEL_CAPTIONHINT;Descripción textual de la información (Caption - Abstract). +IPTCPANEL_CAPTION;Leyenda +IPTCPANEL_CAPTIONWRITER;Autor de la Leyenda +IPTCPANEL_CAPTIONWRITERHINT;Nombre de la persona que escribió, modificó o corrigió la imagen o leyenda/resumen (Writer - Editor). +IPTCPANEL_CATEGORY;Categoría +IPTCPANEL_CATEGORYHINT;Código de tres letras que identifica el sujeto de la imagen en opinión del proveedor (Category). +IPTCPANEL_CITY;Ciudad +IPTCPANEL_CITYHINT;Origen de la imagen: Ciudad (City). +IPTCPANEL_COPYHINT;Copiar ajustes IPTC al portapapeles +IPTCPANEL_COPYRIGHT;Derechos de autor +IPTCPANEL_COPYRIGHTHINT;Cualquier llamada de atención necesaria sobre los derechos de autor (Copyright Notice). +IPTCPANEL_COUNTRYHINT;Origen de la imagen: Pais (Country - Primary Location Name). +IPTCPANEL_COUNTRY;País +IPTCPANEL_CREDIT;Créditos +IPTCPANEL_CREDITHINT;Identifica el proveedor de la imagen, no tiene que ser el creador o el propietario (Credit). +IPTCPANEL_DATECREATED;Fecha de creación +IPTCPANEL_DATECREATEDHINT;Fecha de creación del contenido intelectual de la imagen; Format: AAAAMMDD (Date Created). +IPTCPANEL_EMBEDDEDHINT;Reiniciar a los datos IPTC incrustados en el archivo de la imagen +IPTCPANEL_EMBEDDED;Incrustado +IPTCPANEL_HEADLINEHINT;Una anotación publicable que provee una sinopsis de los contenidos de la imagen (Headline). +IPTCPANEL_HEADLINE;Titular +IPTCPANEL_INSTRUCTIONSHINT;Otras instrucciones editoriales sobre el uso de la imagen (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Instrucciones +IPTCPANEL_KEYWORDSHINT;Palabras clave que hacen la búsqueda de la imagen mas fácil (Keywords). +IPTCPANEL_KEYWORDS;Palabras clave +IPTCPANEL_PASTEHINT;Pegar ajustes IPTC desde el portapapeles +IPTCPANEL_PROVINCE;Estado/Provincia +IPTCPANEL_PROVINCEHINT;Origen de la imagen: Estado/Provincia (Province-State). +IPTCPANEL_RESETHINT;Reiniciar a los ajustes predeterminados del perfil. +IPTCPANEL_RESET;Reiniciar +IPTCPANEL_SOURCE;Fuente +IPTCPANEL_SOURCEHINT;Propietario original del contenido intelectual de la imagen (Source). +IPTCPANEL_SUPPCATEGORIES;Categorías suplementarias +IPTCPANEL_SUPPCATEGORIESHINT;Afinado del sujeto de la imagen (Supplemental Categories). +IPTCPANEL_TITLEHINT;Referencia concisa de la imagen (Object Name). +IPTCPANEL_TITLE;Título +IPTCPANEL_TRANSREFERENCEHINT;Un código que representa el lugar de la transmisión original (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Ref. trans. original +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Preferencias +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;Como... +MAIN_BUTTON_SAVE;Guardar Imagen +MAIN_BUTTON_SENDTOEDITOR;Abrir con editor +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Este archivo ya existe. +MAIN_MSG_CANNOTLOAD;No se puede abrir imagen +MAIN_MSG_CANNOTSAVE;Error al guardar archivo +MAIN_MSG_CANNOTSTARTEDITOR;Problema abriendo con editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Porfavor ajusten las preferencias. +MAIN_MSG_EXITJOBSINQUEUEINFO;Saliendo del programa imagenes no terminados en la cola son perdidos. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Estas seguro de salis ? Hay imagenes no terminados en la cola. +MAIN_MSG_JOBSINQUEUE;trabajo(s) en cola +MAIN_MSG_QOVERWRITE;¿Quieres reemplazarlo? +MAIN_TAB_BASIC;Básicos +MAIN_TAB_COLOR;Color +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Exposición +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;GIC +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Transformar +MAIN_TOOLTIP_HIDEFP;Mostrar/Ocultar panel inferior (explorador carpetas y arch. tecla F) +MAIN_TOOLTIP_HIDEHP;Mostrar/Ocultar panel izquierdo (incluyendo historial, tecla H) +MAIN_TOOLTIP_INDCLIPPEDH;Indicación de luces altas recortadas +MAIN_TOOLTIP_INDCLIPPEDS;Indicación de sombras recortadas +MAIN_TOOLTIP_PREFERENCES;Ajustar preferencias +MAIN_TOOLTIP_QINFO; Información breve de la imagen +MAIN_TOOLTIP_SAVEAS;Guardar imagen a una carpeta seleccionada +MAIN_TOOLTIP_SAVE;Guardar imagen a la carpeta predeterminada +PARTIALPASTE_BASICGROUP;Ajustes Básicos +PARTIALPASTE_CACORRECTION;Corrección de Aberraciones Cromáticas +PARTIALPASTE_COARSETRANS;Rotar 90 grados / voltear +PARTIALPASTE_COLORBOOST;Aumenta de Colores +PARTIALPASTE_COLORDENOISE;Reducción de Ruido de Color +PARTIALPASTE_COLORGROUP;Ajustes de Color +PARTIALPASTE_COLORMIXER;Mezclador de Canal +PARTIALPASTE_COLORSHIFT;Cambio de Colores +PARTIALPASTE_COMPOSITIONGROUP;Ajustes al respecto de la figuración +PARTIALPASTE_CROP;Recortar +PARTIALPASTE_DIALOGLABEL;Pegar perfil de procesamiento parcialmente +PARTIALPASTE_DISTORTION;Distorsión +PARTIALPASTE_EXIFCHANGES;Cambio en datos exif +PARTIALPASTE_EXPOSURE;Exposición +PARTIALPASTE_HLRECOVERY;Recuperación de Luces Altas +PARTIALPASTE_ICMSETTINGS;Ajustes GIC +PARTIALPASTE_IPTCINFO;Informaciones IPTC +PARTIALPASTE_LENSGROUP;Ajustes al respecto del objetivo +PARTIALPASTE_LUMACURVE;Curva de Luminancia +PARTIALPASTE_LUMADENOISE;Reducción de Ruido de Luminancia +PARTIALPASTE_LUMINANCEGROUP;Ajustes de Luminancia +PARTIALPASTE_METAICMGROUP;Ajustes Metadatos/GIC +PARTIALPASTE_RESIZE;Cambiar Tamaño +PARTIALPASTE_ROTATION;Rotar +PARTIALPASTE_SHADOWSHIGHLIGHTS;Sombras/Luces Altas +PARTIALPASTE_SHARPENING;Enfoque +PARTIALPASTE_VIGNETTING;Corrección de viñeteo +PARTIALPASTE_WHITEBALANCE;Equilibrio de Blancos +PREFERENCES_APPLNEXTSTARTUP;aplicado al próximo arranque +PREFERENCES_BLINKCLIPPED;Parpadear áreas cortadas +PREFERENCES_CACHECLEARALL;Borrar todo +PREFERENCES_CACHECLEARPROFILES;Borrar perfiles +PREFERENCES_CACHECLEARTHUMBS;Borrar miniaturas +PREFERENCES_CACHEFORMAT1;Propio (mas rapido y mejor calidad) +PREFERENCES_CACHEFORMAT2;JPEG (menos consume de disco duro) +PREFERENCES_CACHEMAXENTRIES;Cantidad máxima de entradas en la memoria intermedia +PREFERENCES_CACHEOPTS;Ajustar memoria intermedia +PREFERENCES_CACHESTRAT1;Preferir velocidad sobre consume de memoria +PREFERENCES_CACHESTRAT2;Preferir consume de memoria bajo sobre velocidad +PREFERENCES_CACHESTRAT;Estrategia de la memoria intermedia +PREFERENCES_CACHETHUMBFORM;Formato de las miniaturas +PREFERENCES_CACHETHUMBHEIGHT;Altura máxima de las miniaturas +PREFERENCES_CLEARDLG_LINE1;Borrando memoria intermedia +PREFERENCES_CLEARDLG_LINE2;Puede durar unos segundos. +PREFERENCES_CLEARDLG_TITLE;Aguardar, por favor +PREFERENCES_CLIPPINGIND;Indicación de recortes +PREFERENCES_CMETRICINTENT;Intento Colorimétrico +PREFERENCES_DATEFORMAT;Formato de Fechas +PREFERENCES_DATEFORMATHINT;Se puede usar las variables siguientes:\n%y : año\n%m : mes\n%d : dia\n\nPor ejemplo, la fecha en Argentina es:\n%d/%m/%y +PREFERENCES_DEFAULTLANG;Idioma predeterminado +PREFERENCES_DEFAULTTHEME;Estilo predeterminado +PREFERENCES_DEMOSAICINGALGO;Algoritmo de desmosaicado +PREFERENCES_DIRHOME;Carpeta de Usuario +PREFERENCES_DIRLAST;Última carpeta visitada +PREFERENCES_DIROTHER;Otro +PREFERENCES_DIRSELECTDLG;Seleccionar Carpeta de Imagenes en el arranque... +PREFERENCES_DIRSOFTWARE;Carpeta de instalación +PREFERENCES_DMETHOD;Método +PREFERENCES_EDITORCMDLINE;Otro mandato +PREFERENCES_EXTERNALEDITOR;Editor externa +PREFERENCES_FALSECOLOR;Pasos de supresión de colores falsos +PREFERENCES_FBROWSEROPTS;Opciones del Explorador de archivos +PREFERENCES_FILEFORMAT;Formato de Archivos +PREFERENCES_FORIMAGE;Para Archivos de Imágenes +PREFERENCES_FORRAW;Para archivos RAW +PREFERENCES_GIMPPATH;Carpeta de instalación de GIMP +PREFERENCES_GTKTHEME;Estilo de GTK predeterminado +PREFERENCES_HINT;Consejo +PREFERENCES_HLTHRESHOLD;Umbral de luces altas cortados +PREFERENCES_ICCDIR;Carpeta de Perfiles ICC +PREFERENCES_IMPROCPARAMS;Parámetros predeterminados de procesamiento de imágenes +PREFERENCES_INTENT_ABSOLUTE;Colorimétrico Absoluto +PREFERENCES_INTENT_PERCEPTUAL;Perceptual +PREFERENCES_INTENT_RELATIVE;Colorimétrico Relativo +PREFERENCES_INTENT_SATURATION;Saturación +PREFERENCES_LIVETHUMBNAILS;Miniaturas 'en vivo' (mas lento) +PREFERENCES_MONITORICC;Perfil de Pantalla +PREFERENCES_OUTDIR;Carpeta de Salida +PREFERENCES_OUTDIRFOLDER;Guardar en carpeta +PREFERENCES_OUTDIRFOLDERHINT;Guardar las imagenes creadas en una carpeta elegida +PREFERENCES_OUTDIRHINT;Se puede usar las variables siguientes:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nEstas variables son referencias a las carpetas y subrutas de las rutas del lugar donde se encuentra la imagen RAW.\n\nPor ejemplo, si abres /home/tom/image/02-09-2006/dsc0012.nef, los valores de las variables son:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nSi quieres guardar la imagen de salida en el lugar original, usa:\n%p1/%f\n\nSi quieres guardar la imagen de salida en una carpeta 'convertida' dentro de la carpeta original, usa:\n%p1/convertida/%f\n\nSi quieres guardar la imagen de salida en la carpeta '/home/tom/convertida' conservando la misma subcarpeta de fechas, usa:\n%p2/convertida/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;Se puede usar las variables siguientes:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nEstas variables son referencias a las carpetas y subrutas de las rutas del lugar donde se encuentra la imagen RAW.\n\nPor ejemplo, si abres /home/tom/image/02-09-2006/dsc0012.nef, los valores de las variables son:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nSi quieres guardar la imagen de salida en el lugar original, usa:\n%p1/%f\n\nSi quieres guardar la imagen de salida en una carpeta 'convertida' dentro de la carpeta original, usa:\n%p1/convertida/%f\n\nSi quieres guardar la imagen de salida en la carpeta '/home/tom/convertida' conservando la misma subcarpeta de fechas, usa:\n%p2/convertida/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Usar plantilla +PREFERENCES_PARSEDEXTADD;Agregar Extensión +PREFERENCES_PARSEDEXTADDHINT;Entra una extensión y apreta este botón para agregar a la lista +PREFERENCES_PARSEDEXTDELHINT;Borrar extensión de la lista +PREFERENCES_PARSEDEXT;Extensiones analizados +PREFERENCES_PROFILEHANDLING;Tratamiento de perfiles de procesamiento +PREFERENCES_PROFILELOADPR;Prioridad de perfiles quando abriendo imagen +PREFERENCES_PROFILEPRCACHE;Perfil en memoria intermedia +PREFERENCES_PROFILEPRFILE;Perfil junto con imagen de entrada +PREFERENCES_PROFILESAVECACHE;Guardar perfiles de procesamiento en memoria intermedia +PREFERENCES_PROFILESAVEINPUT;Guardar perfiles de procesamiento junto con imagen de entrada +PREFERENCES_PSPATH;Carpeta de instalación de Adobe Photoshop +PREFERENCES_SELECTICCDIRDLG;Seleccionar Carpeta de Perfiles ICC... +PREFERENCES_SELECTLANG;Seleccionar idioma +PREFERENCES_SELECTMONITORPROFDLG;Seleccionar Perfil ICC de la Pantalla... +PREFERENCES_SELECTTHEME;Seleccionar estilo +PREFERENCES_SHOWBASICEXIF;Mostrar datos EXIF básicos +PREFERENCES_SHOWDATETIME;Mostrar fecha y hora +PREFERENCES_SHOWONLYRAW;Mostrar solo Archivos RAW +PREFERENCES_SHTHRESHOLD;Umbral de sombras cortados +PREFERENCES_STARTUPIMDIR;Carpeta de imágenes en el arranque +PREFERENCES_TAB_BROWSER;Explorador de Archivos +PREFERENCES_TAB_COLORMGR;Gestión del Color +PREFERENCES_TAB_GENERAL;General +PREFERENCES_TAB_IMPROC;Procesamiento de Imagenes +PREFERENCES_TAB_OUTPUT;Opciones de Salida +PREFERENCES_THUMBSIZE;Tamaño de Miniaturas +PROFILEPANEL_FILEDLGFILTERANY;Cualquier archivo +PROFILEPANEL_FILEDLGFILTERPP;Perfiles de procesamiento +PROFILEPANEL_LABEL;Perfiles de Procesamiento +PROFILEPANEL_LOADDLGLABEL;Cargar parámetros de procesamiento... +PROFILEPANEL_PCUSTOM;A medida +PROFILEPANEL_PFILE;Desde archivo +PROFILEPANEL_PLASTPHOTO;Última Foto +PROFILEPANEL_PLASTSAVED;Último Guardado +PROFILEPANEL_PROFILE;Perfil +PROFILEPANEL_SAVEDLGLABEL;Guardar parámetros de procesamiento... +PROFILEPANEL_TOOLTIPCOPY;Copiar parámetros de procesamiento al portapapeles +PROFILEPANEL_TOOLTIPLOAD;Cargar perfil de un archivo +PROFILEPANEL_TOOLTIPPASTE; Pegar perfil del portapapeles +PROFILEPANEL_TOOLTIPSAVE;Guardar perfil actual +PROGRESSBAR_DECODING;Descodificando archivo RAW... +PROGRESSBAR_DEMOSAICING;Interpolando mosaico... +PROGRESSBAR_LOADING;Abriendo imagen... +PROGRESSBAR_LOADJPEG;Abriendo archivo JPEG... +PROGRESSBAR_LOADPNG;Abriendo archivo PNG... +PROGRESSBAR_LOADTIFF;Abriendo archivo TIFF... +PROGRESSBAR_PROCESSING;Procesando imagen... +PROGRESSBAR_READY;Listo. +PROGRESSBAR_SAVEJPEG;Guardando archivo JPEG... +PROGRESSBAR_SAVEPNG;Guardando archivo PNG... +PROGRESSBAR_SAVETIFF;Guardando archivo TIFF... +PROGRESSDLG_LOADING;Abriendo archivo... +PROGRESSDLG_PROCESSING;Procesando imagen... +PROGRESSDLG_SAVING;Guardando archivo... +QINFO_FOCALLENGTH;Longitud Focal +QINFO_ISO;ISO +QINFO_LENS;Objetivo +QINFO_NOEXIF;No hay datos EXIF. +SAVEDLG_FILEFORMAT;Formato de archivo +SAVEDLG_JPEGQUAL;Calidad JPEG +SAVEDLG_JPGFILTER;Archivos JPEG +SAVEDLG_PNGCOMPR;Compresión PNG +SAVEDLG_PNGFILTER;Archivos PNG +SAVEDLG_PUTTOQUEUEHEAD;Poner al principio de la cola +SAVEDLG_PUTTOQUEUE;Poner en la cola +SAVEDLG_PUTTOQUEUETAIL;Poner al fin de la cola +SAVEDLG_SAVEIMMEDIATELY;Guardar inmediatamente +SAVEDLG_SAVESPP;Guardar parámetros de procesamiento con la imagen +SAVEDLG_TIFFFILTER;Archivos TIFF +TOOLBAR_TOOLTIP_CROP;Elección de recorte (tecla C) +TOOLBAR_TOOLTIP_HAND;Herramienta mano (tecla N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Elección de línea recta (tecla S) +TOOLBAR_TOOLTIP_WB;Muestrea equilibrio de blancos (tecla W) +TP_CACORRECTION_BLUE;Azul +TP_CACORRECTION_LABEL;Corrección de Aberraciones Cromáticas +TP_CACORRECTION_RED;Rojo +TP_CHMIXER_BLUE;Azul +TP_CHMIXER_GREEN;Verde +TP_CHMIXER_LABEL;Mezclador de Canal +TP_CHMIXER_RED;Rojo +TP_COARSETRAF_DEGREE;Grados: +TP_COARSETRAF_TOOLTIP_HFLIP;Voltear horizontalmente +TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotar a la izquierda +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotar a la derecha +TP_COARSETRAF_TOOLTIP_VFLIP;Voltear verticalmente +TP_COLORBOOST_ACHANNEL;canal "a" +TP_COLORBOOST_AMOUNT;Cantidad +TP_COLORBOOST_AVOIDCOLORCLIP;Evitar Recorte de Colores +TP_COLORBOOST_BCHANNEL;canal "b" +TP_COLORBOOST_CHAB;a & b +TP_COLORBOOST_CHANNEL;Canal +TP_COLORBOOST_CHSEPARATE;independiente +TP_COLORBOOST_ENABLESATLIMITER;Activar Limitador de Saturación +TP_COLORBOOST_LABEL;Aumento de Color +TP_COLORBOOST_SATLIMIT;Límite de Saturación +TP_COLORDENOISE_EDGESENSITIVE;Sensible a bordes +TP_COLORDENOISE_EDGETOLERANCE;Tolerancia de bordes +TP_COLORDENOISE_LABEL;Reducción de Ruido de Color +TP_COLORDENOISE_RADIUS;Radio +TP_COLORSHIFT_BLUEYELLOW;Azul-Amarillo +TP_COLORSHIFT_GREENMAGENTA;Verde-Magenta +TP_COLORSHIFT_LABEL;Cambio de Colores +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Fijar Proporciones: +TP_CROP_GTDIAGONALS;Regla de las diagonales +TP_CROP_GTHARMMEANS1;Forma armónica 1 +TP_CROP_GTHARMMEANS2;Forma armónica 2 +TP_CROP_GTHARMMEANS3;Forma armónica 3 +TP_CROP_GTHARMMEANS4;Forma armónica 4 +TP_CROP_GTNONE;Ninguna +TP_CROP_GTRULETHIRDS;Regla de los tercios +TP_CROP_GUIDETYPE;Clase de Guía: +TP_CROP_H;Al +TP_CROP_LABEL;Recortar +TP_CROP_SELECTCROP; Seleccionar Recorte +TP_CROP_W;An +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Cantidad +TP_DISTORTION_LABEL;Distorsión +TP_EXPOSURE_AUTOLEVELS;Niveles Automáticos +TP_EXPOSURE_BLACKLEVEL;Negro +TP_EXPOSURE_BRIGHTNESS;Brillo +TP_EXPOSURE_CLIP;Recorte +TP_EXPOSURE_COMPRHIGHLIGHTS;Compresión de Luces Altas +TP_EXPOSURE_COMPRSHADOWS;Compresión de Sombras +TP_EXPOSURE_CONTRAST;Contraste +TP_EXPOSURE_CURVEEDITOR;Curva de Tono +TP_EXPOSURE_EXPCOMP;Comp. de Expos. +TP_EXPOSURE_LABEL;Exposición +TP_HLREC_CIELAB;Superposición de CIELab +TP_HLREC_COLOR;Propagación de Color +TP_HLREC_LABEL;Recuperación de Luces Altas +TP_HLREC_LUMINANCE;Recuperación de Luminancia +TP_HLREC_METHOD;Método: +TP_ICM_FILEDLGFILTERANY;Cualquier Archivo +TP_ICM_FILEDLGFILTERICM;Archivos de Perfiles ICC +TP_ICM_GAMMABEFOREINPUT;El Perfil aplica Gamma +TP_ICM_INPUTCAMERA;Valores predeterminados de la cámara +TP_ICM_INPUTCUSTOM;A Medida +TP_ICM_INPUTDLGLABEL;Seleccionar perfil ICC de entrada... +TP_ICM_INPUTEMBEDDED;Usar Incrustado, si es posible +TP_ICM_INPUTPROFILE;Perfil de Entrada +TP_ICM_LABEL;GIC +TP_ICM_NOICM;Ningún MIC: Salida sRGB +TP_ICM_OUTPUTDLGLABEL;Seleccionar perfil ICC de salida... +TP_ICM_OUTPUTPROFILE;Perfil de Salida +TP_ICM_SAVEREFERENCE;Guardar imagen de referencia para el perfilado +TP_ICM_WORKINGPROFILE;Perfil de Trabajo +TP_LUMACURVE_BLACKLEVEL;Negro +TP_LUMACURVE_BRIGHTNESS;Brillo +TP_LUMACURVE_COMPRHIGHLIGHTS;Compresión de Luces Altas +TP_LUMACURVE_COMPRSHADOWS;Compresión de Sombras +TP_LUMACURVE_CONTRAST;Contraste +TP_LUMACURVE_CURVEEDITOR;Curva de Luminancia +TP_LUMACURVE_LABEL;Curva de Luminancia +TP_LUMADENOISE_EDGETOLERANCE;Tolerancia de bordes +TP_LUMADENOISE_LABEL;Reducción de Ruido de Luminancia +TP_LUMADENOISE_RADIUS;Radio +TP_RESIZE_BICUBIC;Bicúbica +TP_RESIZE_BICUBICSF;Bicúbica (Más suave) +TP_RESIZE_BICUBICSH;Bicúbica (Más enfocado) +TP_RESIZE_BILINEAR;Bilineal +TP_RESIZE_FULLSIZE;Tamaño de imagen completo: +TP_RESIZE_H;Al: +TP_RESIZE_LABEL;Cambiar Tamaño +TP_RESIZE_METHOD;Método: +TP_RESIZE_NEAREST;Más cercano +TP_RESIZE_SCALE;Escala +TP_RESIZE_W;An: +TP_ROTATE_AUTOCROP;Recorte Automático +TP_ROTATE_DEGREE;Grados +TP_ROTATE_FILL;Llenar +TP_ROTATE_LABEL;Rotar +TP_ROTATE_SELECTLINE; Seleccionar Línea Recta +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Luces Altas +TP_SHADOWSHLIGHTS_HLTONALW;Ancho Tonal +TP_SHADOWSHLIGHTS_LABEL;Sombras/Luces Altas +TP_SHADOWSHLIGHTS_LOCALCONTR;Constraste Local +TP_SHADOWSHLIGHTS_RADIUS;Radio +TP_SHADOWSHLIGHTS_SHADOWS;Sombras +TP_SHADOWSHLIGHTS_SHTONALW;Ancho Tonal +TP_SHARPENING_AMOUNT;Cantidad +TP_SHARPENING_EDRADIUS;Radio +TP_SHARPENING_EDTOLERANCE;Tolerancia de Bordes +TP_SHARPENING_HALOCONTROL;Control de Halo +TP_SHARPENING_HCAMOUNT;Cantidad +TP_SHARPENING_LABEL;Enfoque +TP_SHARPENING_METHOD;Método +TP_SHARPENING_ONLYEDGES;Enfocar solo Bordes +TP_SHARPENING_RADIUS;Radio +TP_SHARPENING_RLD_AMOUNT;Cantidad +TP_SHARPENING_RLD_DAMPING;Amortiguación +TP_SHARPENING_RLD;Deconvolución RL +TP_SHARPENING_RLD_ITERATIONS;Reiteraciones +TP_SHARPENING_THRESHOLD;Umbral +TP_SHARPENING_USM;Máscara de enfoque +TP_VIGNETTING_AMOUNT;Cantidad +TP_VIGNETTING_LABEL;Corrección de viñeteo +TP_VIGNETTING_RADIUS;Radio +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Cámara +TP_WBALANCE_CUSTOM;A Medida +TP_WBALANCE_GREEN;Tinte +TP_WBALANCE_LABEL;Equilibrio de Blancos +TP_WBALANCE_METHOD;Método +TP_WBALANCE_SIZE;Tamaño: +TP_WBALANCE_SPOTWB;Muestra Eq.Bl. +TP_WBALANCE_TEMPERATURE;Temperatura +ZOOMBAR_DETAIL;Detalle +ZOOMBAR_HUGE;Enorme +ZOOMBAR_LARGE;Grande +ZOOMBAR_NORMAL;Normal +ZOOMBAR_PREVIEW;Previsualización +ZOOMBAR_SCALE;Escala +ZOOMBAR_SMALL;Pequeño + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Euskara b/rtdata/languages/Euskara new file mode 100644 index 000000000..057ae0308 --- /dev/null +++ b/rtdata/languages/Euskara @@ -0,0 +1,703 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# Euskara (Basque) +# 03.03.2008 +# Ioritz Ibarguren +ADJUSTER_RESET_TO_DEFAULT;Hasierako balioetara itzuli +CURVEEDITOR_FILEDLGFILTERANY;Artxibo guztiak +CURVEEDITOR_FILEDLGFILTERCURVE;Kurba artxiboak +CURVEEDITOR_LINEAR;Lineala +CURVEEDITOR_LOADDLGLABEL;Kurba ireki... +CURVEEDITOR_SAVEDLGLABEL;Kurba gorde... +CURVEEDITOR_TOOLTIPLINEAR;Kurba lineala berrabiarazi +CURVEEDITOR_TOOLTIPLOAD;Artxibo batetik kurba ireki +CURVEEDITOR_TOOLTIPSAVE;Uneko kurba gorde +EXIFFILTER_APERTURE;Aperture +EXIFFILTER_CAMERA;Camera +EXIFFILTER_DIALOGLABEL;Exif Filter +EXIFFILTER_FOCALLEN;Focal Length +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Lens +EXIFFILTER_SHUTTER;Shutter +EXIFPANEL_ADDEDIT;Add/Edit +EXIFPANEL_ADDEDITHINT;Add new tag or edit tag +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Enter value +EXIFPANEL_ADDTAGDLG_SELECTTAG;Select tag +EXIFPANEL_ADDTAGDLG_TITLE;Add/Edit Tag +EXIFPANEL_KEEPHINT;Keep the selected tags when writing output file +EXIFPANEL_KEEP;Keep +EXIFPANEL_REMOVEHINT;Remove the selected tags when writing output file +EXIFPANEL_REMOVE;Remove +EXIFPANEL_RESETALLHINT;Reset all tags to their original values +EXIFPANEL_RESETALL;Reset All +EXIFPANEL_RESETHINT;Reset the selected tags to their original values +EXIFPANEL_RESET;Reset +EXIFPANEL_SUBDIRECTORY;Subdirectory +FILEBROWSER_APPLYPROFILE;Apply profile +FILEBROWSER_ARRANGEMENTHINT;Change between vertical/horizontal alignment of thumbnails +FILEBROWSER_CLEARPROFILE;Clear profile +FILEBROWSER_COPYPROFILE;Copy profile +FILEBROWSER_DELETEDLGLABEL;File delete confirmation +FILEBROWSER_DELETEDLGMSG;Are you sure you want to delete the selected %1 files? +FILEBROWSER_EMPTYTRASH;Empty Trash +FILEBROWSER_EMPTYTRASHHINT;Permanently delete the files of the trash +FILEBROWSER_EXIFFILTERAPPLY;Apply +FILEBROWSER_EXIFFILTERAPPLYHINT;Switch on/off exif filter of the file browser +FILEBROWSER_EXIFFILTERLABEL;Exif Filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Change settings of the exif filter +FILEBROWSER_EXIFFILTERSETTINGS;Setup +FILEBROWSER_PARTIALPASTEPROFILE;Partial paste +FILEBROWSER_PASTEPROFILE;Paste profile +FILEBROWSER_POPUPCANCELJOB;Cancel job +FILEBROWSER_POPUPMOVEEND;Move to end of queue +FILEBROWSER_POPUPMOVEHEAD;Move to head of queue +FILEBROWSER_POPUPOPEN;Open +FILEBROWSER_POPUPPROCESS;Put to processing queue +FILEBROWSER_POPUPRANK1;Rank 1 +FILEBROWSER_POPUPRANK2;Rank 2 +FILEBROWSER_POPUPRANK3;Rank 3 +FILEBROWSER_POPUPRANK4;Rank 4 +FILEBROWSER_POPUPRANK5;Rank 5 +FILEBROWSER_POPUPREMOVE;Remove from filesystem +FILEBROWSER_POPUPRENAME;Rename +FILEBROWSER_POPUPSELECTALL;Select all +FILEBROWSER_POPUPTRASH;Move to trash +FILEBROWSER_POPUPUNRANK;Unrank +FILEBROWSER_POPUPUNTRASH;Remove from trash +FILEBROWSER_PROCESSINGSETTINGSHINT;Set the file format and output directory +FILEBROWSER_PROCESSINGSETTINGS;Settings +FILEBROWSER_RENAMEDLGLABEL;Rename file +FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +FILEBROWSER_SHOWDIRHINT;Show all images of the directory +FILEBROWSER_SHOWQUEUEHINT;Show content of the processing queue +FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1 star +FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2 star +FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3 star +FILEBROWSER_SHOWRANK4HINT;Show images ranked as 4 star +FILEBROWSER_SHOWRANK5HINT;Show images ranked as 5 star +FILEBROWSER_SHOWTRASHHINT;Show content of the trash +FILEBROWSER_SHOWUNRANKHINT;Show unranked images +FILEBROWSER_STARTPROCESSINGHINT;Start processing/saving of images in the queue +FILEBROWSER_STARTPROCESSING;Start Processing +FILEBROWSER_STOPPROCESSINGHINT;Stop processing of images +FILEBROWSER_STOPPROCESSING;Stop processing +FILEBROWSER_THUMBSIZE;Thumb. size +FILEBROWSER_ZOOMINHINT;Increase thumbnail size +FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size +GENERAL_ABOUT;Honi buruz +GENERAL_CANCEL;Baztertu +GENERAL_DISABLED;Ezeztatua +GENERAL_DISABLE;Ezestatu +GENERAL_ENABLED;Gaitua +GENERAL_ENABLE;Gaitu +GENERAL_LANDSCAPE;Paisaia +GENERAL_LOAD;Ireki +GENERAL_NA;n/a +GENERAL_NO;Ez +GENERAL_OK;Onartu +GENERAL_PORTRAIT;Erretratua +GENERAL_SAVE;Gorde +GENERAL_YES;Bai +HISTOGRAM_LABEL;Histogram +HISTOGRAM_TOOLTIP_B;Erakutsi/Ezkutatu urdin histograma +HISTOGRAM_TOOLTIP_G;Erakutsi/Ezkutatu berde histograma +HISTOGRAM_TOOLTIP_L;Erakutsi/Ezkutatu CIELAB argitasun histograma +HISTOGRAM_TOOLTIP_R;Erakutsi/Ezkutatu gorri histograma +HISTORY_CHANGED;Changed +HISTORY_CUSTOMCURVE;Neurriko kurba +HISTORY_DELSNAPSHOT;Argazkia kendu +HISTORY_FROMCLIPBOARD;From clipboard +HISTORY_LABEL;Historia +HISTORY_MSG_10;Itzal konpresioa +HISTORY_MSG_11;Tonu kurba +HISTORY_MSG_12;Auto-esposizioa +HISTORY_MSG_13;Esposizio mozketa +HISTORY_MSG_14;Liminantzia argitasuna +HISTORY_MSG_15;Luminantzia kontrastea +HISTORY_MSG_16;Luminantzia beltza +HISTORY_MSG_17;Liminantzia argi konpresioa +HISTORY_MSG_18;Luminantzia itzal konpresioa +HISTORY_MSG_19;Luminantzia kurba +HISTORY_MSG_1;Argazki irekia +HISTORY_MSG_20;Fokatzea +HISTORY_MSG_21;Fokatze erradioa +HISTORY_MSG_22;Fokatze kopurua +HISTORY_MSG_23;Fokatze muga +HISTORY_MSG_24;Ertzak bakarrik fokatu +HISTORY_MSG_25;Ertz detekzio erradio fokatzea +HISTORY_MSG_26;Ertz tolerantzia fokatzea +HISTORY_MSG_27;Halo kontrol fokatzea +HISTORY_MSG_28;Halo kopuru kontrola +HISTORY_MSG_29;Fokatze metodoa +HISTORY_MSG_2;Profila irekia +HISTORY_MSG_30;Dekonboluzio erradioa +HISTORY_MSG_31;Dekonboluzio kopurua +HISTORY_MSG_32;Dekonboluzio indargetzea +HISTORY_MSG_33;Dekonboluzio iterazioak +HISTORY_MSG_34;Kolore mozketa ekidin +HISTORY_MSG_35;Saturazio mugatzailea +HISTORY_MSG_36;Saturazio muga +HISTORY_MSG_37;Koloreak jaso +HISTORY_MSG_38;Zuri balantze metodoa +HISTORY_MSG_39;Kolore tenperatura +HISTORY_MSG_3;Profila aldatua +HISTORY_MSG_40;Zuri balantze tonua +HISTORY_MSG_41;"A" kolore aldaketa +HISTORY_MSG_42;"B" kolore aldaketa +HISTORY_MSG_43;Luminantzia zarata murrizketa +HISTORY_MSG_44;Lum. zar. murr. erradioa +HISTORY_MSG_45;Lum. zar. murr. ertz tolerantzia +HISTORY_MSG_46;Kolore zarata murrizketa +HISTORY_MSG_47;Kol. zar. murr. erradioa +HISTORY_MSG_48;Kol. zar. murr. ertz tolerantzia +HISTORY_MSG_49;Kol. zar. murr. ertzekiko sentikorra +HISTORY_MSG_4;Historia arakatu +HISTORY_MSG_50;Itzal/Argi tresna +HISTORY_MSG_51;Argiak jaso +HISTORY_MSG_52;Itzalak jaso +HISTORY_MSG_53;Argi tonu zabalera +HISTORY_MSG_54;Itzal tonu zabalera +HISTORY_MSG_55;Tokiko kontrastea +HISTORY_MSG_56;Itzal/Argi erradioa +HISTORY_MSG_57;Biraketa arrunta +HISTORY_MSG_58;Horizontalki irauli +HISTORY_MSG_59;Bertikalki irauli +HISTORY_MSG_5;Argitasuna +HISTORY_MSG_60;Biraketa +HISTORY_MSG_61;Biraketa +HISTORY_MSG_62;Objetibo deformazio zuzenketa +HISTORY_MSG_63;Lastermarka hautatua +HISTORY_MSG_64;Argazkia moztu +HISTORY_MSG_65;C/A zuzenketa +HISTORY_MSG_66;Distira berreskurapena +HISTORY_MSG_67;Distira berreskurapen kopurua +HISTORY_MSG_68;Distira berreskurapen metodoa +HISTORY_MSG_69;Lan kolore esparrua +HISTORY_MSG_6;Kontrastea +HISTORY_MSG_70;Irteera kolore esparrua +HISTORY_MSG_71;Sarrera kolore esparrua +HISTORY_MSG_72;Iluntze zuzenketa +HISTORY_MSG_73;Kanal nahastainlea +HISTORY_MSG_74;Eskala tamaina aldaketa +HISTORY_MSG_75;Tamaina aldaketa metodoa +HISTORY_MSG_76;Exif Metadata +HISTORY_MSG_77;IPTC Metadata +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;Beltza +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;Esposizio konpentsazioa +HISTORY_MSG_9;Argi konpresioa +HISTORY_NEWSNAPSHOT;Argazki berria +HISTORY_NEWSNAPSHOTAS;Honela... +HISTORY_NEWSSDIALOGLABEL;Argazkiaren etiketa: +HISTORY_NEWSSDIALOGTITLE;Argazki berria gehitu +HISTORY_SETTO;Honetara doitua +HISTORY_SNAPSHOT;Argazkia +HISTORY_SNAPSHOTS;Argazkiak +ICMPANEL_FILEDLGFILTERANY;Artxibo guztiak +ICMPANEL_FILEDLGFILTERICM;ICC profilen artxiboak +ICMPANEL_GAMMABEFOREINPUT;Profile applies Gamma +ICMPANEL_INPUTCAMERA;Kameraren jatorrizko balioak +ICMPANEL_INPUTCUSTOM;Neurrira +ICMPANEL_INPUTDLGLABEL;Sarrerako ICC profila hautatu... +ICMPANEL_INPUTEMBEDDED;Txertatutakoa erabili, egonez gero +ICMPANEL_INPUTPROFILE;Sarrerako profila +ICMPANEL_NOICM;ICM-rik ez: sRGB irteera +ICMPANEL_OUTPUTDLGLABEL;Irteerako ICC profila hautatu... +ICMPANEL_OUTPUTPROFILE;Irteera profila +ICMPANEL_SAVEREFERENCE;Save reference image for profiling +ICMPANEL_WORKINGPROFILE;Lan profila +IMAGEAREA_DETAILVIEW;Zehaztasun bista +IPTCPANEL_AUTHOR;Author +IPTCPANEL_AUTHORHINT;Name of the creator of the object, e.g. writer, photographer or graphic artist (By-line). +IPTCPANEL_AUTHORSPOSITION;Author's position +IPTCPANEL_AUTHORSPOSITIONHINT;Title of the creator or creators of the object (By-line Title). +IPTCPANEL_CAPTION;Caption +IPTCPANEL_CAPTIONHINT;A textual description of the data (Caption - Abstract) +IPTCPANEL_CAPTIONWRITER;Caption Writer +IPTCPANEL_CAPTIONWRITERHINT;The name of the person involved in the writing, editing or correcting the image or caption/abstract (Writer - Editor) +IPTCPANEL_CATEGORY;Category +IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider (Category). +IPTCPANEL_CITY;City +IPTCPANEL_CITYHINT;City of image origin (City). +IPTCPANEL_COPYHINT;Copy IPTC settings to clipboard +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COPYRIGHTHINT;Any necessary copyright notice (Copyright Notice). +IPTCPANEL_COUNTRY;Country +IPTCPANEL_COUNTRYHINT;The name of the country/primary location where the image was created (Country - Primary Location Name). +IPTCPANEL_CREDIT;Credit +IPTCPANEL_CREDITHINT;Identifies the provider of the image, not necessarily the owner/creator (Credit). +IPTCPANEL_DATECREATED;Date Created +IPTCPANEL_DATECREATEDHINT;The date the intellectual content of the image was created; Format: JJJJMMTT (Date Created). +IPTCPANEL_EMBEDDED;Embedded +IPTCPANEL_EMBEDDEDHINT;Reset to IPTC data embedded in the image file +IPTCPANEL_HEADLINE;Headline +IPTCPANEL_HEADLINEHINT;A publishable entry providing a synopsis of the contents of the image (Headline). +IPTCPANEL_INSTRUCTIONSHINT;Other editorial instructions concerning the use of the image (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Instructions +IPTCPANEL_KEYWORDSHINT;Used to indicate specific information retrieval words (Keywords). +IPTCPANEL_KEYWORDS;Keywords +IPTCPANEL_PASTEHINT;Paste IPTC settings from clipboard +IPTCPANEL_PROVINCEHINT;The Province/State where the image originates (Province-State). +IPTCPANEL_PROVINCE;Province +IPTCPANEL_RESETHINT;Reset to profile default +IPTCPANEL_RESET;Reset +IPTCPANEL_SOURCEHINT;The original owner of the intellectual content of the image (Source). +IPTCPANEL_SOURCE;Source +IPTCPANEL_SUPPCATEGORIESHINT;Further refines the subject of the image (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Suppl. Categories +IPTCPANEL_TITLEHINT;A shorthand reference for the image (Object Name). +IPTCPANEL_TITLE;Title +IPTCPANEL_TRANSREFERENCEHINT;A code representing the location of original transmission (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Trans. Reference +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Ezarpenak +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;Honela... +MAIN_BUTTON_SAVE;Irudia gorde +MAIN_BUTTON_SENDTOEDITOR;Send to editor +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Artxiboa jadanik badago. +MAIN_MSG_CANNOTLOAD;Ezin dut irudia ireki +MAIN_MSG_CANNOTSAVE;Errorea irudia gordetzen +MAIN_MSG_CANNOTSTARTEDITOR;Can not start editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Please set the correct path in the "Preferences" dialog. +MAIN_MSG_EXITJOBSINQUEUEINFO;Unprocessed images in the queue will be lost on exit. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Are you sure you want to exit? There are unprocessed images waiting in the queue. +MAIN_MSG_JOBSINQUEUE;lana(k) ilaran +MAIN_MSG_QOVERWRITE;Gainidatzi? +MAIN_TAB_BASIC;Oinarrizkoak +MAIN_TAB_COLOR;Color +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Exposure +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Bihurtu +MAIN_TOOLTIP_HIDEFP;Erakutsi/Ezkutatu behe panela (arakatzailea, shortcut key: F) +MAIN_TOOLTIP_HIDEHP;Erakutsi/Ezkutatu ezker panela (historia, shortcut key: H) +MAIN_TOOLTIP_INDCLIPPEDH;Mozturiko argi adierazlea +MAIN_TOOLTIP_INDCLIPPEDS;Mozturiko itzal adierazlea +MAIN_TOOLTIP_PREFERENCES;Ezarpenak doitu +MAIN_TOOLTIP_QINFO; Irudiaren informazio laburra +MAIN_TOOLTIP_SAVEAS;Irudia hautatutako karpeta batera gorde +MAIN_TOOLTIP_SAVE;Irudia lehenetsiriko karpetara gorde +PARTIALPASTE_BASICGROUP;Basic settings +PARTIALPASTE_CACORRECTION;C/A correction +PARTIALPASTE_COARSETRANS;90 deg rotation / flipping +PARTIALPASTE_COLORBOOST;Color boost +PARTIALPASTE_COLORDENOISE;Color denoise +PARTIALPASTE_COLORGROUP;Color related settings +PARTIALPASTE_COLORMIXER;Color mixer +PARTIALPASTE_COLORSHIFT;Color shift +PARTIALPASTE_COMPOSITIONGROUP;Composition settings +PARTIALPASTE_CROP;Crop +PARTIALPASTE_DIALOGLABEL;Partial paste processing profile +PARTIALPASTE_DISTORTION;Distortion correction +PARTIALPASTE_EXIFCHANGES;Changes to exif data +PARTIALPASTE_EXPOSURE;Exposure +PARTIALPASTE_HLRECOVERY;Highlight recovery +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Lens related settings +PARTIALPASTE_LUMACURVE;Luminance curve +PARTIALPASTE_LUMADENOISE;Luminance noise reduction +PARTIALPASTE_LUMINANCEGROUP;Luminance related settings +PARTIALPASTE_METAICMGROUP;Metadata/ICM settings +PARTIALPASTE_RESIZE;Resize +PARTIALPASTE_ROTATION;Rotation +PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights +PARTIALPASTE_SHARPENING;Sharpening +PARTIALPASTE_VIGNETTING;Vignetting correction +PARTIALPASTE_WHITEBALANCE;White balance +PREFERENCES_APPLNEXTSTARTUP;hurrengo abioan aplikatua +PREFERENCES_BLINKCLIPPED;Moztutako guneak keinuka +PREFERENCES_CACHECLEARALL;Clear All +PREFERENCES_CACHECLEARPROFILES;Clear Profiles +PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +PREFERENCES_CACHEFORMAT1;Proprietary (faster and better quality) +PREFERENCES_CACHEFORMAT2;JPEG (smaller disk footprint) +PREFERENCES_CACHEMAXENTRIES;Maximal Number of Cache Entries +PREFERENCES_CACHEOPTS;Cache Options +PREFERENCES_CACHESTRAT1;Prefer Speed to Low Memory Consumption +PREFERENCES_CACHESTRAT2;Prefer Low Memory Consumption to Speed +PREFERENCES_CACHESTRAT;Cache Strategy +PREFERENCES_CACHETHUMBFORM;Cache Thumbnail Format +PREFERENCES_CACHETHUMBHEIGHT;Maximal Thumbnail Height +PREFERENCES_CLEARDLG_LINE1;Clearing cache +PREFERENCES_CLEARDLG_LINE2;This may take a few seconds. +PREFERENCES_CLEARDLG_TITLE;Please wait +PREFERENCES_CLIPPINGIND;Itzal/argi moztuen adierazlea +PREFERENCES_CMETRICINTENT;Saiakera kolorimetrikoa +PREFERENCES_DATEFORMAT;Data formatua +PREFERENCES_DATEFORMATHINT;You can use the following formatting strings:\n%y : year\n%m : month\n%d : day\n\nFor example, the hungarian date format is:\n%y/%m/%d +PREFERENCES_DEFAULTLANG;Hizkuntza +PREFERENCES_DEFAULTTHEME;Default theme +PREFERENCES_DEMOSAICINGALGO;Demosaikatze algoritmoa +PREFERENCES_DIRHOME;Etxe karpeta +PREFERENCES_DIRLAST;Azkena ikusitako karpeta +PREFERENCES_DIROTHER;Besterik +PREFERENCES_DIRSELECTDLG;Abioko irudien karpeta hautatu... +PREFERENCES_DIRSOFTWARE;Inatalazio karpeta +PREFERENCES_DMETHOD;Metodoa +PREFERENCES_EDITORCMDLINE;Other command line +PREFERENCES_EXTERNALEDITOR;External editor +PREFERENCES_FALSECOLOR;Okerreko kolore ezabaketa atalak +PREFERENCES_FBROWSEROPTS;Arakatzailearen aukerak +PREFERENCES_FILEFORMAT;Artxiboen formatua +PREFERENCES_FORIMAGE;Irudi artxiboetarako +PREFERENCES_FORRAW;RAW artxiboetarako +PREFERENCES_GIMPPATH;GIMP installation directory +PREFERENCES_GTKTHEME;GTK default +PREFERENCES_HINT;Gomendioa +PREFERENCES_HLTHRESHOLD;Moztutako argien muga +PREFERENCES_ICCDIR;ICC profilen karpeta +PREFERENCES_IMPROCPARAMS;Irudi prozesurako aukera lehenetsiak +PREFERENCES_INTENT_ABSOLUTE;Kolorimetriko absolutua +PREFERENCES_INTENT_PERCEPTUAL;Petzeptuala +PREFERENCES_INTENT_RELATIVE;Kolorimetriko erlatiboa +PREFERENCES_INTENT_SATURATION;Saturazioa +PREFERENCES_LIVETHUMBNAILS;Live Thumbnails (slower) +PREFERENCES_MONITORICC;Pantaila profilak +PREFERENCES_OUTDIRFOLDERHINT;Put the saved images to the seledted folder +PREFERENCES_OUTDIRFOLDER;Save to folder +PREFERENCES_OUTDIRHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIR;Irteera karpeta +PREFERENCES_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Use Template +PREFERENCES_PARSEDEXTADD;Add Extension +PREFERENCES_PARSEDEXTADDHINT;Type an extension and press this button to append list +PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list +PREFERENCES_PARSEDEXT;Parsed Extensions +PREFERENCES_PROFILEHANDLING;Processing Profile Handling +PREFERENCES_PROFILELOADPR;Profile Loading Priority +PREFERENCES_PROFILEPRCACHE;Profile in Cache +PREFERENCES_PROFILEPRFILE;Profile Next to the Input File +PREFERENCES_PROFILESAVECACHE;Save Processing Parameters to the Cache +PREFERENCES_PROFILESAVEINPUT;Save Processing Parameters Next to the Input File +PREFERENCES_PSPATH;Adobe Photoshop installation directory +PREFERENCES_SELECTICCDIRDLG;ICC profilen carpeta hautatu... +PREFERENCES_SELECTLANG;Hizkuntza hautatu +PREFERENCES_SELECTMONITORPROFDLG;Pantaila profilen karpeta hautatu... +PREFERENCES_SELECTTHEME;Select theme +PREFERENCES_SHOWBASICEXIF;Oinarrizko EXIF datuak bistaratu +PREFERENCES_SHOWDATETIME;Data eta ordua bistratu +PREFERENCES_SHOWONLYRAW;RAW artxiboak bakarrik erakutsi +PREFERENCES_SHTHRESHOLD;Moztutako itzalen muga +PREFERENCES_STARTUPIMDIR;Abioako irudien karpeta +PREFERENCES_TAB_BROWSER;Artxibo arakatzailea +PREFERENCES_TAB_COLORMGR;Kolore kudeaketa +PREFERENCES_TAB_GENERAL;Orokorra +PREFERENCES_TAB_IMPROC;Irudien prozesua +PREFERENCES_TAB_OUTPUT;Irteera aukerak +PREFERENCES_THUMBSIZE;Miniaturen tamaina +PROFILEPANEL_FILEDLGFILTERANY;Artxibo guztiak +PROFILEPANEL_FILEDLGFILTERPP;Prozesu profilak +PROFILEPANEL_LABEL;Prozesu profilak +PROFILEPANEL_LOADDLGLABEL;Profilaren aldagaiak ireki... +PROFILEPANEL_PCUSTOM;Neurrira +PROFILEPANEL_PFILE;Artxibotik +PROFILEPANEL_PLASTPHOTO;Azken argazkia +PROFILEPANEL_PLASTSAVED;Gordtako azkena +PROFILEPANEL_PROFILE;Profilak +PROFILEPANEL_SAVEDLGLABEL;Profilaren aldagaiak gorde... +PROFILEPANEL_TOOLTIPCOPY;Copy current profile to clipboard +PROFILEPANEL_TOOLTIPLOAD;Profila artxibotik ireki +PROFILEPANEL_TOOLTIPPASTE; Paste profile from clipboard +PROFILEPANEL_TOOLTIPSAVE;Uneko profila gorde +PROGRESSBAR_DECODING;RAW artxiboa dekodetzen... +PROGRESSBAR_DEMOSAICING;Demosaikatzen... +PROGRESSBAR_LOADING;Irudia ireki... +PROGRESSBAR_LOADJPEG;JPG artxiboa irekitzen... +PROGRESSBAR_LOADPNG;PNG artxiboa irekitzen... +PROGRESSBAR_LOADTIFF;TIFF artxiboa irekitzen... +PROGRESSBAR_PROCESSING;Irudiaren prozesua... +PROGRESSBAR_READY;Prest. +PROGRESSBAR_SAVEJPEG;JPG artxiboa gordetzen... +PROGRESSBAR_SAVEPNG;PNG artxiboa gordetzen... +PROGRESSBAR_SAVETIFF;TIFF artxiboa gordetzen... +PROGRESSDLG_LOADING;Loading file... +PROGRESSDLG_PROCESSING;Processing image... +PROGRESSDLG_SAVING;Saving file... +QINFO_FOCALLENGTH;Fokal luzera +QINFO_ISO;ISO +QINFO_LENS;Lens +QINFO_NOEXIF;Ez dago EXIF daturik. +SAVEDLG_FILEFORMAT;Artxiboaren formatua +SAVEDLG_JPEGQUAL;JPEG kalitatea +SAVEDLG_JPGFILTER;JPEG artxiboak +SAVEDLG_PNGCOMPR;PNG konpresioa +SAVEDLG_PNGFILTER;PNG artxiboak +SAVEDLG_PUTTOQUEUEHEAD;Put to the head of the processing queue +SAVEDLG_PUTTOQUEUE;Put into processing queue +SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue +SAVEDLG_SAVEIMMEDIATELY;Save immediately +SAVEDLG_SAVESPP;Prozesu aldagaiak irudiarekin batera gorde +SAVEDLG_TIFFFILTER;TIFF artxiboak +TOOLBAR_TOOLTIP_CROP;Hautapena moztu (shortcut key: C) +TOOLBAR_TOOLTIP_HAND;Esku tresna (shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Lerro zuzena hautatu (shortcut key: S) +TOOLBAR_TOOLTIP_WB;Zuri balantze puntuala (shortcut key: W) +TP_CACORRECTION_BLUE;Urdina +TP_CACORRECTION_LABEL;C/A zuzenketa +TP_CACORRECTION_RED;Gorria +TP_CHMIXER_BLUE;Urdina +TP_CHMIXER_GREEN;Berdea +TP_CHMIXER_LABEL;Kanal nahastailea +TP_CHMIXER_RED;Gorria +TP_COARSETRAF_DEGREE;Graduak: +TP_COARSETRAF_TOOLTIP_HFLIP;Horizontalki irauli +TP_COARSETRAF_TOOLTIP_ROTLEFT;Errotazioa ezkerraldera +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Errotazioa eskunialdera +TP_COARSETRAF_TOOLTIP_VFLIP;Bertikalki irauli +TP_COLORBOOST_ACHANNEL;"a" kanala +TP_COLORBOOST_AMOUNT;Kopurua +TP_COLORBOOST_AVOIDCOLORCLIP;Kolore mozketa ekidin +TP_COLORBOOST_BCHANNEL;"b" kanala +TP_COLORBOOST_CHAB;a & b +TP_COLORBOOST_CHANNEL;Kanala +TP_COLORBOOST_CHSEPARATE;bananduak +TP_COLORBOOST_ENABLESATLIMITER;Saturazio muga gaitu +TP_COLORBOOST_LABEL;Koloreak jaso +TP_COLORBOOST_SATLIMIT;Saturazio muga +TP_COLORDENOISE_EDGESENSITIVE;Ertzetara sentikorra +TP_COLORDENOISE_EDGETOLERANCE;Ertz tolerantzia +TP_COLORDENOISE_LABEL;Kolore zarata murrizketa +TP_COLORDENOISE_RADIUS;Erradioa +TP_COLORSHIFT_BLUEYELLOW;Urdin-Horia +TP_COLORSHIFT_GREENMAGENTA;Berde-Magenta +TP_COLORSHIFT_LABEL;Kolore aldaketa +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Erlazio finkoa: +TP_CROP_GTDIAGONALS;Diagonalen erregela +TP_CROP_GTHARMMEANS1;Bataz besteko armonikoa 1 +TP_CROP_GTHARMMEANS2;Bataz besteko armonikoa 2 +TP_CROP_GTHARMMEANS3;Bataz besteko armonikoa 3 +TP_CROP_GTHARMMEANS4;Bataz besteko armonikoa 4 +TP_CROP_GTNONE;Bat ere ez +TP_CROP_GTRULETHIRDS;Herenen erregela +TP_CROP_GUIDETYPE;Gida mota: +TP_CROP_H;H +TP_CROP_LABEL;Moztu +TP_CROP_SELECTCROP; Mozketa hautatu +TP_CROP_W;W +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Kopurua +TP_DISTORTION_LABEL;Distortsioa +TP_EXPOSURE_AUTOLEVELS;Maila auto. +TP_EXPOSURE_BLACKLEVEL;Beltza +TP_EXPOSURE_BRIGHTNESS;Distira +TP_EXPOSURE_CLIP;Moztu +TP_EXPOSURE_COMPRHIGHLIGHTS;Argi konpresioa +TP_EXPOSURE_COMPRSHADOWS;Itzal konpresioa +TP_EXPOSURE_CONTRAST;Kontrastea +TP_EXPOSURE_CURVEEDITOR;Tonu kurba +TP_EXPOSURE_EXPCOMP;Esp. Konp. +TP_EXPOSURE_LABEL;Esposizioa +TP_HLREC_CIELAB;CIELab Blending +TP_HLREC_COLOR;Kolorearen hedapena +TP_HLREC_LABEL;Distiren berreskurapena +TP_HLREC_LUMINANCE;Argitasun berreskurapena +TP_HLREC_METHOD;Metodoa: +TP_ICM_FILEDLGFILTERANY;Artxibo guztiak +TP_ICM_FILEDLGFILTERICM;ICC profilen artxiboak +TP_ICM_GAMMABEFOREINPUT;Profile applies Gamma +TP_ICM_INPUTCAMERA;Kameraren jatorrizko balioak +TP_ICM_INPUTCUSTOM;Neurrira +TP_ICM_INPUTDLGLABEL;Sarrerako ICC profila hautatu... +TP_ICM_INPUTEMBEDDED;Txertatutakoa erabili, egonez gero +TP_ICM_INPUTPROFILE;Sarrerako profila +TP_ICM_LABEL;ICM +TP_ICM_NOICM;ICM-rik ez: sRGB irteera +TP_ICM_OUTPUTDLGLABEL;Irteerako ICC profila hautatu... +TP_ICM_OUTPUTPROFILE;Irteera profila +TP_ICM_SAVEREFERENCE;Save reference image for profiling +TP_ICM_WORKINGPROFILE;Lan profila +TP_LUMACURVE_BLACKLEVEL;Beltza +TP_LUMACURVE_BRIGHTNESS;Distira +TP_LUMACURVE_COMPRHIGHLIGHTS;Argi konpresioa +TP_LUMACURVE_COMPRSHADOWS;Itzal konpresioa +TP_LUMACURVE_CONTRAST;Kontrastea +TP_LUMACURVE_CURVEEDITOR;Argitasun kurba +TP_LUMACURVE_LABEL;Argitasun kurba +TP_LUMADENOISE_EDGETOLERANCE;Ertz tolerantzia +TP_LUMADENOISE_LABEL;Argitasun zarata murrizketa +TP_LUMADENOISE_RADIUS;Erradioa +TP_RESIZE_BICUBIC;Bikubikoa +TP_RESIZE_BICUBICSF;Bikubikoa (Biguna) +TP_RESIZE_BICUBICSH;Bikubikoa (Fokatua) +TP_RESIZE_BILINEAR;Bilineala +TP_RESIZE_FULLSIZE;Irudi tamaina osoa: +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Tamaina aldatu +TP_RESIZE_METHOD;Metodoa: +TP_RESIZE_NEAREST;Gertuena +TP_RESIZE_SCALE;Eskala +TP_RESIZE_W;W: +TP_ROTATE_AUTOCROP;Auto mozketa +TP_ROTATE_DEGREE;Angelua +TP_ROTATE_FILL;Bete +TP_ROTATE_LABEL;Errotazioa +TP_ROTATE_SELECTLINE; Lerro zuzena hautatu +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Argiak +TP_SHADOWSHLIGHTS_HLTONALW;Tonu zabalera +TP_SHADOWSHLIGHTS_LABEL;Itzalak/Argiak +TP_SHADOWSHLIGHTS_LOCALCONTR;Tokiko kontrastea +TP_SHADOWSHLIGHTS_RADIUS;Erradioa +TP_SHADOWSHLIGHTS_SHADOWS;Itzalak +TP_SHADOWSHLIGHTS_SHTONALW;Tonu zabalera +TP_SHARPENING_AMOUNT;Kopurua +TP_SHARPENING_EDRADIUS;Erradioa +TP_SHARPENING_EDTOLERANCE;Ertz tolerantzia +TP_SHARPENING_HALOCONTROL;Halo kontrola +TP_SHARPENING_HCAMOUNT;Kopurua +TP_SHARPENING_LABEL;Fokatu +TP_SHARPENING_METHOD;Metodoa +TP_SHARPENING_ONLYEDGES;Ertzak bakarrik fokatu +TP_SHARPENING_RADIUS;Erradioa +TP_SHARPENING_RLD_AMOUNT;Kopurua +TP_SHARPENING_RLD_DAMPING;Indargetzea +TP_SHARPENING_RLD_ITERATIONS;Iterazioak +TP_SHARPENING_RLD;RL Dekonboluzioa +TP_SHARPENING_THRESHOLD;Muga +TP_SHARPENING_USM;Defokatze maskara +TP_VIGNETTING_AMOUNT;Kopurua +TP_VIGNETTING_LABEL;Iluntze zuzenketa +TP_VIGNETTING_RADIUS;Erradioa +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Camera +TP_WBALANCE_CUSTOM;Pertsonalizatua +TP_WBALANCE_GREEN;Tindua +TP_WBALANCE_LABEL;Zuri balantzea +TP_WBALANCE_METHOD;Metodoa +TP_WBALANCE_SIZE;Tamaina: +TP_WBALANCE_SPOTWB;Z/B Puntuala +TP_WBALANCE_TEMPERATURE;Tenperatura +ZOOMBAR_DETAIL;Xehetasuna +ZOOMBAR_HUGE;Ikaragarria +ZOOMBAR_LARGE;Handia +ZOOMBAR_NORMAL;Arrunta +ZOOMBAR_PREVIEW;Aurrebista +ZOOMBAR_SCALE;Eskala +ZOOMBAR_SMALL;Txikia + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais new file mode 100644 index 000000000..a0a1f2c05 --- /dev/null +++ b/rtdata/languages/Francais @@ -0,0 +1,675 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# Français +# 1.3.2008: Hombre +# 1.5.2008: Hombre: updates for 2.4m1 +# 27.10.2008: Hombre: updates for 2.4b1 +# 18.11.2008: Hombre: updates for 2.4b2 +ADJUSTER_RESET_TO_DEFAULT;Réglages par défaut +CURVEEDITOR_FILEDLGFILTERANY;Tous les fichiers +CURVEEDITOR_FILEDLGFILTERCURVE;Fichiers de courbe +CURVEEDITOR_LINEAR;Linéaire +CURVEEDITOR_LOADDLGLABEL;Charger la courbe... +CURVEEDITOR_SAVEDLGLABEL;Enregistrer la courbe... +CURVEEDITOR_TOOLTIPLINEAR;Réinitialise la courbe en linéaire +CURVEEDITOR_TOOLTIPLOAD;Charger une courbe depuis un fichier +CURVEEDITOR_TOOLTIPSAVE;Enregistrer la courbe actuelle +EXIFFILTER_APERTURE;Ouverture +EXIFFILTER_CAMERA;Appareil photo +EXIFFILTER_DIALOGLABEL;Filtre EXIF +EXIFFILTER_FOCALLEN;Longueur focale +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Optique +EXIFFILTER_SHUTTER;Obturateur +EXIFPANEL_ADDEDIT;Ajouter/Editer +EXIFPANEL_ADDEDITHINT;Ajoute ou édite un tag +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Saisissez une valeur +EXIFPANEL_ADDTAGDLG_SELECTTAG;Choisissez un tag +EXIFPANEL_ADDTAGDLG_TITLE;Ajouter/Editer un tag +EXIFPANEL_KEEP;Conserver +EXIFPANEL_KEEPHINT;Conserve les tags sélectionnés lors de l'écriture du fichier de sortie +EXIFPANEL_REMOVEHINT;Retire les tags sélectionnés lors de l'écriture du fichier de sortie +EXIFPANEL_REMOVE;Retirer +EXIFPANEL_RESETALLHINT;Réinitialise tous les tags à leur valeur initiale +EXIFPANEL_RESETALL;Réinitialiser tout +EXIFPANEL_RESETHINT;Réinitialise les tags séléctionnés à la valeur initiale +EXIFPANEL_RESET;Réinitialiser +EXIFPANEL_SUBDIRECTORY;Sous-répertoire +FILEBROWSER_APPLYPROFILE;Appliquer le profil +FILEBROWSER_ARRANGEMENTHINT;Permuter entre l'alignement vertical/horizontal des vignettes +FILEBROWSER_CLEARPROFILE;Remettre le profil à zéro +FILEBROWSER_COPYPROFILE;Copier le profil +FILEBROWSER_DELETEDLGLABEL;Confirmation de la suppression de fichier +FILEBROWSER_DELETEDLGMSG;Êtes-vous sûr de vouloir supprimer les %1 fichiers selectionnés? +FILEBROWSER_EMPTYTRASHHINT;Supprime définitivement les fichiers de la corbeille +FILEBROWSER_EMPTYTRASH;Vider la corbeille +FILEBROWSER_EXIFFILTERAPPLY;Appliquer +FILEBROWSER_EXIFFILTERAPPLYHINT;Activer/désactiver les filtres EXIF le navigateur de fichier +FILEBROWSER_EXIFFILTERLABEL;Filtre EXIF +FILEBROWSER_EXIFFILTERSETTINGSHINT;Change les réglages du filtre EXIF +FILEBROWSER_EXIFFILTERSETTINGS;Réglages +FILEBROWSER_PARTIALPASTEPROFILE;Coller partiellement +FILEBROWSER_PASTEPROFILE;Coller le profil +FILEBROWSER_POPUPCANCELJOB;Abandonner la file de traitement +FILEBROWSER_POPUPMOVEEND;Déplacer à la fin de la file +FILEBROWSER_POPUPMOVEHEAD;Déplacer en tête de file +FILEBROWSER_POPUPOPEN;Ouvrir +FILEBROWSER_POPUPPROCESS;Mettre dans la file de traitement +FILEBROWSER_POPUPRANK1;1 étoile +FILEBROWSER_POPUPRANK2;2 étoiles +FILEBROWSER_POPUPRANK3;3 étoiles +FILEBROWSER_POPUPRANK4;4 étoiles +FILEBROWSER_POPUPRANK5;5 étoiles +FILEBROWSER_POPUPREMOVE;Retirer du système de fichier +FILEBROWSER_POPUPRENAME;Renommer +FILEBROWSER_POPUPSELECTALL;Sélectionner tout +FILEBROWSER_POPUPTRASH;Déplacer dans la corbeille +FILEBROWSER_POPUPUNRANK;Effacer le rang +FILEBROWSER_POPUPUNTRASH;Retirer de la corbeille +FILEBROWSER_PROCESSINGSETTINGSHINT;Règle le format de fichier et le dossier de sortie +FILEBROWSER_PROCESSINGSETTINGS;Réglages +FILEBROWSER_RENAMEDLGLABEL;Rennommage du fichier +FILEBROWSER_RENAMEDLGMSG;Renommer le fichier "%1" en: +FILEBROWSER_SHOWDIRHINT;Voir toutes les images du dossier +FILEBROWSER_SHOWQUEUEHINT;Voir le contenu de la file de traitement +FILEBROWSER_SHOWRANK1HINT;Voir les images 1 étoile +FILEBROWSER_SHOWRANK2HINT;Voir les images 2 étoiles +FILEBROWSER_SHOWRANK3HINT;Voir les images 3 étoiles +FILEBROWSER_SHOWRANK4HINT;Voir les images 4 étoiles +FILEBROWSER_SHOWRANK5HINT;Voir les images 5 étoiles +FILEBROWSER_SHOWTRASHHINT;Voir le contenu de la corbeille +FILEBROWSER_SHOWUNRANKHINT;Voir les images sans étoile +FILEBROWSER_STARTPROCESSING;Démarrer le traitement +FILEBROWSER_STARTPROCESSINGHINT;Démarre le traitement/sauvegarde des images dans la file +FILEBROWSER_STOPPROCESSING;Arrêter le traitement +FILEBROWSER_STOPPROCESSINGHINT;Arrête le traitement des images +FILEBROWSER_THUMBSIZE;Taille vign. +FILEBROWSER_ZOOMINHINT;Augmenter la taille des vignettes +FILEBROWSER_ZOOMOUTHINT;Diminuer la taille des vignettes +GENERAL_ABOUT;À propos +GENERAL_CANCEL;Annuler +GENERAL_DISABLED;Désactivé +GENERAL_DISABLE;Désactiver +GENERAL_ENABLE;Activer +GENERAL_ENABLED;Activé +GENERAL_LANDSCAPE;Paysage +GENERAL_LOAD;Charger +GENERAL_NA;indisponible +GENERAL_NO;Non +GENERAL_OK;OK +GENERAL_PORTRAIT;Portrait +GENERAL_SAVE;Enregistrer +GENERAL_YES;Oui +HISTOGRAM_LABEL;Histogramme +HISTOGRAM_TOOLTIP_B;Montrer/cacher l'histogramme BLEU +HISTOGRAM_TOOLTIP_G;Montrer/cacher l'histogramme VERT +HISTOGRAM_TOOLTIP_L;Montrer/cacher l'histogramme Luminance CIELAB +HISTOGRAM_TOOLTIP_R;Montrer/cacher l'histogramme ROUGE +HISTORY_CHANGED;Changé +HISTORY_CUSTOMCURVE;Courbe personnelle +HISTORY_DELSNAPSHOT;Supprimer +HISTORY_FROMCLIPBOARD;Du presse-papier +HISTORY_LABEL;Historique +HISTORY_MSG_10;Compression des ombres +HISTORY_MSG_11;Courbe tonale +HISTORY_MSG_12;Exposition auto +HISTORY_MSG_13;Rognage de l'exposition +HISTORY_MSG_14;Luminance - Luminosité +HISTORY_MSG_15;Luminance - Contraste +HISTORY_MSG_16;Luminance - Noir +HISTORY_MSG_17;Luminance - Compression Hautes lumières +HISTORY_MSG_18;Luminance - Compression des Ombres +HISTORY_MSG_19;Luminance - Courbe +HISTORY_MSG_1;Photo chargée +HISTORY_MSG_20;Netteté +HISTORY_MSG_21;Netteté - Rayon +HISTORY_MSG_22;Netteté - Quantité +HISTORY_MSG_23;Netteté - Seuil +HISTORY_MSG_24;Netteté - Améliorer seulement les bords +HISTORY_MSG_25;Netteté - Amélio. bords - Rayon +HISTORY_MSG_26;Netteté - Amélio. bords - Tolérance +HISTORY_MSG_27;Netteté - Contrôle du halo +HISTORY_MSG_28;Netteté - Contrôle du halo - Quantité +HISTORY_MSG_29;Méthode d'amélioration de la netteté +HISTORY_MSG_2;Profil chargé +HISTORY_MSG_30;Déconvolution - Rayon +HISTORY_MSG_31;Déconvolution - Quantité +HISTORY_MSG_32;Déconvolution - Amortissement +HISTORY_MSG_33;Déconvolution - Itérations +HISTORY_MSG_34;Éviter l'écrêtage couleur +HISTORY_MSG_35;Limiteur de saturation +HISTORY_MSG_36;Limite de saturation +HISTORY_MSG_37;Rehaussement couleur +HISTORY_MSG_38;Méthode de balance des blancs +HISTORY_MSG_39;Température de couleur +HISTORY_MSG_3;Profil changé +HISTORY_MSG_40;Teinte de balance des blancs +HISTORY_MSG_41;Décalage couleur "A" +HISTORY_MSG_42;Décalage couleur "B" +HISTORY_MSG_43;Débruitage de la Luminance +HISTORY_MSG_44;Débruitage Lum. - Rayon +HISTORY_MSG_45;Débruitage Lum. - Tolérance des bords +HISTORY_MSG_46;Débruitage Chromatique +HISTORY_MSG_47;Débruitage Chrom. - Rayon +HISTORY_MSG_48;Débruitage Chrom. - Tolérance des bords +HISTORY_MSG_49;Débruitage Chrom. - Sensible aux bords +HISTORY_MSG_4;Navigation dans l'historique +HISTORY_MSG_50;Outil Ombres/Hautes lumières +HISTORY_MSG_51;Accentuation des hautes lumières +HISTORY_MSG_52;Accentuation des ombres +HISTORY_MSG_53;Amplitude tonale des hautes lumières +HISTORY_MSG_54;Amplitude tonale des ombres +HISTORY_MSG_55;Contraste Local +HISTORY_MSG_56;Ombres/Hautes lumières - Rayon +HISTORY_MSG_57;Rotation grossière +HISTORY_MSG_58;Symétrisation / axe vertical +HISTORY_MSG_59;Symétrisation / axe horizontal +HISTORY_MSG_5;Luminosité +HISTORY_MSG_60;Rotation +HISTORY_MSG_61;Rotation +HISTORY_MSG_62;Correction de la distorsion +HISTORY_MSG_63;Signet sélectionné +HISTORY_MSG_64;Rognage de la Photo +HISTORY_MSG_65;Correction de l'aberration chromatique +HISTORY_MSG_66;Récup. Hautes lumières +HISTORY_MSG_67;Récup. Hautes lumières - Quantité +HISTORY_MSG_68;Récup. Hautes lumières - Méthode +HISTORY_MSG_69;Espace de couleur de travail +HISTORY_MSG_6;Contraste +HISTORY_MSG_70;Espace de couleur de sortie +HISTORY_MSG_71;Espace de couleur d'entrée +HISTORY_MSG_72;Correction du vignetage +HISTORY_MSG_73;Mixage des canaux +HISTORY_MSG_74;Echelle de redimensionnement +HISTORY_MSG_75;Méthode de redimensionnement +HISTORY_MSG_76;Métadonnées EXIF +HISTORY_MSG_77;Métadonnées IPTC +HISTORY_MSG_78;Données spécifiées pour redimensionnement +HISTORY_MSG_79;Redimensionner la largeur +HISTORY_MSG_7;Noir +HISTORY_MSG_80;Redimensionner la hauteur +HISTORY_MSG_81;Redimensionnement activé +HISTORY_MSG_8;Compensation d'exposition +HISTORY_MSG_9;Compression des hautes lumières +HISTORY_NEWSNAPSHOT;Ajouter +HISTORY_NEWSNAPSHOTAS;Sous... +HISTORY_NEWSSDIALOGLABEL;Label de la capture: +HISTORY_NEWSSDIALOGTITLE;Ajouter une nouvelle capture +HISTORY_SETTO;Réglé à +HISTORY_SNAPSHOT;Capture +HISTORY_SNAPSHOTS;Captures +ICMPANEL_FILEDLGFILTERANY;Tous les fichiers +ICMPANEL_FILEDLGFILTERICM;Fichiers de profil ICC +ICMPANEL_GAMMABEFOREINPUT;Appliquer le amma du profil +ICMPANEL_INPUTCAMERA;Celui de l'appareil photo +ICMPANEL_INPUTCUSTOM;Personnel +ICMPANEL_INPUTDLGLABEL;Choix du profil ICC d'entrée... +ICMPANEL_INPUTEMBEDDED;Utiliser celui inclus, si possible +ICMPANEL_INPUTPROFILE;Profil d'entrée +ICMPANEL_NOICM;Pas d'ICM: sortie sRGB +ICMPANEL_OUTPUTDLGLABEL;Choix du profil ICC de sortie... +ICMPANEL_OUTPUTPROFILE;Profil de sortie +ICMPANEL_SAVEREFERENCE;Utiliser l'image comme profil de référence +ICMPANEL_WORKINGPROFILE;Profil de travail +IMAGEAREA_DETAILVIEW;Vue de détail +IPTCPANEL_AUTHOR;Auteur +IPTCPANEL_AUTHORHINT;Nom du créateur de l'objet, p.ex. le rédacteur, le photographe ou le graphiste (By-line). +IPTCPANEL_AUTHORSPOSITIONHINT;Statut du ou des créateurs de l'objet (By-line Title). +IPTCPANEL_AUTHORSPOSITION;Statut de l'auteur +IPTCPANEL_CAPTIONHINT;Une description explicite de la donnée (Légende - Résumé) +IPTCPANEL_CAPTION;Légende +IPTCPANEL_CAPTIONWRITER;Auteur de la légende +IPTCPANEL_CAPTIONWRITERHINT;Le nom de la personne ayant rédigé, édité ou corrigé l'image ou la légende/résumé (Auteur - Editeur). +IPTCPANEL_CATEGORY;Catégorie +IPTCPANEL_CATEGORYHINT;Identifie le sujet de l'image selon l'avis du fournisseur (Catégorie). +IPTCPANEL_CITYHINT;Ville d'origine de l'image (Ville). +IPTCPANEL_CITY;Ville +IPTCPANEL_COPYHINT;Copie les réglages IPTC dans le presse-papier +IPTCPANEL_COPYRIGHT;Droit de copie +IPTCPANEL_COPYRIGHTHINT;Toute remarque nécessaire de droit de copie (Remarque droit de copie). +IPTCPANEL_COUNTRYHINT;Le nom du pays de la ville principale où l'image a été créée (Pays - Nom de la ville principale). +IPTCPANEL_COUNTRY;Pays +IPTCPANEL_CREDIT;Crédit +IPTCPANEL_CREDITHINT;Identifie le fournisseur de l'image, pas nécessairement le propriétaire/créateur (Crédit). +IPTCPANEL_DATECREATED;Date de création +IPTCPANEL_DATECREATEDHINT;La date de création du contenu intellectuel de l'image; Format: AAAAMMJJ (Date de création). +IPTCPANEL_EMBEDDEDHINT;Réinitialise selon les données IPTC incorporées dans le fichier image +IPTCPANEL_EMBEDDED;Incorporés +IPTCPANEL_HEADLINEHINT;Une entrée publiable fournissant un synopsis du contenu de l'image (Titre). +IPTCPANEL_HEADLINE;Titre +IPTCPANEL_INSTRUCTIONSHINT;Autres instructions éditoriales concernant l'utilisation de l'image (Instructions spéciales). +IPTCPANEL_INSTRUCTIONS;Instructions +IPTCPANEL_KEYWORDSHINT;Utilisé pour spécifier des mots clés de recherches (Mots clés). +IPTCPANEL_KEYWORDS;Mots clés +IPTCPANEL_PASTEHINT;Colle les réglages IPTC du presse-papier +IPTCPANEL_PROVINCEHINT;La province/état d'où est issue l'image (Province-Etat). +IPTCPANEL_PROVINCE;Province +IPTCPANEL_RESETHINT;Réinitialise selon le profil par défaut +IPTCPANEL_RESET;Réinitialisation +IPTCPANEL_SOURCEHINT;Le propriétaire intellectuel du contenu de l'image (Source). +IPTCPANEL_SOURCE;Source +IPTCPANEL_SUPPCATEGORIES;Catégories suppl. +IPTCPANEL_SUPPCATEGORIESHINT;Précise un peu plus le sujet de l'image (Catégories supplémentaires). +IPTCPANEL_TITLEHINT;Raccourcis de référence de l'image (Nom de l'objet). +IPTCPANEL_TITLE;Titre +IPTCPANEL_TRANSREFERENCEHINT;Un code représentant le lieux de la transmission initiale (Référence de transmission initiale). +IPTCPANEL_TRANSREFERENCE;Réf. transmission +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Préférences +MAIN_BUTTON_QUEUE;Envoyer dans la file +MAIN_BUTTON_SAVEAS;Sous... +MAIN_BUTTON_SAVE;Enregistrer l'image +MAIN_BUTTON_SENDTOEDITOR;Envoyer vers l'éditeur +MAIN_FRAME_BATCHQUEUE;File d'attente +MAIN_FRAME_FILEBROWSER;Explorateur de fichiers +MAIN_FRAME_PLACES_ADD;Ajouter +MAIN_FRAME_PLACES_DEL;Supprimer +MAIN_FRAME_PLACES;Emplacements +MAIN_FRAME_RECENT;Fichiers récents +MAIN_MSG_ALREADYEXISTS;Le fichier existe déjà. +MAIN_MSG_CANNOTLOAD;Impossible de charger l'image +MAIN_MSG_CANNOTSAVE;Erreur d'enregistrement du fichier +MAIN_MSG_CANNOTSTARTEDITOR;Impossible de lancer l'éditeur. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Veuillez saisir son chemin d'accès dans les "Préférences". +MAIN_MSG_EXITJOBSINQUEUEINFO;Les images non traitées seront perdues en quittant l'application +MAIN_MSG_EXITJOBSINQUEUEQUEST;Êtes-vous sûr de vouloir quitter? Il reste dans la file des images en attente de traitement. +MAIN_MSG_JOBSINQUEUE;travail(aux) en file d'attente +MAIN_MSG_QOVERWRITE;Voulez-vous l'écraser? +MAIN_TAB_BASIC;Basique +MAIN_TAB_COLOR;Couleur +MAIN_TAB_DETAIL;Détail +MAIN_TAB_DEVELOP;Développer +MAIN_TAB_EXIF;EXIF +MAIN_TAB_EXPOSURE;Exposition +MAIN_TAB_FILTER;Filtrer +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Métadonnées +MAIN_TAB_TAGGING;Tagguer +MAIN_TAB_TRANSFORM;Transformation +MAIN_TOOLTIP_HIDEFP;Montrer/cacher le panneau inférieur (navigateur de dossiers et de fichiers, touche F) +MAIN_TOOLTIP_HIDEHP;Montrer/cacher le panneau gauche (incluant l'historique, touche H) +MAIN_TOOLTIP_INDCLIPPEDH;Indication hautes lumières hors domaine +MAIN_TOOLTIP_INDCLIPPEDS;Indication ombres hors domaine +MAIN_TOOLTIP_PREFERENCES;Régler les préférences +MAIN_TOOLTIP_QINFO;Infos rapides sur l'image +MAIN_TOOLTIP_SAVEAS;Enregistrer l'image dans un dossier de son choix +MAIN_TOOLTIP_SAVE;Enregistrer l'image dans le dossier par défaut +PARTIALPASTE_BASICGROUP;Réglages de base +PARTIALPASTE_CACORRECTION;Correction aberr./chrom. +PARTIALPASTE_COARSETRANS;Rotation de 90° / symétrisation +PARTIALPASTE_COLORBOOST;Réhaussement couleur +PARTIALPASTE_COLORDENOISE;Réduction du bruit chromatique +PARTIALPASTE_COLORGROUP;Réglages couleurs +PARTIALPASTE_COLORMIXER;Mixage couleur +PARTIALPASTE_COLORSHIFT;Décalage couleur +PARTIALPASTE_COMPOSITIONGROUP;Réglages de la composition +PARTIALPASTE_CROP;Rognage +PARTIALPASTE_DIALOGLABEL;Collage partiel de profil de traitement +PARTIALPASTE_DISTORTION;Correction de distortion +PARTIALPASTE_EXIFCHANGES;Modification des données EXIF +PARTIALPASTE_EXPOSURE;Exposition +PARTIALPASTE_HLRECOVERY;Récupération des hautes lumières +PARTIALPASTE_ICMSETTINGS;Réglages ICM +PARTIALPASTE_IPTCINFO;Infos IPTC +PARTIALPASTE_LENSGROUP;Réglages de l'objectif +PARTIALPASTE_LUMACURVE;Courbe de luminance +PARTIALPASTE_LUMADENOISE;Réduction du bruit de luminance +PARTIALPASTE_LUMINANCEGROUP;Réglages de la luminance +PARTIALPASTE_METAICMGROUP;Réglages des Métadonnées/ICM +PARTIALPASTE_RESIZE;Redimentionnement +PARTIALPASTE_ROTATION;Rotation +PARTIALPASTE_SHADOWSHIGHLIGHTS;Ombres/Hautes lumières +PARTIALPASTE_SHARPENING;Netteté +PARTIALPASTE_VIGNETTING;Correction du vignettage +PARTIALPASTE_WHITEBALANCE;Balance des blancs +PREFERENCES_APPLNEXTSTARTUP;appliqué au prochain lancement +PREFERENCES_BLINKCLIPPED;Faire clignoter les zones hors domaine +PREFERENCES_CACHECLEARALL;Tout nettoyer +PREFERENCES_CACHECLEARPROFILES;Nettoyer les profils +PREFERENCES_CACHECLEARTHUMBS;Nettoyer les vignettes +PREFERENCES_CACHEFORMAT1;Propriétaire (plus rapide et de meilleur qualité) +PREFERENCES_CACHEFORMAT2;JPEG (moins volumineux sur le disque) +PREFERENCES_CACHEMAXENTRIES;Nombre maximal d'éléments dans le Cache +PREFERENCES_CACHEOPTS;Options du Cache +PREFERENCES_CACHESTRAT1;Optimiser la vitesse au détriment de la consommation mémoire +PREFERENCES_CACHESTRAT2;Optimiser la consommation mémoire au détriment de la vitesse +PREFERENCES_CACHESTRAT;Stratégie de gestion du Cache +PREFERENCES_CACHETHUMBFORM;Format des vignettes du Cache +PREFERENCES_CACHETHUMBHEIGHT;Hauteur maximale des vignettes +PREFERENCES_CLEARDLG_LINE1;Nettoyage du Cache +PREFERENCES_CLEARDLG_LINE2;Ceci peut prendre plusieurs secondes. +PREFERENCES_CLEARDLG_TITLE;Veuillez patienter +PREFERENCES_CLIPPINGIND;Indication du dépassement de plage dynamique +PREFERENCES_CMETRICINTENT;Intention Colorimétrique +PREFERENCES_DATEFORMAT;Format de la date +PREFERENCES_DATEFORMATHINT;Vous pouvez utiliser les paramètres de chaînes formatés suivants:\n%y : année\n%m : mois\n%d : jour\n\nPar exemple, le format de date française est:\n%d/%m/%y +PREFERENCES_DEFAULTLANG;Langue par défaut +PREFERENCES_DEFAULTTHEME;Thème par défaut +PREFERENCES_DEMOSAICINGALGO;Algorithme de dématriçage +PREFERENCES_DIRHOME;Racine de mes documents personnels +PREFERENCES_DIRLAST;Dernier dossier visité +PREFERENCES_DIROTHER;Autre +PREFERENCES_DIRSELECTDLG;Choix du dossier Image au lancement... +PREFERENCES_DIRSOFTWARE;Dossier d'installation +PREFERENCES_DMETHOD;Méthode +PREFERENCES_EDITORCMDLINE;Autre ligne de commande +PREFERENCES_EXTERNALEDITOR;Editeur externe +PREFERENCES_FALSECOLOR;Itérations pour la suppression des fausses couleurs +PREFERENCES_FBROWSEROPTS;Options du navigateur de fichiers +PREFERENCES_FILEFORMAT;Format du fichier +PREFERENCES_FORIMAGE;Pour les fichiers images +PREFERENCES_FORRAW;Pour les fichiers RAW +PREFERENCES_GIMPPATH;Dossier d'intallation de GIMP +PREFERENCES_GTKTHEME;GTK par défaut +PREFERENCES_HINT;Conseil +PREFERENCES_HLTHRESHOLD;Seuil pour le dépassement de domaine supérieur +PREFERENCES_ICCDIR;Dossier des profils ICC +PREFERENCES_IMPROCPARAMS;Paramètres de traitement d'image par défaut +PREFERENCES_INTENT_ABSOLUTE;Colorimétrie absolue +PREFERENCES_INTENT_PERCEPTUAL;Perceptuel +PREFERENCES_INTENT_RELATIVE;Colorimétrie relative +PREFERENCES_INTENT_SATURATION;Saturation +PREFERENCES_LIVETHUMBNAILS;Vignettes "Live" (plus lent) +PREFERENCES_MONITORICC;Profil du moniteur +PREFERENCES_OUTDIR;Dossier de sortie +PREFERENCES_OUTDIRFOLDER;Dossier de sauvegarde +PREFERENCES_OUTDIRFOLDERHINT;Place les images traitées dans le dossier selectionné +PREFERENCES_OUTDIRHINT;Vous pouvez utiliser les paramètres de chaîne formatées suivants:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nCes paramètres de chaînes formatés se réfèrent aux dossiers et sous-chemins du chemin du fichier RAW.\n\nPar exemple, si /home/tom/image/02-09-2006/dsc0012.nefa été ouvert, la signification des paramètres est:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nSi vous voulez enregistrer l'image de sortie là où se trouve l'original, écrivez:\n%p1/%f\n\nSi vous voulez enregistrer l'image de sortie dans un dossier 'convertis' situé dans le dossier de l'original, écrivez:\n%p1/convertis/%f\n\nSi vous voulez enregistrer l'image de sortie dans le dossier '/home/tom/convertis' en conservant le même sous-dossier de dates, écrivez:\n%p2/convertis/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;Vous pouvez utiliser les paramètres de chaîne formatées suivants:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nCes paramètres de chaînes formatées se réfèrent aux dossiers et sous-chemins du chemin du fichier RAW.\n\nPar exemple, si /home/tom/image/02-09-2006/dsc0012.nefa été ouvert, la signification des paramètres est:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nSi vous voulez enregistrer l'image de sortie là où se trouve l'original, écrivez:\n%p1/%f\n\nSi vous voulez enregistrer l'image de sortie dans un dossier 'convertis' situé dans le dossier de l'original, écrivez:\n%p1/convertis/%f\n\nSi vous voulez enregistrer l'image de sortie dans le dossier '/home/tom/convertis' en conservant le même sous-dossier de dates, écrivez:\n%p2/convertis/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Utiliser le modèle +PREFERENCES_PARSEDEXTADD;Ajout de l'extension +PREFERENCES_PARSEDEXTADDHINT;Tapez une extension et cliquez ce bouton pour l'ajouter à la liste +PREFERENCES_PARSEDEXTDELHINT;Supprime de la liste les extensions sélectionnées +PREFERENCES_PARSEDEXT;Extensions considérées +PREFERENCES_PROFILEHANDLING;Gestionnaire des profils de traitement +PREFERENCES_PROFILELOADPR;Priorité de chargement des profils +PREFERENCES_PROFILEPRCACHE;Profil dans le Cache +PREFERENCES_PROFILEPRFILE;Profil accolé au fichier d'entrée +PREFERENCES_PROFILESAVECACHE;Enregistrer la paramètres de traitement dans le Cache +PREFERENCES_PROFILESAVEINPUT;Enregistrer la paramètres de traitement accolé au fichier d'entrée +PREFERENCES_PSPATH;Dossier d'installation d'Adobe Photoshop +PREFERENCES_SELECTICCDIRDLG;Choix du dossier des profils ICC... +PREFERENCES_SELECTLANG;Choix de la langue +PREFERENCES_SELECTMONITORPROFDLG;Choix du profil ICC de l'affichage... +PREFERENCES_SELECTTHEME;Choisissez un thème +PREFERENCES_SHOWBASICEXIF;Voir les infos EXIF basiques +PREFERENCES_SHOWDATETIME;Voir la date et l'heure +PREFERENCES_SHOWONLYRAW;Voir seulement les fichiers RAW +PREFERENCES_SHTHRESHOLD;Seuil pour le dépassement de domaine inférieur +PREFERENCES_STARTUPIMDIR;Répertoire Image au démarrage +PREFERENCES_TAB_BROWSER;Navigateur de fichiers +PREFERENCES_TAB_COLORMGR;Gestion des couleurs +PREFERENCES_TAB_GENERAL;Général +PREFERENCES_TAB_IMPROC;Traitement de l'Image +PREFERENCES_TAB_OUTPUT;Options de sortie +PREFERENCES_THUMBSIZE;Tailles des vignettes +PROFILEPANEL_FILEDLGFILTERANY;Tous les fichiers +PROFILEPANEL_FILEDLGFILTERPP;Profils de post-traitement +PROFILEPANEL_LABEL;Profils de post-traitement +PROFILEPANEL_LOADDLGLABEL;Charger les paramètres de post-traitement... +PROFILEPANEL_PCUSTOM;Personnel +PROFILEPANEL_PFILE;Depuis le fichier +PROFILEPANEL_PLASTPHOTO;Photo précédente +PROFILEPANEL_PLASTSAVED;Dernière sauvegarde +PROFILEPANEL_PROFILE;Profil +PROFILEPANEL_SAVEDLGLABEL;Enregistrer les paramètres de post-traitement... +PROFILEPANEL_TOOLTIPCOPY;Copie le profil courant dans le presse-papier +PROFILEPANEL_TOOLTIPLOAD;Charger un profil depuis un fichier +PROFILEPANEL_TOOLTIPPASTE; Colle le profil depuis le presse-papier +PROFILEPANEL_TOOLTIPSAVE;Enregistrer le profil actuel +PROGRESSBAR_DECODING;Décodage du fichier RAW... +PROGRESSBAR_DEMOSAICING;Dématriçage... +PROGRESSBAR_LOADING;Chargement de l'Image... +PROGRESSBAR_LOADJPEG;Chargement du fichier JPEG... +PROGRESSBAR_LOADPNG;Chargement du fichier PNG... +PROGRESSBAR_LOADTIFF;Chargement du fichier TIFF... +PROGRESSBAR_PROCESSING;Traitement de l'Image... +PROGRESSBAR_READY;Prêt. +PROGRESSBAR_SAVEJPEG;Enregistrement du fichier JPEG... +PROGRESSBAR_SAVEPNG;Enregistrement du fichier PNG... +PROGRESSBAR_SAVETIFF;Enregistrement du fichier TIFF... +PROGRESSDLG_LOADING;Chargement du fichier... +PROGRESSDLG_PROCESSING;Traitement de l'image... +PROGRESSDLG_SAVING;Enregistrement du fichier... +QINFO_FOCALLENGTH;Longueur focale +QINFO_ISO;ISO +QINFO_LENS;Objectif +QINFO_NOEXIF;Données EXIF non disponibles. +SAVEDLG_FILEFORMAT;Format de fichier +SAVEDLG_JPEGQUAL;Qualité JPEG +SAVEDLG_JPGFILTER;Fichiers JPEG +SAVEDLG_PNGCOMPR;Compression PNG +SAVEDLG_PNGFILTER;Fichiers PNG +SAVEDLG_PUTTOQUEUEHEAD;Placer au début de la file de traitement +SAVEDLG_PUTTOQUEUE;Placer dans la file de traitement +SAVEDLG_PUTTOQUEUETAIL;Placer au fin de la file de traitement +SAVEDLG_SAVEIMMEDIATELY;Enregistrer immédiatement +SAVEDLG_SAVESPP;Enregistrer les paramètres de développement avec l'image +SAVEDLG_TIFFFILTER;Fichiers TIFF +TOOLBAR_TOOLTIP_CROP;Sélection du rognage (touche C) +TOOLBAR_TOOLTIP_HAND;Outil de navigation (touche N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Sélection de la ligne d'horizon (touche S) +TOOLBAR_TOOLTIP_WB;Choix du point déterminant la balance des blancs (touche W) +TP_CACORRECTION_BLUE;Bleu +TP_CACORRECTION_LABEL;Correction aberration chromatique +TP_CACORRECTION_RED;Rouge +TP_CHMIXER_BLUE;Bleu +TP_CHMIXER_GREEN;Vert +TP_CHMIXER_LABEL;Mixage des canaux +TP_CHMIXER_RED;Rouge +TP_COARSETRAF_DEGREE;degré: +TP_COARSETRAF_TOOLTIP_HFLIP;Symétriser / axe vertical +TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotation vers la gauche +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotation vers la droite +TP_COARSETRAF_TOOLTIP_VFLIP;Symétriser / axe horizontal +TP_COLORBOOST_ACHANNEL;canal "a" +TP_COLORBOOST_AMOUNT;Quantité +TP_COLORBOOST_AVOIDCOLORCLIP;Éviter l'écrêtage couleur +TP_COLORBOOST_BCHANNEL;canal "b" +TP_COLORBOOST_CHAB;a & b +TP_COLORBOOST_CHANNEL;Canal +TP_COLORBOOST_CHSEPARATE;séparé +TP_COLORBOOST_ENABLESATLIMITER;Activer le limiteur de saturation +TP_COLORBOOST_LABEL;Réhaussement couleur +TP_COLORBOOST_SATLIMIT;Limite de saturation +TP_COLORDENOISE_EDGESENSITIVE;Sensible aux bords +TP_COLORDENOISE_EDGETOLERANCE;Tolérance des bords +TP_COLORDENOISE_LABEL;Réduction du bruit chromatique +TP_COLORDENOISE_RADIUS;Rayon +TP_COLORSHIFT_BLUEYELLOW;Bleu-Jaune +TP_COLORSHIFT_GREENMAGENTA;Vert-Magenta +TP_COLORSHIFT_LABEL;Décalage couleur +TP_CROP_DPI;PPP= +TP_CROP_FIXRATIO;Ratio fixe: +TP_CROP_GTDIAGONALS;Règle des diagonales +TP_CROP_GTHARMMEANS1;Manière harmonique 1 +TP_CROP_GTHARMMEANS2;Manière harmonique 2 +TP_CROP_GTHARMMEANS3;Manière harmonique 3 +TP_CROP_GTHARMMEANS4;Manière harmonique 4 +TP_CROP_GTNONE;Aucun +TP_CROP_GTRULETHIRDS;Règle des tiers +TP_CROP_GUIDETYPE;Type de guide: +TP_CROP_H;H +TP_CROP_LABEL;Rognage +TP_CROP_SELECTCROP; Sélection du rognage +TP_CROP_W;L +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Quantité +TP_DISTORTION_LABEL;Distorsion +TP_EXPOSURE_AUTOLEVELS;Niveaux Auto +TP_EXPOSURE_BLACKLEVEL;Noir +TP_EXPOSURE_BRIGHTNESS;Luminosité +TP_EXPOSURE_CLIP;Rognage +TP_EXPOSURE_COMPRHIGHLIGHTS;Compression hautes lumières +TP_EXPOSURE_COMPRSHADOWS;Compression des ombres +TP_EXPOSURE_CONTRAST;Contraste +TP_EXPOSURE_CURVEEDITOR;Courbe tonale +TP_EXPOSURE_EXPCOMP;Compensation d'exposition +TP_EXPOSURE_LABEL;Exposition +TP_HLREC_CIELAB;Mélange CIELab +TP_HLREC_COLOR;Propagation de la couleur +TP_HLREC_LABEL;Récupération des hautes lumières +TP_HLREC_LUMINANCE;Récupération de la luminance +TP_HLREC_METHOD;Méthode: +TP_ICM_FILEDLGFILTERANY;Tous les fichiers +TP_ICM_FILEDLGFILTERICM;Fichiers de profil ICC +TP_ICM_GAMMABEFOREINPUT;Appliquer le Gamma du profil +TP_ICM_INPUTCAMERA;Celui de l'appareil photo +TP_ICM_INPUTCUSTOM;Personnel +TP_ICM_INPUTDLGLABEL;Choix du profil ICC d'entrée... +TP_ICM_INPUTEMBEDDED;Utiliser celui inclus, si possible +TP_ICM_INPUTPROFILE;Profil d'entrée +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Pas d'ICM: sortie sRGB +TP_ICM_OUTPUTDLGLABEL;Choix du profil ICC de sortie... +TP_ICM_OUTPUTPROFILE;Profil de sortie +TP_ICM_SAVEREFERENCE;Utiliser l'image comme profil de référence +TP_ICM_WORKINGPROFILE;Profil de Travail +TP_LUMACURVE_BLACKLEVEL;Noir +TP_LUMACURVE_BRIGHTNESS;Luminosité +TP_LUMACURVE_COMPRHIGHLIGHTS;Compression hautes lumières +TP_LUMACURVE_COMPRSHADOWS;Compression des ombres +TP_LUMACURVE_CONTRAST;Contraste +TP_LUMACURVE_CURVEEDITOR;Courbe de luminance +TP_LUMACURVE_LABEL;Courbe de luminance +TP_LUMADENOISE_EDGETOLERANCE;Tolérance des bords +TP_LUMADENOISE_LABEL;Réduction du bruit de luminance +TP_LUMADENOISE_RADIUS;Rayon +TP_RESIZE_BICUBIC;Bicubique +TP_RESIZE_BICUBICSF;Bicubique (Plus doux) +TP_RESIZE_BICUBICSH;Bicubique (Plus net) +TP_RESIZE_BILINEAR;Bilinéaire +TP_RESIZE_FULLSIZE;Dimensions finales de l'image: +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Redimensionnement +TP_RESIZE_METHOD;Méthode: +TP_RESIZE_NEAREST;Au plus proche +TP_RESIZE_SCALE;Echelle +TP_RESIZE_W;L: +TP_ROTATE_AUTOCROP;Rognage auto +TP_ROTATE_DEGREE;Degré +TP_ROTATE_FILL;Remplir +TP_ROTATE_LABEL;Rotation +TP_ROTATE_SELECTLINE;Choisir la ligne d'horizon +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Hautes lumières +TP_SHADOWSHLIGHTS_HLTONALW;Amplitude tonale +TP_SHADOWSHLIGHTS_LABEL;Ombres/Hautes lumières +TP_SHADOWSHLIGHTS_LOCALCONTR;Contraste local +TP_SHADOWSHLIGHTS_RADIUS;Rayon +TP_SHADOWSHLIGHTS_SHADOWS;Ombres +TP_SHADOWSHLIGHTS_SHTONALW;Amplitude tonale +TP_SHARPENING_AMOUNT;Quantité +TP_SHARPENING_EDRADIUS;Rayon +TP_SHARPENING_EDTOLERANCE;Tolérance des bords +TP_SHARPENING_HALOCONTROL;Contrôle du halo +TP_SHARPENING_HCAMOUNT;Quantité +TP_SHARPENING_LABEL;Netteté +TP_SHARPENING_METHOD;Méthode +TP_SHARPENING_ONLYEDGES;Améliorer seulement les bords +TP_SHARPENING_RADIUS;Rayon +TP_SHARPENING_RLD_AMOUNT;Quantité +TP_SHARPENING_RLD_DAMPING;Amortissement +TP_SHARPENING_RLD;Déconvolution de Richardson–Lucy +TP_SHARPENING_RLD_ITERATIONS;Itérations +TP_SHARPENING_THRESHOLD;Seuil +TP_SHARPENING_USM;Masque flou +TP_VIGNETTING_AMOUNT;Quantité +TP_VIGNETTING_LABEL;Correction vignettage +TP_VIGNETTING_RADIUS;Rayon +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Appareil photo +TP_WBALANCE_CUSTOM;Personnalisé +TP_WBALANCE_GREEN;Teinte +TP_WBALANCE_LABEL;Balance des blancs +TP_WBALANCE_METHOD;Méthode +TP_WBALANCE_SIZE;Taille: +TP_WBALANCE_SPOTWB;Point de mesure +TP_WBALANCE_TEMPERATURE;Température +ZOOMBAR_DETAIL;Détail +ZOOMBAR_HUGE;Énorme +ZOOMBAR_LARGE;Large +ZOOMBAR_NORMAL;Normal +ZOOMBAR_PREVIEW;Prévisualiation +ZOOMBAR_SCALE;Echelle +ZOOMBAR_SMALL;Petit + +GENERAL_HIGH_QUALITY;Qualité élevée +GENERAL_UNCHANGED;(Inchangé) +MAIN_MSG_PLACES;Emplacement +GENERAL_BEFORE;Après +GENERAL_AFTER;Avant +MAIN_TOOLTIP_TOGGLE;Comparaison avant/après +MAIN_BUTTON_PUTTOQUEUE;Envoyer dans la file +MAIN_MSG_NAVIGATOR;Navigateur +FILEBROWSER_TOOLTIP_STOPPROCESSING;Démarrer automatiquement le traitement à l'arrivée d'une nouvelle tâche +BATCHQUEUE_AUTOSTART;Démarrage auto +TP_DETAIL_AMOUNT;Quantité +TP_RESIZE_SPECIFY;Préciser: +TP_RESIZE_SCALE;Echelle +TP_RESIZE_WIDTH;Largeur +TP_RESIZE_HEIGHT;Hauteur +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Activer les filtres sur les Métadonnées +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Hautes kumières +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Ombres +BATCH_PROCESSING;Traitement par lot +PREFERENCES_BATCH_PROCESSING;Traitement par lot +PREFERENCES_BEHAVIOR;Comportement +PREFERENCES_PROPERTY;Propriété +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profil modifié dans le navigateur +MAIN_MSG_ERRORDURINGIMAGESAVING;Erreur pendant la sauvegarde de l'image +FILEBROWSER_CURRENT_NAME;Nom courant: +FILEBROWSER_NEW_NAME;Nouveau nom: +FILEBROWSER_USETEMPLATE;Utiliser le modèle: +FILEBROWSER_ADDDELTEMPLATE;Ajouter/Supprimer le modèle... +ZOOMPANEL_ZOOMIN;Zoom + +ZOOMPANEL_ZOOMOUT;Zoom - +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Ajuster à la fenêtre +ZOOMPANEL_NEWCROPWINDOW;Ajouter une nouvelle fenêtre de zoom +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Plein écran +MAIN_BUTTON_UNFULLSCREEN;Quitter plein écran +PREFERENCES_OVERLAY_FILENAMES;Superposer les noms de fichier sur les vignettes +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;V = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;T = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;V = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;T = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Greek b/rtdata/languages/Greek new file mode 100644 index 000000000..916237f75 --- /dev/null +++ b/rtdata/languages/Greek @@ -0,0 +1,701 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# 14.05.2008: zeusalmighty +ADJUSTER_RESET_TO_DEFAULT;ΕπαναφοÏά Ï€Ïοεπιλογών +CURVEEDITOR_FILEDLGFILTERANY;Οποιοδήποτε αÏχείο +CURVEEDITOR_FILEDLGFILTERCURVE;ΑÏχεία καμπυλών +CURVEEDITOR_LINEAR;ΓÏαμμικό +CURVEEDITOR_LOADDLGLABEL;ΦόÏτωση καμπÏλης... +CURVEEDITOR_SAVEDLGLABEL;Αποθήκευση καμπλης... +CURVEEDITOR_TOOLTIPLINEAR;ΕπαναφοÏά καμπÏλης σε γÏαμμική +CURVEEDITOR_TOOLTIPLOAD;ΦόÏτωση καμπÏλης απο αÏχείο +CURVEEDITOR_TOOLTIPSAVE;Αποθήκευση παÏοÏσας καμπÏλης +EXIFFILTER_APERTURE;Aperture +EXIFFILTER_CAMERA;Camera +EXIFFILTER_DIALOGLABEL;Exif Filter +EXIFFILTER_FOCALLEN;Focal Length +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Lens +EXIFFILTER_SHUTTER;Shutter +EXIFPANEL_ADDEDITHINT;ΠÏοσθήκη καινοÏÏιας ετικέττας ή επεξεÏγασία +EXIFPANEL_ADDEDIT;ΠÏοσθήκη/ΕπεξεÏγασία +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Εισαγωγή τιμής +EXIFPANEL_ADDTAGDLG_SELECTTAG;Επιλογή ετικέττας +EXIFPANEL_ADDTAGDLG_TITLE;ΠÏοσθήκη/ΕπεξεÏγασία ετικέττας +EXIFPANEL_KEEPHINT;ΣυγκÏάτηση των επιλεγμένων ετικεττών κατά την εγγÏαφή του παÏαγώμενου αÏχείου +EXIFPANEL_KEEP;ΣυγκÏάτηση +EXIFPANEL_REMOVEHINT;ΑφαίÏεση των επιλεγμένων ετικεττών κατά την εγγÏαφή του παÏαγώμενου αÏχείου +EXIFPANEL_REMOVE;ΑφαίÏεση +EXIFPANEL_RESETALLHINT;ΕπαναφοÏά όλων των ετικεττών στην αÏχική τους τιμή +EXIFPANEL_RESETALL;ΕπαναφοÏά όλων +EXIFPANEL_RESETHINT;ΕπαναφοÏά των επιλεγμένων ετικεττών στις Ï€Ïωτότυπες τους τιμές +EXIFPANEL_RESET;ΕπαναφοÏά +EXIFPANEL_SUBDIRECTORY;Subdirectory +FILEBROWSER_APPLYPROFILE;Apply profile +FILEBROWSER_ARRANGEMENTHINT;Change between vertical/horizontal alignment of thumbnails +FILEBROWSER_CLEARPROFILE;Clear profile +FILEBROWSER_COPYPROFILE;Copy profile +FILEBROWSER_DELETEDLGLABEL;File delete confirmation +FILEBROWSER_DELETEDLGMSG;Are you sure you want to delete the selected %1 files? +FILEBROWSER_EMPTYTRASH;Empty Trash +FILEBROWSER_EMPTYTRASHHINT;Permanently delete the files of the trash +FILEBROWSER_EXIFFILTERAPPLY;Apply +FILEBROWSER_EXIFFILTERAPPLYHINT;Switch on/off exif filter of the file browser +FILEBROWSER_EXIFFILTERLABEL;Exif Filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Change settings of the exif filter +FILEBROWSER_EXIFFILTERSETTINGS;Setup +FILEBROWSER_PARTIALPASTEPROFILE;Partial paste +FILEBROWSER_PASTEPROFILE;Paste profile +FILEBROWSER_POPUPCANCELJOB;Cancel job +FILEBROWSER_POPUPMOVEEND;Move to end of queue +FILEBROWSER_POPUPMOVEHEAD;Move to head of queue +FILEBROWSER_POPUPOPEN;Open +FILEBROWSER_POPUPPROCESS;Put to processing queue +FILEBROWSER_POPUPRANK1;Rank 1 +FILEBROWSER_POPUPRANK2;Rank 2 +FILEBROWSER_POPUPRANK3;Rank 3 +FILEBROWSER_POPUPRANK4;Rank 4 +FILEBROWSER_POPUPRANK5;Rank 5 +FILEBROWSER_POPUPREMOVE;Remove from filesystem +FILEBROWSER_POPUPRENAME;Rename +FILEBROWSER_POPUPSELECTALL;Select all +FILEBROWSER_POPUPTRASH;Move to trash +FILEBROWSER_POPUPUNRANK;Unrank +FILEBROWSER_POPUPUNTRASH;Remove from trash +FILEBROWSER_PROCESSINGSETTINGSHINT;Set the file format and output directory +FILEBROWSER_PROCESSINGSETTINGS;Settings +FILEBROWSER_RENAMEDLGLABEL;Rename file +FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +FILEBROWSER_SHOWDIRHINT;Show all images of the directory +FILEBROWSER_SHOWQUEUEHINT;Show content of the processing queue +FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1 star +FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2 star +FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3 star +FILEBROWSER_SHOWRANK4HINT;Show images ranked as 4 star +FILEBROWSER_SHOWRANK5HINT;Show images ranked as 5 star +FILEBROWSER_SHOWTRASHHINT;Show content of the trash +FILEBROWSER_SHOWUNRANKHINT;Show unranked images +FILEBROWSER_STARTPROCESSINGHINT;Start processing/saving of images in the queue +FILEBROWSER_STARTPROCESSING;Start Processing +FILEBROWSER_STOPPROCESSINGHINT;Stop processing of images +FILEBROWSER_STOPPROCESSING;Stop processing +FILEBROWSER_THUMBSIZE;Thumb. size +FILEBROWSER_ZOOMINHINT;Increase thumbnail size +FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size +GENERAL_ABOUT;About +GENERAL_CANCEL;ΑκÏÏωση +GENERAL_DISABLED;ΑπενεÏγοποιημένο +GENERAL_DISABLE;ΑπενεÏγοποίηση +GENERAL_ENABLED;ΕνεÏγοποιημένο +GENERAL_ENABLE;ΕνεÏγοποίηση +GENERAL_LANDSCAPE;Τοπίο +GENERAL_LOAD;ΦόÏτωση +GENERAL_NA;μη διαθέσιμο +GENERAL_NO;Όχι +GENERAL_OK;Εντάξει +GENERAL_PORTRAIT;ΠοÏÏ„Ïαίτο +GENERAL_SAVE;Αποθήκευση +GENERAL_YES;Îαί +HISTOGRAM_LABEL;Histogram +HISTOGRAM_TOOLTIP_B;ΠÏοβολή/απόκÏυψη ΜΠΛΕ ιστογÏάμματος +HISTOGRAM_TOOLTIP_G;ΠÏοβολή/απόκÏυψη ΠΡΑΣΙÎΟΥ ιστογÏάμματος +HISTOGRAM_TOOLTIP_L;ΠÏοβολή/απόκÏυψη CIELAB ιστογÏάμματος φωτεινότητας +HISTOGRAM_TOOLTIP_R;ΠÏοβολή/απόκÏυψη KOKKINOY ιστογÏάμματος +HISTORY_CHANGED;Αλλαγή +HISTORY_CUSTOMCURVE;ΠÏοσαÏμοσμένη καμπÏλη +HISTORY_DELSNAPSHOT;ΑφαίÏεση στιγμιοτÏπου +HISTORY_FROMCLIPBOARD;From clipboard +HISTORY_LABEL;ΙστοÏικό +HISTORY_MSG_10;Συμπίεση σκιών +HISTORY_MSG_11;ΚαμπÏλη τονικότητας +HISTORY_MSG_12;Αυτόματη έκθεση +HISTORY_MSG_13;Ψαλιδισμός έκθεσης +HISTORY_MSG_14;Φωτεινότητα Φωτεινότητας +HISTORY_MSG_15;Φωτεινότητα αντίθεσης +HISTORY_MSG_16;Φωτεινότητα μαÏÏων +HISTORY_MSG_17;Φωτεινότητα συμπίεσησ φωτεινών σημείων. +HISTORY_MSG_18;Φωτεινότητα συμπίεσης σκιών. +HISTORY_MSG_19;ΚαμπÏλη φωτεινότητας +HISTORY_MSG_1;ΦοÏτώθηκε εικόνα +HISTORY_MSG_20;Όξυνση +HISTORY_MSG_21;Ακτίνα όξυνσης +HISTORY_MSG_22;Ένταση όξυνσης +HISTORY_MSG_23;Κατώφλι όξυνσης +HISTORY_MSG_24;Όξυνση μόνο οÏίων +HISTORY_MSG_25;Ακτίνα ανίχνευσης οÏίων όξυνσης +HISTORY_MSG_26;Όξυνση, Ανοχή οÏίων +HISTORY_MSG_27;Όξυνση, Έλεγχος άλως +HISTORY_MSG_28;Ένταση ελέγχου άλως +HISTORY_MSG_29;Μέθοδοςν όξυνσης +HISTORY_MSG_2;ΦοÏτώθηκε Ï€Ïοφίλ +HISTORY_MSG_30;Ακτίνα Deconvolution +HISTORY_MSG_31;Ένταση Deconvolution +HISTORY_MSG_32;Καταστολή Deconvolution +HISTORY_MSG_33;Επαναλήψεις Deconvolution +HISTORY_MSG_34;Αποφυγή ψαλιδίσματος χÏώματος +HISTORY_MSG_35;ΠεÏιοσμός κοÏÎµÏƒÎ¼Î¿Ï +HISTORY_MSG_36;Ένταση πεÏÎ¹Î¿ÏƒÎ¼Î¿Ï ÎºÎ¿ÏÎµÏƒÎ¼Î¿Ï +HISTORY_MSG_37;Ενίσχυση χÏώματος +HISTORY_MSG_38;Μέθοδος εξισοÏÏόπησης Î»ÎµÏ…ÎºÎ¿Ï +HISTORY_MSG_39;ΘεÏμοκÏασία χÏώματος +HISTORY_MSG_3;Αλλαγή Ï€Ïοφίλ +HISTORY_MSG_40;ΑπόχÏωση εξισοÏÏόπησης Î»ÎµÏ…ÎºÎ¿Ï +HISTORY_MSG_41;ΧÏωματική μετατόπιση "A" +HISTORY_MSG_42;ΧÏωματική μετατόπιση "B" +HISTORY_MSG_43;ΑποθοÏÏβηση φωτεινότητας +HISTORY_MSG_44;Ακτίνα αποθοÏÏβησης φωτεινότητας +HISTORY_MSG_45;Ανοχή οÏίων αποθοÏÏβησης φωτεινότητας +HISTORY_MSG_46;ΑποθοÏÏβηση χÏώματος +HISTORY_MSG_47;Ακτίνα αποθοÏÏβησης χÏώματος +HISTORY_MSG_48;Ανοχή οÏίων αποθοÏÏβησης χÏώματος +HISTORY_MSG_49;ΑποθοÏÏβηση χÏώματος (ευαισθησία οÏίων) +HISTORY_MSG_4;Αναζήτηση ιστοÏÎ¹ÎºÎ¿Ï +HISTORY_MSG_50;ΕÏγαλείο σκιών/φωτεινών σημείων +HISTORY_MSG_51;Μείωση φωτεινών σημείων +HISTORY_MSG_52;Ενίσχυση σκιών +HISTORY_MSG_53;Τονικό εÏÏος φωτεινών σημείων +HISTORY_MSG_54;Τονικό εÏÏος σκιών +HISTORY_MSG_55;Τοπική αντίθεση +HISTORY_MSG_56;Ακτίνα σκιών/φωτεινών σημείων +HISTORY_MSG_57;Coarse Rotation +HISTORY_MSG_58;ΟÏιζόντια ανατÏοπή +HISTORY_MSG_59;ΚατακόÏυφη ανατÏοπή +HISTORY_MSG_5;Φωτεινότητα +HISTORY_MSG_60;ΠεÏιστÏοφή +HISTORY_MSG_61;ΠεÏιστÏοφή +HISTORY_MSG_62;ΔιόÏθωση παÏαμόÏφωσης Ï†Î±ÎºÎ¿Ï +HISTORY_MSG_63;Επιλέχθηκε στιγμιότυπο +HISTORY_MSG_64;Αποκοπή εικόνας +HISTORY_MSG_65;C/A ΔιόÏθωση +HISTORY_MSG_66;Ανάκτηση Φωτεινών σημείων +HISTORY_MSG_67;Ένταση ανάκτησης φωτεινών σημείων +HISTORY_MSG_68;Μέθοδος ανάκτηση φωτεινών σημείων +HISTORY_MSG_69;ΠαÏόν χÏωματικό Ï€Ïοφίλ +HISTORY_MSG_6;Αντίθεση +HISTORY_MSG_70;ΧÏωματικό Ï€Ïοφίλ εξόδου +HISTORY_MSG_71;ΧÏωματικό Ï€Ïοφίλ εισόδου +HISTORY_MSG_72;ΔιόÏθωση Vignetting +HISTORY_MSG_73;Μίξη καναλιών +HISTORY_MSG_74;Αλλαγή μεγέθους/κλίμακας +HISTORY_MSG_75;Μέθοδος αλλαγής μεγέθους +HISTORY_MSG_76;Αλλαγή στοιχείων Exif +HISTORY_MSG_77;Αλλαγή στοιχίεων IPTC +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;ΜαÏÏα +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;ΕπανόÏθωση Έκθεσης +HISTORY_MSG_9;Συμπίεση φωτεινών σημείων +HISTORY_NEWSNAPSHOTAS;Ως... +HISTORY_NEWSNAPSHOT;Îέο στιγμιότυπο +HISTORY_NEWSSDIALOGLABEL;Όνομα στιγμιοτÏπου: +HISTORY_NEWSSDIALOGTITLE;ΠÏοσθήκη νέου στιγμιοτÏπου +HISTORY_SETTO;ΟÏισμός σε +HISTORY_SNAPSHOTS;Στιγμιότυπα +HISTORY_SNAPSHOT;Στιγμιότυπο +ICMPANEL_FILEDLGFILTERANY;Οποιοδήποτε αÏχείο +ICMPANEL_FILEDLGFILTERICM;ΑÏχεία Ï€Ïοφίλ ICC +ICMPANEL_GAMMABEFOREINPUT;Το Ï€Ïοφίλ αλλάζει την gamma +ICMPANEL_INPUTCAMERA;ΠÏοεπιλογή φωτογÏαφικής μηχανής +ICMPANEL_INPUTCUSTOM;ΠÏοσαÏμοσμένο +ICMPANEL_INPUTDLGLABEL;Επιλέξτε Ï€Ïοφιλ ICC εισόδου... +ICMPANEL_INPUTEMBEDDED;ΧÏήση ενσωματωμένου, αν αυτό είναι δυνατό +ICMPANEL_INPUTPROFILE;ΠÏοφίλ εισαγωγής +ICMPANEL_NOICM;No ICM: sRGB output +ICMPANEL_OUTPUTDLGLABEL;Επιλέξτε Ï€Ïοφιλ ICC εξόδου... +ICMPANEL_OUTPUTPROFILE;ΠÏοφίλ εξόδου +ICMPANEL_SAVEREFERENCE;Αποθήκευση εικόνας ως αναφοÏά για δημιουÏγία Ï€Ïοφίλ. +ICMPANEL_WORKINGPROFILE;ΠαÏόν Ï€Ïοφίλ +IMAGEAREA_DETAILVIEW;ΛεπτομεÏής Ï€Ïοβολή +IPTCPANEL_AUTHORHINT;Όνομα του δημιουÏÎ³Î¿Ï Ï„Î¿Ï… αντικειμένου, Ï€.χ. συγγÏαφέας, φωτογÏάφος ή γÏαφίστας (Ανα γÏαμμή). +IPTCPANEL_AUTHORSPOSITIONHINT;Τίτλος που αποδίδεται από τον/τους δημιουÏγό/γους (Ανα γÏαμμή τίτλος). +IPTCPANEL_AUTHORSPOSITION;Θέση δημιουÏÎ³Î¿Ï +IPTCPANEL_AUTHOR;ΣυγγÏαφέας +IPTCPANEL_CAPTIONHINT;Μια λεκτική πεÏιγÏαφή των στοιχείων (Λεζάντα - ΠεÏίληψη). +IPTCPANEL_CAPTIONWRITERHINT;Το όνομα του Ï€Ïοσώπου που ασχολήθηκε με την συγγÏαφή, επεξεÏγασία ή διόÏθωση της εικόνας ή λεζάντας/πεÏίληψης (ΣυγγÏαφέας - Επιμελητής). +IPTCPANEL_CAPTIONWRITER;ΣυγγÏαφέας λεζάντας +IPTCPANEL_CAPTION;Λεζάντα +IPTCPANEL_CATEGORYHINT;Ταυτοποιεί το θέμα της εικόνας βάση της άποψης του παÏοχέα (ΚατηγοÏία). +IPTCPANEL_CATEGORY;ΚατηγοÏία +IPTCPANEL_CITYHINT;Πόλη Ï€Ïοέλευσης εικόνας (Πόλη). +IPTCPANEL_CITY;Πόλη +IPTCPANEL_COPYHINT;ΑντιγÏαφή Ïυθμίσεων IPTC στην πεÏιοχή αποκομμάτων +IPTCPANEL_COPYRIGHTHINT;Όποιο απαÏαίτητο σχόλιο πεÏι πνευματικής ιδιοκτησίας (Σχόλια πεÏι πνευματική ιδιοκτησία). +IPTCPANEL_COPYRIGHT;Πνευματική ιδιοκτησία +IPTCPANEL_COUNTRYHINT;ΧώÏα/αÏχική τοποθεσία δημιουÏγίας εικόνας (ΧώÏα/αÏχική τοποθεσία). +IPTCPANEL_COUNTRY;ΧώÏα +IPTCPANEL_CREDITHINT;Ταυτοποιεί τον παÏοχέα της εικόνας, όχι απÏαίτητα δημιουÏγό/ιδιοκτήτη (ΕÏσημα). +IPTCPANEL_CREDIT;ΕÏσημα +IPTCPANEL_DATECREATEDHINT;Η ημεÏομηνία δημιουÏγίας του Ï€Î½ÎµÏ…Î¼Î±Ï„Î¹ÎºÎ¿Ï Ï€ÎµÏιεχομένου; ΤÏπος: JJJJMMTT (ΗμεÏομηνία δημιουÏγίας). +IPTCPANEL_DATECREATED;ΗμεÏομηνία δημιουÏγίας +IPTCPANEL_EMBEDDEDHINT;ΕπαναφοÏά στοιχείων IPTC αÏχείου εικόνας +IPTCPANEL_EMBEDDED;Ενσωματωμένο +IPTCPANEL_HEADLINEHINT;Ένας δημοσιεÏσιμος τίτλος που παÏέχει μια σÏνοψη των πεÏιεχομένων της εικόνας (Επικεφαλίδα). +IPTCPANEL_HEADLINE;Επικεφαλίδα +IPTCPANEL_INSTRUCTIONSHINT;Άλλες οδηγίες επιμέλειας που αφοÏοÏν την χÏήση της εικόνας (Ειδικίες οδηγίες). +IPTCPANEL_INSTRUCTIONS;Οδηγίες +IPTCPANEL_KEYWORDSHINT;ΧÏησιμοποιοÏνται ενδεικτικά ως λέξεις ανάκτησης(Λέξεις-κλειδιά). +IPTCPANEL_KEYWORDS;Λέξεις-κλειδιά +IPTCPANEL_PASTEHINT;Επικόλληση Ïυθμίσεων IPTC από την πεÏιοχή αποκομμάτων +IPTCPANEL_PROVINCEHINT;ΕπαÏχία/Πολιτεία/Îομός Ï€Ïοέλευσης της εικόνας (ΕπαÏχία/Πολιτεία/Îομός). +IPTCPANEL_PROVINCE;ΕπαÏχία +IPTCPANEL_RESETHINT;ΕπαναφοÏά Ï€Ïοεπιλεγμένου Ï€Ïοφίλ +IPTCPANEL_RESET;ΕπαναφοÏά +IPTCPANEL_SOURCEHINT;Αυθεντικός ιδιοκτήτης Ï€Î½ÎµÏ…Î¼Î±Ï„Î¹ÎºÎ¿Ï Ï€ÎµÏιεχομένου της εικόνας (Πηγή). +IPTCPANEL_SOURCE;Πηγή +IPTCPANEL_SUPPCATEGORIESHINT;ΠÏοσδιοÏίζουν επιπλέον το θέμα της εικόνας (ΣυμπληÏωματικές κατηγοÏίες). +IPTCPANEL_SUPPCATEGORIES;ΣυμπληÏ. ΚατηγοÏίες +IPTCPANEL_TITLEHINT;Μια σÏντομη αναφοÏά για την εικόνα (Όνομα αντικειμένου). +IPTCPANEL_TITLE;Τίτλος +IPTCPANEL_TRANSREFERENCEHINT;Ένας κωδικός που αντιπÏοσωπέυει την τοποθεσία αυθεντικής μετάδοσης (Κωδικός Αυθεντικής Μετάδοσης). +IPTCPANEL_TRANSREFERENCE;Κωδικός αυθεντικής μετάδοσης +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Ρυθμίσεις +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;Ως... +MAIN_BUTTON_SAVE;Αποθήκευση εικόνας +MAIN_BUTTON_SENDTOEDITOR;Send to editor +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Το αÏχείο ήδη υπάÏχει. +MAIN_MSG_CANNOTLOAD;ΑδÏνατη η φόÏτωση εικόνας +MAIN_MSG_CANNOTSAVE;ΑδÏνατη η αποθήκευση αÏχείου +MAIN_MSG_CANNOTSTARTEDITOR;Can not start editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Please set the correct path in the "Preferences" dialog. +MAIN_MSG_EXITJOBSINQUEUEINFO;Unprocessed images in the queue will be lost on exit. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Are you sure you want to exit? There are unprocessed images waiting in the queue. +MAIN_MSG_JOBSINQUEUE;εÏγασία(ες) μέσα στην λίστα αναμονής +MAIN_MSG_QOVERWRITE;Θέλετε να το αντικαταστήσετε; +MAIN_TAB_BASIC;Βασικό +MAIN_TAB_COLOR;Color +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Exposure +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;ΜετατÏοπή +MAIN_TOOLTIP_HIDEFP;ΠÏοβολή/απόκÏυψη του κάτω πλαισίου (τοποθεσίες και πεÏιηγητής αÏχείων, shortcut key: F) +MAIN_TOOLTIP_HIDEHP;ΠÏοβολή/απόκÏυψη αÏιστεÏÎ¿Ï Ï€Î»Î±Î¹ÏƒÎ¯Î¿Ï… (πεÏιλαμβανομένου του ιστοÏικοÏ, shortcut key: H) +MAIN_TOOLTIP_INDCLIPPEDH;Ένδειξη ÏˆÎ±Î»Î¹ÏƒÎ¼Î¿Ï Ï†Ï‰Ï„ÎµÎ¹Î½ÏŽÎ½ σημείων +MAIN_TOOLTIP_INDCLIPPEDS;Ένδειξη ÏˆÎ±Î»Î¹ÏƒÎ¼Î¿Ï ÏƒÎºÎ¹ÏŽÎ½ +MAIN_TOOLTIP_PREFERENCES;ΟÏισμός Ïυθμίσεων +MAIN_TOOLTIP_QINFO;ΓÏήγοÏες πληÏοφοÏίες στην εικόνα +MAIN_TOOLTIP_SAVEAS;Αποθήκευση εικόνας σε ένα επιλεγμένο φάκελο +MAIN_TOOLTIP_SAVE;Αποθήκευση εικόνας στον Ï€ÏοκαθοÏισμένο φάκελο +PARTIALPASTE_BASICGROUP;Basic settings +PARTIALPASTE_CACORRECTION;C/A correction +PARTIALPASTE_COARSETRANS;90 deg rotation / flipping +PARTIALPASTE_COLORBOOST;Color boost +PARTIALPASTE_COLORDENOISE;Color denoise +PARTIALPASTE_COLORGROUP;Color related settings +PARTIALPASTE_COLORMIXER;Color mixer +PARTIALPASTE_COLORSHIFT;Color shift +PARTIALPASTE_COMPOSITIONGROUP;Composition settings +PARTIALPASTE_CROP;Crop +PARTIALPASTE_DIALOGLABEL;Partial paste processing profile +PARTIALPASTE_DISTORTION;Distortion correction +PARTIALPASTE_EXIFCHANGES;Changes to exif data +PARTIALPASTE_EXPOSURE;Exposure +PARTIALPASTE_HLRECOVERY;Highlight recovery +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Lens related settings +PARTIALPASTE_LUMACURVE;Luminance curve +PARTIALPASTE_LUMADENOISE;Luminance noise reduction +PARTIALPASTE_LUMINANCEGROUP;Luminance related settings +PARTIALPASTE_METAICMGROUP;Metadata/ICM settings +PARTIALPASTE_RESIZE;Resize +PARTIALPASTE_ROTATION;Rotation +PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights +PARTIALPASTE_SHARPENING;Sharpening +PARTIALPASTE_VIGNETTING;Vignetting correction +PARTIALPASTE_WHITEBALANCE;White balance +PREFERENCES_APPLNEXTSTARTUP;εφαÏμόζεται στην επόμενη εκκίνηση +PREFERENCES_BLINKCLIPPED;Οι πεÏιοχές ψαλιδίσματος να αναβοσβήνουν +PREFERENCES_CACHECLEARALL;Clear All +PREFERENCES_CACHECLEARPROFILES;Clear Profiles +PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +PREFERENCES_CACHEFORMAT1;Proprietary (faster and better quality) +PREFERENCES_CACHEFORMAT2;JPEG (smaller disk footprint) +PREFERENCES_CACHEMAXENTRIES;Maximal Number of Cache Entries +PREFERENCES_CACHEOPTS;Cache Options +PREFERENCES_CACHESTRAT1;Prefer Speed to Low Memory Consumption +PREFERENCES_CACHESTRAT2;Prefer Low Memory Consumption to Speed +PREFERENCES_CACHESTRAT;Cache Strategy +PREFERENCES_CACHETHUMBFORM;Cache Thumbnail Format +PREFERENCES_CACHETHUMBHEIGHT;Maximal Thumbnail Height +PREFERENCES_CLEARDLG_LINE1;Clearing cache +PREFERENCES_CLEARDLG_LINE2;This may take a few seconds. +PREFERENCES_CLEARDLG_TITLE;Please wait +PREFERENCES_CLIPPINGIND;Ένδειξη ψαλιδίσματος +PREFERENCES_CMETRICINTENT;Colorimetric Intent +PREFERENCES_DATEFORMATHINT;YΜποÏείτε να χÏησιμοποιήσετε τις εξής εντολές μοÏφοποίησης:\n%y : χÏονολογία\n%m : μήνας\n%d : ημέÏα\n\nΓια παÏάδειγμα, η μοÏφοποίηση ημεÏομηνίας στην Ελλάδα είναι:\n%y/%m/%d +PREFERENCES_DATEFORMAT;Διάταξη ημεÏομηνίας +PREFERENCES_DEFAULTLANG;ΠÏοεπιλεγμένη γλώσσα +PREFERENCES_DEFAULTTHEME;ΠÏοεπιλεγμένο θέμα +PREFERENCES_DEMOSAICINGALGO;ΑλγόÏιθμος απομωσαϊκοποίησης +PREFERENCES_DIRHOME;Τοποθεσία "Home" +PREFERENCES_DIRLAST;Τελευταία τοποθεσία που χÏησιμοποιήθηκε +PREFERENCES_DIROTHER;Άλλο +PREFERENCES_DIRSELECTDLG;Επιλέξτε τοποθεσία εικόνων κατά την έναÏξη... +PREFERENCES_DIRSOFTWARE;Τοποθεσία εγκατάστασης +PREFERENCES_DMETHOD;Μέθοδος +PREFERENCES_EDITORCMDLINE;Other command line +PREFERENCES_EXTERNALEDITOR;External editor +PREFERENCES_FALSECOLOR;Βήματα καταστολής σφαλμένων χÏωμάτων +PREFERENCES_FBROWSEROPTS;Επιλογές πεÏιήγησης αÏχείων +PREFERENCES_FILEFORMAT;Είδος αÏχείου +PREFERENCES_FORIMAGE;Για αÏχεία εικόνων +PREFERENCES_FORRAW;Για αÏχεία RAW +PREFERENCES_GIMPPATH;GIMP installation directory +PREFERENCES_GTKTHEME;ΠÏοεπιλεγμένη GTK +PREFERENCES_HINT;ÎÏξη +PREFERENCES_HLTHRESHOLD;Κατώφλι ψαλιδίσματος φωτεινών σημείων +PREFERENCES_ICCDIR;Τοποθεσία των Ï€Ïοφίλ ICC +PREFERENCES_IMPROCPARAMS;ΠÏοεπιλεγμένες παÏαμέτÏοι επεξεÏγασίας εικόνας +PREFERENCES_INTENT_ABSOLUTE;Absolute Colorimetric +PREFERENCES_INTENT_PERCEPTUAL;Perceptual +PREFERENCES_INTENT_RELATIVE;Relative Colorimetric +PREFERENCES_INTENT_SATURATION;Saturation +PREFERENCES_LIVETHUMBNAILS;Live Thumbnails (slower) +PREFERENCES_MONITORICC;ΠÏοφίλ οθόνης +PREFERENCES_OUTDIRFOLDERHINT;Put the saved images to the seledted folder +PREFERENCES_OUTDIRFOLDER;Save to folder +PREFERENCES_OUTDIRHINT;ΜποÏείτε να χÏησιμοποιήσετε τις ακόλουθες σειÏές μοÏφοποίησης:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nΑυτές οι σειÏές μοÏφοποίησης αναφέÏονται στις τοποθεσίες και τις υπο-διαδÏομές της τοποθεσίας του αÏχείου raw.\n\nΓια παÏάδειγμα, αν το /home/tom/image/02-09-2006/dsc0012.nef ανοιχθεί, η σημασία των ακόλουθων σειÏών μοÏφοποίησης είναι:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nΑν θέλεθτε να αποδηκεÏσετε την εικόνα εξόδου μαζί με το Ï€Ïωτότυπο, γÏάψτε:\n%p1/%f\n\nΑν θέλετε να αποθηκεÏσετε την εικόνα εξόδου σε ένα φάκελο 'converted', μέσα στην τοποθεσία που βÏίσκεται το Ï€Ïωτότυπο, γÏάψτε:\n%p1/converted/%f\n\nΑν θέλετε να αποθηκεÏσετε την εικόνα εξόδου σε στην τοποθεσία '/home/tom/converted' κÏατώντας όμως την ίδια δομή υπο-τοποθεσιών ημεÏομηνίων, γÏάψτε:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Use Template +PREFERENCES_OUTDIR;Τοποθεσία εξόδου +PREFERENCES_PARSEDEXTADD;Add Extension +PREFERENCES_PARSEDEXTADDHINT;Type an extension and press this button to append list +PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list +PREFERENCES_PARSEDEXT;Parsed Extensions +PREFERENCES_PROFILEHANDLING;Processing Profile Handling +PREFERENCES_PROFILELOADPR;Profile Loading Priority +PREFERENCES_PROFILEPRCACHE;Profile in Cache +PREFERENCES_PROFILEPRFILE;Profile Next to the Input File +PREFERENCES_PROFILESAVECACHE;Save Processing Parameters to the Cache +PREFERENCES_PROFILESAVEINPUT;Save Processing Parameters Next to the Input File +PREFERENCES_PSPATH;Adobe Photoshop installation directory +PREFERENCES_SELECTICCDIRDLG;Επιλογή τοποθεσίας Ï€Ïοφίλ ICC... +PREFERENCES_SELECTLANG;Επιλογή γλώσσας +PREFERENCES_SELECTMONITORPROFDLG;Επιλογή Ï€Ïοφίλ ICC της οθόνης... +PREFERENCES_SELECTTHEME;Επιλογή θέματος +PREFERENCES_SHOWBASICEXIF;ΠÏοβολή βασικών στοιχείων Exif +PREFERENCES_SHOWDATETIME;ΠÏοβολή ημεÏομηνίας και ÏŽÏας +PREFERENCES_SHOWONLYRAW;ΠÏοβολή μόνο αÏχείων RAW +PREFERENCES_SHTHRESHOLD;Κατώφλι ψαλιδίσματος σκιών +PREFERENCES_STARTUPIMDIR;Τοποθεσία εικόνων κατά την έναÏξη +PREFERENCES_TAB_BROWSER;ΠεÏιήγηση αÏχείου +PREFERENCES_TAB_COLORMGR;ΔιαχείÏιση χÏώματος +PREFERENCES_TAB_GENERAL;Γενικά +PREFERENCES_TAB_IMPROC;ΕπεξεÏγασίας εικόνας +PREFERENCES_TAB_OUTPUT;Επιλογές παÏαγωγής +PREFERENCES_THUMBSIZE;Μέγεθος εικονιδίου +PROFILEPANEL_FILEDLGFILTERANY;Οποιοφήποτε αÏχείο +PROFILEPANEL_FILEDLGFILTERPP;ΠÏοφίλ επεξεÏγασίας +PROFILEPANEL_LABEL;ΠÏοφίλ επεξεÏγασίας +PROFILEPANEL_LOADDLGLABEL;ΦόÏτωση παÏαμέτÏων επεξεÏγασίας... +PROFILEPANEL_PCUSTOM;ΠÏοσαÏμοσμένο +PROFILEPANEL_PFILE;Απο αÏχείο +PROFILEPANEL_PLASTPHOTO;Τελευταία φωτογÏαφία +PROFILEPANEL_PLASTSAVED;Τελευταία αποθηκευμένη +PROFILEPANEL_PROFILE;ΠÏοφίλ +PROFILEPANEL_SAVEDLGLABEL;Αποθήκευση παÏαμέτÏων επεξεÏγασίας... +PROFILEPANEL_TOOLTIPCOPY;Copy current profile to clipboard +PROFILEPANEL_TOOLTIPLOAD;ΦόÏτωση Ï€Ïοφίλ απο αÏχείο +PROFILEPANEL_TOOLTIPPASTE; Paste profile from clipboard +PROFILEPANEL_TOOLTIPSAVE;Αποθήκευση παÏόντος Ï€Ïοφίλ +PROGRESSBAR_DECODING;Αποκωδικοποίηση εικόνας... +PROGRESSBAR_DEMOSAICING;Demosaicing... +PROGRESSBAR_LOADING;ΦόÏτωση εικόνας... +PROGRESSBAR_LOADJPEG;ΦόÏτωση αÏχείου JPEG... +PROGRESSBAR_LOADPNG;ΦόÏτωση αÏχείου PNG... +PROGRESSBAR_LOADTIFF;ΦόÏτωση αÏχείου TIFF... +PROGRESSBAR_PROCESSING;ΕπεξεÏγάζεται εικόνα... +PROGRESSBAR_READY;Έτοιμο. +PROGRESSBAR_SAVEJPEG;Αποθήκευση αÏχείου JPEG... +PROGRESSBAR_SAVEPNG;Αποθήκευση αÏχείου PNG... +PROGRESSBAR_SAVETIFF;Αποθήκευση αÏχείου TIFF... +PROGRESSDLG_LOADING;Loading file... +PROGRESSDLG_PROCESSING;Processing image... +PROGRESSDLG_SAVING;Saving file... +QINFO_FOCALLENGTH;Εστιακή απόσταση +QINFO_ISO;ISO +QINFO_LENS;Lens +QINFO_NOEXIF;Στοιχεία Exif μη διαθέσιμα. +SAVEDLG_FILEFORMAT;Είδος αÏχείου +SAVEDLG_JPEGQUAL;Ποιότητα JPEG +SAVEDLG_JPGFILTER;ΑÏχεία JPEG +SAVEDLG_PNGCOMPR;Συμπίεση PNG +SAVEDLG_PNGFILTER;ΑÏχεία PNG +SAVEDLG_PUTTOQUEUEHEAD;Put to the head of the processing queue +SAVEDLG_PUTTOQUEUE;Put into processing queue +SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue +SAVEDLG_SAVEIMMEDIATELY;Save immediately +SAVEDLG_SAVESPP;Αποθήκευση παÏαμέτÏων επεξεÏγασίας μαζί με την εικόνα +SAVEDLG_TIFFFILTER;ΑÏχεία TIFF +TOOLBAR_TOOLTIP_CROP;Αποκοπή επιλογής (shortcut key: C) +TOOLBAR_TOOLTIP_HAND;ΕÏγαλείο μετακίνησης (shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Επιλογή ευθείας γÏαμμής (shortcut key: S) +TOOLBAR_TOOLTIP_WB;ΕξισοÏÏοπία Î»ÎµÏ…ÎºÎ¿Ï Î±Ï€ÏŒ σημείο (shortcut key: W) +TP_CACORRECTION_BLUE;Μπλέ +TP_CACORRECTION_LABEL;C/A ΔιόÏθωση +TP_CACORRECTION_RED;Κόκκινο +TP_CHMIXER_BLUE;Μπλέ +TP_CHMIXER_GREEN;ΠÏάσινο +TP_CHMIXER_LABEL;Μίξη καναλιών +TP_CHMIXER_RED;Κόκκινο +TP_COARSETRAF_DEGREE;γωνία: +TP_COARSETRAF_TOOLTIP_HFLIP;ΑναστÏοφή οÏιζόντια +TP_COARSETRAF_TOOLTIP_ROTLEFT;ΠεÏιστÏοφή αÏιστεÏά +TP_COARSETRAF_TOOLTIP_ROTRIGHT;ΠεÏιστÏοφή δεξιά +TP_COARSETRAF_TOOLTIP_VFLIP;ΑναστÏοφή κατακόÏυφα +TP_COLORBOOST_ACHANNEL;κανάλι "a" +TP_COLORBOOST_AMOUNT;Ένταση +TP_COLORBOOST_AVOIDCOLORCLIP;Αποφυγή ψαλιδίσματος χÏώματος +TP_COLORBOOST_BCHANNEL;κανάλι "b" +TP_COLORBOOST_CHAB;a & b +TP_COLORBOOST_CHANNEL;Κανάλι +TP_COLORBOOST_CHSEPARATE;ξεχωÏιστά +TP_COLORBOOST_ENABLESATLIMITER;ΕνεÏγοποίηση πεÏιοÏÎ¹ÏƒÎ¼Î¿Ï ÎºÎ¿ÏÎµÏƒÎ¼Î¿Ï +TP_COLORBOOST_LABEL;Ενίσχυση χÏώματος +TP_COLORBOOST_SATLIMIT;ΠεÏιοÏισμός κοÏÎµÏƒÎ¼Î¿Ï +TP_COLORDENOISE_EDGESENSITIVE;Ευαισθησία οÏίων +TP_COLORDENOISE_EDGETOLERANCE;Ανοχή οÏίων +TP_COLORDENOISE_LABEL;Μείωση χÏÏ‰Î¼Î±Ï„Î¹ÎºÎ¿Ï Î¸Î¿ÏÏβου +TP_COLORDENOISE_RADIUS;Ακτίνα +TP_COLORSHIFT_BLUEYELLOW;Μπλέ-ΚίτÏινο +TP_COLORSHIFT_GREENMAGENTA;ΠÏάσινο-Magenta +TP_COLORSHIFT_LABEL;Μετατόπιση χÏώματος +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Κλείδωμα αναλογίας: +TP_CROP_GTDIAGONALS;Κανόνας διαγωνίων +TP_CROP_GTHARMMEANS1;Harmonic means 1 +TP_CROP_GTHARMMEANS2;Harmonic means 2 +TP_CROP_GTHARMMEANS3;Harmonic means 3 +TP_CROP_GTHARMMEANS4;Harmonic means 4 +TP_CROP_GTNONE;Κανένα +TP_CROP_GTRULETHIRDS;Κανόνας Ï„Ïίτων +TP_CROP_GUIDETYPE;Είδος βοηθών: +TP_CROP_H;H +TP_CROP_LABEL;Αποκοπή +TP_CROP_SELECTCROP; Επιλογή αποκοπής +TP_CROP_W;W +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Ένταση +TP_DISTORTION_LABEL;ΠαÏαμόÏφωση +TP_EXPOSURE_AUTOLEVELS;Αυτόματα επίπεδα +TP_EXPOSURE_BLACKLEVEL;ΜαÏÏα +TP_EXPOSURE_BRIGHTNESS;Φωτεινότητα +TP_EXPOSURE_CLIP;Αποκοπή +TP_EXPOSURE_COMPRHIGHLIGHTS;Συμπίεση φωτεινών σημείων +TP_EXPOSURE_COMPRSHADOWS;Συμπίεση σκιών +TP_EXPOSURE_CONTRAST;Αντίθεση +TP_EXPOSURE_CURVEEDITOR;ΚαμπÏλη τονικότητας +TP_EXPOSURE_EXPCOMP;ΕπανόÏθωση Έκθεσης +TP_EXPOSURE_LABEL;Έκθεση +TP_HLREC_CIELAB;Ανάμιξη CIELab +TP_HLREC_COLOR;Διάδοση χÏώματος +TP_HLREC_LABEL;Ανάκτηση φωτεινών σημείων +TP_HLREC_LUMINANCE;Ανάκτηση Φωτεινότητας +TP_HLREC_METHOD;Μέθοδος: +TP_ICM_FILEDLGFILTERANY;Οποιοδήποτε αÏχείο +TP_ICM_FILEDLGFILTERICM;ΑÏχεία Ï€Ïοφίλ ICC +TP_ICM_GAMMABEFOREINPUT;Το Ï€Ïοφίλ αλλάζει την gamma +TP_ICM_INPUTCAMERA;ΠÏοεπιλογή φωτογÏαφικής μηχανής +TP_ICM_INPUTCUSTOM;ΠÏοσαÏμοσμένο +TP_ICM_INPUTDLGLABEL;Επιλέξτε Ï€Ïοφιλ ICC εισόδου... +TP_ICM_INPUTEMBEDDED;ΧÏήση ενσωματωμένου, αν αυτό είναι δυνατό +TP_ICM_INPUTPROFILE;ΠÏοφίλ εισαγωγής +TP_ICM_LABEL;ICM +TP_ICM_NOICM;No ICM: sRGB output +TP_ICM_OUTPUTDLGLABEL;Επιλέξτε Ï€Ïοφιλ ICC εξόδου... +TP_ICM_OUTPUTPROFILE;ΠÏοφίλ εξόδου +TP_ICM_SAVEREFERENCE;Αποθήκευση εικόνας ως αναφοÏά για δημιουÏγία Ï€Ïοφίλ. +TP_ICM_WORKINGPROFILE;ΠαÏόν Ï€Ïοφίλ +TP_LUMACURVE_BLACKLEVEL;ΜαÏÏα +TP_LUMACURVE_BRIGHTNESS;Φωτεινότητα +TP_LUMACURVE_COMPRHIGHLIGHTS;Συμπίεση φωτεινών σημείων +TP_LUMACURVE_COMPRSHADOWS;Συμπίεση σκιών +TP_LUMACURVE_CONTRAST;Αντίθεση +TP_LUMACURVE_CURVEEDITOR;ΚαμπÏλη φωτεινότητας +TP_LUMACURVE_LABEL;ΚαμπÏλη φωτεινότητας +TP_LUMADENOISE_EDGETOLERANCE;Ανοχή οÏίων +TP_LUMADENOISE_LABEL;Μείωση θοÏÏβου φωτεινότητας +TP_LUMADENOISE_RADIUS;Ακτίνα +TP_RESIZE_BICUBIC;Bicubic +TP_RESIZE_BICUBICSF;Bicubic (Softer) +TP_RESIZE_BICUBICSH;Bicubic (Sharper) +TP_RESIZE_BILINEAR;Bilinear +TP_RESIZE_FULLSIZE;ΠλήÏες μέγεθος εικόνας: +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Αλλαγή μεγέθους +TP_RESIZE_METHOD;Μέθοδος: +TP_RESIZE_NEAREST;Nearest +TP_RESIZE_SCALE;Κλίμακα +TP_RESIZE_W;W: +TP_ROTATE_AUTOCROP;Αυτόματη αποκοπή +TP_ROTATE_DEGREE;Γωνία +TP_ROTATE_FILL;Γέμισμα εικόνας +TP_ROTATE_LABEL;ΠεÏιστÏοφή +TP_ROTATE_SELECTLINE; Επιλογή ευθείας +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Φωτεινά σημεία +TP_SHADOWSHLIGHTS_HLTONALW;Τονικό εÏÏος +TP_SHADOWSHLIGHTS_LABEL;Σκιές/Φωτεινά σημεία +TP_SHADOWSHLIGHTS_LOCALCONTR;Τοπική αντίθεση +TP_SHADOWSHLIGHTS_RADIUS;Ακτίνα +TP_SHADOWSHLIGHTS_SHADOWS;Σκιές +TP_SHADOWSHLIGHTS_SHTONALW;Τονικό εÏÏος +TP_SHARPENING_AMOUNT;Ένταση +TP_SHARPENING_EDRADIUS;Ακτίνα +TP_SHARPENING_EDTOLERANCE;Ανοχή οÏίων +TP_SHARPENING_HALOCONTROL;Έλεγχος άλως +TP_SHARPENING_HCAMOUNT;Ένταση +TP_SHARPENING_LABEL;Όξυνση +TP_SHARPENING_METHOD;Μέθοδος +TP_SHARPENING_ONLYEDGES;Όξυνση μόνο οÏίων +TP_SHARPENING_RADIUS;Ακτίνα +TP_SHARPENING_RLD_AMOUNT;Ένταση +TP_SHARPENING_RLD_DAMPING;Απόσβεση +TP_SHARPENING_RLD_ITERATIONS;Επαναλήψεις +TP_SHARPENING_RLD;RL Deconvolution +TP_SHARPENING_THRESHOLD;Κατώφλι +TP_SHARPENING_USM;Unsharp Mask +TP_VIGNETTING_AMOUNT;Ένταση +TP_VIGNETTING_LABEL;ΔιόÏθωση vignetting +TP_VIGNETTING_RADIUS;Ακτίνα +TP_WBALANCE_AUTO;Αυτόματο +TP_WBALANCE_CAMERA;ΦωτογÏαφικής μηχανής +TP_WBALANCE_CUSTOM;ΠÏοσαÏμοσμένο +TP_WBALANCE_GREEN;ΑπόχÏωση +TP_WBALANCE_LABEL;ΕξισοÏÏόπηση Î»ÎµÏ…ÎºÎ¿Ï +TP_WBALANCE_METHOD;Μέθοδος +TP_WBALANCE_SIZE;Μέγεθος: +TP_WBALANCE_SPOTWB;Εξ.Λ. σημείου +TP_WBALANCE_TEMPERATURE;ΘεÏμοκÏασία +ZOOMBAR_DETAIL;ΛεπτομέÏεια +ZOOMBAR_HUGE;ΤεÏάστιο +ZOOMBAR_LARGE;Μεγάλο +ZOOMBAR_NORMAL;Κανονικό +ZOOMBAR_PREVIEW;ΠÏοεπισκόπηση +ZOOMBAR_SCALE;Κλίμακα +ZOOMBAR_SMALL;ΜικÏÏŒ + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Hebrew b/rtdata/languages/Hebrew new file mode 100644 index 000000000..d36a69924 --- /dev/null +++ b/rtdata/languages/Hebrew @@ -0,0 +1,703 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# Hebrew +# 21.02.2008: initially translated by ??? +# ---------------------------------------------- +ADJUSTER_RESET_TO_DEFAULT;ברירת מחדל +CURVEEDITOR_FILEDLGFILTERANY;×§×‘×¦×™× ×›×œ×©×”× +CURVEEDITOR_FILEDLGFILTERCURVE;קבצי עקמות +CURVEEDITOR_LINEAR;ישיר +CURVEEDITOR_LOADDLGLABEL;הטען עקמה +CURVEEDITOR_SAVEDLGLABEL;שמור עקמה +CURVEEDITOR_TOOLTIPLINEAR;החזר עקמה לישירה +CURVEEDITOR_TOOLTIPLOAD;הטען עקמה +CURVEEDITOR_TOOLTIPSAVE;שמור עקמה נוכחית +EXIFFILTER_APERTURE;Aperture +EXIFFILTER_CAMERA;Camera +EXIFFILTER_DIALOGLABEL;Exif Filter +EXIFFILTER_FOCALLEN;Focal Length +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Lens +EXIFFILTER_SHUTTER;Shutter +EXIFPANEL_ADDEDIT;Add/Edit +EXIFPANEL_ADDEDITHINT;Add new tag or edit tag +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Enter value +EXIFPANEL_ADDTAGDLG_SELECTTAG;Select tag +EXIFPANEL_ADDTAGDLG_TITLE;Add/Edit Tag +EXIFPANEL_KEEPHINT;Keep the selected tags when writing output file +EXIFPANEL_KEEP;Keep +EXIFPANEL_REMOVEHINT;Remove the selected tags when writing output file +EXIFPANEL_REMOVE;Remove +EXIFPANEL_RESETALLHINT;Reset all tags to their original values +EXIFPANEL_RESETALL;Reset All +EXIFPANEL_RESETHINT;Reset the selected tags to their original values +EXIFPANEL_RESET;Reset +EXIFPANEL_SUBDIRECTORY;Subdirectory +FILEBROWSER_APPLYPROFILE;Apply profile +FILEBROWSER_ARRANGEMENTHINT;Change between vertical/horizontal alignment of thumbnails +FILEBROWSER_CLEARPROFILE;Clear profile +FILEBROWSER_COPYPROFILE;Copy profile +FILEBROWSER_DELETEDLGLABEL;File delete confirmation +FILEBROWSER_DELETEDLGMSG;Are you sure you want to delete the selected %1 files? +FILEBROWSER_EMPTYTRASH;Empty Trash +FILEBROWSER_EMPTYTRASHHINT;Permanently delete the files of the trash +FILEBROWSER_EXIFFILTERAPPLY;Apply +FILEBROWSER_EXIFFILTERAPPLYHINT;Switch on/off exif filter of the file browser +FILEBROWSER_EXIFFILTERLABEL;Exif Filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Change settings of the exif filter +FILEBROWSER_EXIFFILTERSETTINGS;Setup +FILEBROWSER_PARTIALPASTEPROFILE;Partial paste +FILEBROWSER_PASTEPROFILE;Paste profile +FILEBROWSER_POPUPCANCELJOB;Cancel job +FILEBROWSER_POPUPMOVEEND;Move to end of queue +FILEBROWSER_POPUPMOVEHEAD;Move to head of queue +FILEBROWSER_POPUPOPEN;Open +FILEBROWSER_POPUPPROCESS;Put to processing queue +FILEBROWSER_POPUPRANK1;Rank 1 +FILEBROWSER_POPUPRANK2;Rank 2 +FILEBROWSER_POPUPRANK3;Rank 3 +FILEBROWSER_POPUPRANK4;Rank 4 +FILEBROWSER_POPUPRANK5;Rank 5 +FILEBROWSER_POPUPREMOVE;Remove from filesystem +FILEBROWSER_POPUPRENAME;Rename +FILEBROWSER_POPUPSELECTALL;Select all +FILEBROWSER_POPUPTRASH;Move to trash +FILEBROWSER_POPUPUNRANK;Unrank +FILEBROWSER_POPUPUNTRASH;Remove from trash +FILEBROWSER_PROCESSINGSETTINGSHINT;Set the file format and output directory +FILEBROWSER_PROCESSINGSETTINGS;Settings +FILEBROWSER_RENAMEDLGLABEL;Rename file +FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +FILEBROWSER_SHOWDIRHINT;Show all images of the directory +FILEBROWSER_SHOWQUEUEHINT;Show content of the processing queue +FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1 star +FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2 star +FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3 star +FILEBROWSER_SHOWRANK4HINT;Show images ranked as 4 star +FILEBROWSER_SHOWRANK5HINT;Show images ranked as 5 star +FILEBROWSER_SHOWTRASHHINT;Show content of the trash +FILEBROWSER_SHOWUNRANKHINT;Show unranked images +FILEBROWSER_STARTPROCESSINGHINT;Start processing/saving of images in the queue +FILEBROWSER_STARTPROCESSING;Start Processing +FILEBROWSER_STOPPROCESSINGHINT;Stop processing of images +FILEBROWSER_STOPPROCESSING;Stop processing +FILEBROWSER_THUMBSIZE;Thumb. size +FILEBROWSER_ZOOMINHINT;Increase thumbnail size +FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size +GENERAL_ABOUT;×ודות +GENERAL_CANCEL;בטל +GENERAL_DISABLED;מבוטל +GENERAL_DISABLE;בטל +GENERAL_ENABLED;מופעל +GENERAL_ENABLE;הפעל +GENERAL_LANDSCAPE;נוף +GENERAL_LOAD;הטען +GENERAL_NA;×ין +GENERAL_NO;×œ× +GENERAL_OK;שמור +GENERAL_PORTRAIT;דיוקן +GENERAL_SAVE;שמור +GENERAL_YES;כן +HISTOGRAM_LABEL;Histogram +HISTOGRAM_TOOLTIP_B;Show/הסתר ×”×™×¡×˜×•×’×¨× ×›×—×•×œ +HISTOGRAM_TOOLTIP_G;Show/הסתר ×”×™×¡×˜×•×’×¨× ×™×¨×•×§ +HISTOGRAM_TOOLTIP_L;Show/CIELAB הסתר ×”×™×¡×˜×•×’×¨× +HISTOGRAM_TOOLTIP_R;Show/הסתר ×”×™×¡×˜×•×’×¨× ××“×•× +HISTORY_CHANGED;Changed +HISTORY_CUSTOMCURVE;עקמה מות×מת +HISTORY_DELSNAPSHOT;הסר ×ª×¦×œ×•× +HISTORY_FROMCLIPBOARD;From clipboard +HISTORY_LABEL;היסטוריה +HISTORY_MSG_10;דחיסת ×’×•×•× ×™× ×›×”×™× +HISTORY_MSG_11;עקמת ×’×•×•× ×™× +HISTORY_MSG_12;חשיפה ×וטומטית +HISTORY_MSG_13;קיצוץ החסיפה +HISTORY_MSG_14;×”×רה - בהירות +HISTORY_MSG_15;×”×רה - ניגודיות +HISTORY_MSG_16;×”×רה - שחור +HISTORY_MSG_17;×”×רה - דחיסת ×’×•×•× ×™× ×‘×”×™×¨×™× +HISTORY_MSG_18;×”×רה - דחיסת ×’×•×•× ×™× ×›×”×™× +HISTORY_MSG_19;×”×רה - עקמה +HISTORY_MSG_1;×¦×™×œ×•× ×˜×¢×•×Ÿ +HISTORY_MSG_20;חידוד +HISTORY_MSG_21;חידוד - רדיוס +HISTORY_MSG_22;חידוד - כמות +HISTORY_MSG_23;חידוד - סף +HISTORY_MSG_24;חידוד - רק קצוות +HISTORY_MSG_25;חידוד - רדיוס גילוי קצוות +HISTORY_MSG_26;חידוד - סבילות קצוות +HISTORY_MSG_27;חידוד - בקרת הילה +HISTORY_MSG_28;בקרת הילה, כמות +HISTORY_MSG_29;שיטת החידוד +HISTORY_MSG_2;פרופיל טעון +HISTORY_MSG_30;דיקונבולוציה - רדיוס +HISTORY_MSG_31;גיקונבולוציה - כמות +HISTORY_MSG_32;גיקונבולוציה - ריסון +HISTORY_MSG_33;גיקונבולוציה - חזרות +HISTORY_MSG_34;המנע מקיצוץ צבע +HISTORY_MSG_35;הגבלת רויה +HISTORY_MSG_36;גבול רויה +HISTORY_MSG_37;הגברת צבע +HISTORY_MSG_38;שיטת ×יזון לבן +HISTORY_MSG_39;מידת ×—×•× +HISTORY_MSG_3;פרופיל הוחלף +HISTORY_MSG_40;גיוון ×יזון צבע +HISTORY_MSG_41;העברת צבע × +HISTORY_MSG_42;העברת צבע ב +HISTORY_MSG_43;הסרת רעש בהירות +HISTORY_MSG_44;הסרת רעש בהירות רדיוס +HISTORY_MSG_45;הסרת רעש בהירות סבילות קצוות +HISTORY_MSG_46;הסרת רעש צבעוני +HISTORY_MSG_47;הסרת רעש צבעוני רדיוס +HISTORY_MSG_48;הסרת רעש צבעוני סבילות קצוות +HISTORY_MSG_49;הסרת רעש צבעוני רגישות לקצוות +HISTORY_MSG_4;דיפדוף בהיסטוריה +HISTORY_MSG_50;כלי בהירי×\×›×”×™× +HISTORY_MSG_51;הגברת ×’×•×•× ×™× ×‘×”×™×¨×™× +HISTORY_MSG_52;ההגברת ×’×•×•× ×™× ×›×”×™× +HISTORY_MSG_53;בהירי×, רוחב ×’×•×•× ×™× +HISTORY_MSG_54;×›×”×™×, רוחב ×’×•×•× ×™× +HISTORY_MSG_55;ניגודיות מקומית +HISTORY_MSG_56;בהירי×\×›×”×™× ×¨×“×™×•×¡ +HISTORY_MSG_57;סיבוב גס +HISTORY_MSG_58;היפוך ×ופקי +HISTORY_MSG_59;היפוך ×× ×›×™ +HISTORY_MSG_5;בהירות +HISTORY_MSG_60;סיבוב +HISTORY_MSG_61;סיבוב +HISTORY_MSG_62;תיקון עיוות בעדשה +HISTORY_MSG_63;סימניה נבחרה +HISTORY_MSG_64;גזירת ×ª×¦×œ×•× +HISTORY_MSG_65;C/A תיקון עיוות +HISTORY_MSG_66;שחזור ×’×•×•× ×™× ×‘×”×™×¨×™× +HISTORY_MSG_67;שחזור ×’×•×•× ×™× ×‘×”×™×¨×™×, כמות +HISTORY_MSG_68;שחזור ×’×•×•× ×™× ×‘×”×™×¨×™×, שיטה +HISTORY_MSG_69;מרחב צבע עבודה +HISTORY_MSG_6;ניגודיות +HISTORY_MSG_70;מרחב צבע ×™×™×¦×•× +HISTORY_MSG_71;מרחב צבע ×™×™×‘×•× +HISTORY_MSG_72;תיקון פינות כהות +HISTORY_MSG_73;מערבב ×¢×¨×•×¦×™× +HISTORY_MSG_74;מידת שינוי גודל +HISTORY_MSG_75;שיטת שינוי גודל +HISTORY_MSG_76;Exif Metadata +HISTORY_MSG_77;IPTC Metadata +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;שחור +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;פיצוי חשיפה +HISTORY_MSG_9;דחיסת ×’×•×•× ×™× ×‘×”×™×¨×™× +HISTORY_NEWSNAPSHOTAS;×‘×©× +HISTORY_NEWSNAPSHOT;×ª×¦×œ×•× ×—×“×© +HISTORY_NEWSSDIALOGLABEL;×©× ×”×ª×¦×œ×•× +HISTORY_NEWSSDIALOGTITLE;הוסף ×ª×¦×œ×•× ×—×“×© +HISTORY_SETTO;העבר ×ל +HISTORY_SNAPSHOTS;×ª×¦×œ×•×ž×™× +HISTORY_SNAPSHOT;×ª×¦×œ×•× +ICMPANEL_FILEDLGFILTERANY;×§×‘×¦×™× ×›×œ×©×”× +ICMPANEL_FILEDLGFILTERICM;ICC קבצי צבע +ICMPANEL_GAMMABEFOREINPUT;Profile applies Gamma +ICMPANEL_INPUTCAMERA;ברירת מחדל המצלמה +ICMPANEL_INPUTCUSTOM;מות×× +ICMPANEL_INPUTDLGLABEL;בחר בפרופיל צבע ×™×™×‘×•× +ICMPANEL_INPUTEMBEDDED;השתמש בפרופיל משובץ,×× ×פשר +ICMPANEL_INPUTPROFILE;פרופיל ×™×™×‘×•× +ICMPANEL_NOICM;sRGB×œ×œ× × ×™×”×•×œ צבע - ×™×™×¦×•× ×‘ +ICMPANEL_OUTPUTDLGLABEL;בחר בפרופיל צבע ×™×™×¦×•× +ICMPANEL_OUTPUTPROFILE;פרופיל ×™×™×¦×•× +ICMPANEL_SAVEREFERENCE;Save reference image for profiling +ICMPANEL_WORKINGPROFILE;פרופיל עבודה +IMAGEAREA_DETAILVIEW;תצוגת ×¤×¨×˜×™× +IPTCPANEL_AUTHOR;Author +IPTCPANEL_AUTHORHINT;Name of the creator of the object, e.g. writer, photographer or graphic artist (By-line). +IPTCPANEL_AUTHORSPOSITION;Author's position +IPTCPANEL_AUTHORSPOSITIONHINT;Title of the creator or creators of the object (By-line Title). +IPTCPANEL_CAPTION;Caption +IPTCPANEL_CAPTIONHINT;A textual description of the data (Caption - Abstract) +IPTCPANEL_CAPTIONWRITER;Caption Writer +IPTCPANEL_CAPTIONWRITERHINT;The name of the person involved in the writing, editing or correcting the image or caption/abstract (Writer - Editor). +IPTCPANEL_CATEGORY;Category +IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider (Category). +IPTCPANEL_CITY;City +IPTCPANEL_CITYHINT;City of image origin (City). +IPTCPANEL_COPYHINT;Copy IPTC settings to clipboard +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COPYRIGHTHINT;Any necessary copyright notice (Copyright Notice). +IPTCPANEL_COUNTRY;Country +IPTCPANEL_COUNTRYHINT;The name of the country/primary location where the image was created (Country - Primary Location Name). +IPTCPANEL_CREDIT;Credit +IPTCPANEL_CREDITHINT;Identifies the provider of the image, not necessarily the owner/creator (Credit). +IPTCPANEL_DATECREATED;Date Created +IPTCPANEL_DATECREATEDHINT;The date the intellectual content of the image was created; Format: JJJJMMTT (Date Created). +IPTCPANEL_EMBEDDED;Embedded +IPTCPANEL_EMBEDDEDHINT;Reset to IPTC data embedded in the image file +IPTCPANEL_HEADLINE;Headline +IPTCPANEL_HEADLINEHINT;A publishable entry providing a synopsis of the contents of the image (Headline). +IPTCPANEL_INSTRUCTIONSHINT;Other editorial instructions concerning the use of the image (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Instructions +IPTCPANEL_KEYWORDSHINT;Used to indicate specific information retrieval words (Keywords). +IPTCPANEL_KEYWORDS;Keywords +IPTCPANEL_PASTEHINT;Paste IPTC settings from clipboard +IPTCPANEL_PROVINCEHINT;The Province/State where the image originates (Province-State). +IPTCPANEL_PROVINCE;Province +IPTCPANEL_RESETHINT;Reset to profile default +IPTCPANEL_RESET;Reset +IPTCPANEL_SOURCEHINT;The original owner of the intellectual content of the image (Source). +IPTCPANEL_SOURCE;Source +IPTCPANEL_SUPPCATEGORIESHINT;Further refines the subject of the image (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Suppl. Categories +IPTCPANEL_TITLEHINT;A shorthand reference for the image (Object Name). +IPTCPANEL_TITLE;Title +IPTCPANEL_TRANSREFERENCEHINT;A code representing the location of original transmission (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Trans. Reference +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;העדפויות +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;שמור ×‘×©× +MAIN_BUTTON_SAVE;שמור ×¦×™×œ×•× +MAIN_BUTTON_SENDTOEDITOR;Send to editor +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;הקובץ כבר ×§×™×™× +MAIN_MSG_CANNOTLOAD;×œ× ×™×›×•×œ להעלות ×ת הקובץ +MAIN_MSG_CANNOTSAVE;טעות בשמירת הקובץ +MAIN_MSG_CANNOTSTARTEDITOR;Can not start editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Please set the correct path in the "Preferences" dialog. +MAIN_MSG_EXITJOBSINQUEUEINFO;Unprocessed images in the queue will be lost on exit. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Are you sure you want to exit? There are unprocessed images waiting in the queue. +MAIN_MSG_JOBSINQUEUE;עבודות בתור +MAIN_MSG_QOVERWRITE;?רצונך לכתוב ×ותו מחדש? +MAIN_TAB_BASIC;יסודות +MAIN_TAB_COLOR;Color +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Exposure +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ניהול צבע +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;התמרות +MAIN_TOOLTIP_HIDEFP;גלה\הסתר לוח תחתון - דפדפן (shortcut key: F) +MAIN_TOOLTIP_HIDEHP;גלה\הסתר לוח שמ×לי - היסטוריה (shortcut key: F) +MAIN_TOOLTIP_INDCLIPPEDH;סימן ×œ×’×•×•× ×™× ×‘×”×™×¨×™× ×ž×§×•×¦×¦×™× +MAIN_TOOLTIP_INDCLIPPEDS;סימן ×œ×’×•×•× ×™× ×›×”×™× ×ž×§×•×¦×¦×™× +MAIN_TOOLTIP_PREFERENCES;קבע העדפויות +MAIN_TOOLTIP_QINFO;מידע מהיר ×ודות ×”×¦×™×œ×•× +MAIN_TOOLTIP_SAVEAS;שמור לתיק נבחר +MAIN_TOOLTIP_SAVE;שמור לתיק ברירת המחדל +PARTIALPASTE_BASICGROUP;Basic settings +PARTIALPASTE_CACORRECTION;C/A correction +PARTIALPASTE_COARSETRANS;90 deg rotation / flipping +PARTIALPASTE_COLORBOOST;Color boost +PARTIALPASTE_COLORDENOISE;Color denoise +PARTIALPASTE_COLORGROUP;Color related settings +PARTIALPASTE_COLORMIXER;Color mixer +PARTIALPASTE_COLORSHIFT;Color shift +PARTIALPASTE_COMPOSITIONGROUP;Composition settings +PARTIALPASTE_CROP;Crop +PARTIALPASTE_DIALOGLABEL;Partial paste processing profile +PARTIALPASTE_DISTORTION;Distortion correction +PARTIALPASTE_EXIFCHANGES;Changes to exif data +PARTIALPASTE_EXPOSURE;Exposure +PARTIALPASTE_HLRECOVERY;Highlight recovery +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Lens related settings +PARTIALPASTE_LUMACURVE;Luminance curve +PARTIALPASTE_LUMADENOISE;Luminance noise reduction +PARTIALPASTE_LUMINANCEGROUP;Luminance related settings +PARTIALPASTE_METAICMGROUP;Metadata/ICM settings +PARTIALPASTE_RESIZE;Resize +PARTIALPASTE_ROTATION;Rotation +PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights +PARTIALPASTE_SHARPENING;Sharpening +PARTIALPASTE_VIGNETTING;Vignetting correction +PARTIALPASTE_WHITEBALANCE;White balance +PREFERENCES_APPLNEXTSTARTUP;×™×™×•×©× ×‘×תחול ×”×‘× +PREFERENCES_BLINKCLIPPED;הבהוב ב×זור המקוצץ +PREFERENCES_CACHECLEARALL;Clear All +PREFERENCES_CACHECLEARPROFILES;Clear Profiles +PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +PREFERENCES_CACHEFORMAT1;Proprietary (faster and better quality) +PREFERENCES_CACHEFORMAT2;JPEG (smaller disk footprint) +PREFERENCES_CACHEMAXENTRIES;Maximal Number of Cache Entries +PREFERENCES_CACHEOPTS;Cache Options +PREFERENCES_CACHESTRAT1;Prefer Speed to Low Memory Consumption +PREFERENCES_CACHESTRAT2;Prefer Low Memory Consumption to Speed +PREFERENCES_CACHESTRAT;Cache Strategy +PREFERENCES_CACHETHUMBFORM;Cache Thumbnail Format +PREFERENCES_CACHETHUMBHEIGHT;Maximal Thumbnail Height +PREFERENCES_CLEARDLG_LINE1;Clearing cache +PREFERENCES_CLEARDLG_LINE2;This may take a few seconds. +PREFERENCES_CLEARDLG_TITLE;Please wait +PREFERENCES_CLIPPINGIND;סימון קיצוץ +PREFERENCES_CMETRICINTENT;כוונה קולורמטרית +PREFERENCES_DATEFORMATHINT;You can use the following formatting strings:\n%y : year\n%m : month\n%d : day\n\nFor example, the hungarian date format is:\n%y/%m/%d +PREFERENCES_DATEFORMAT;צורת ת×ריך +PREFERENCES_DEFAULTLANG;שפה ברירת המחדל +PREFERENCES_DEFAULTTHEME;Default theme +PREFERENCES_DEMOSAICINGALGO;××œ×’×•×¨×™×ª× ×“×™×ž×•×–××™×§ +PREFERENCES_DIRHOME;תיקיית הבית +PREFERENCES_DIRLAST;תיקיה ×”×חרונה שביקרתי בה +PREFERENCES_DIROTHER;×חר +PREFERENCES_DIRSELECTDLG;בחר תיקיית ×¦×™×œ×•×ž×™× ×œ×תחול +PREFERENCES_DIRSOFTWARE;תיקיית התקנה +PREFERENCES_DMETHOD;שיטה +PREFERENCES_EDITORCMDLINE;Other command line +PREFERENCES_EXTERNALEDITOR;External editor +PREFERENCES_FALSECOLOR;דחיית צבע מסולף +PREFERENCES_FBROWSEROPTS;ברירות דפדפן +PREFERENCES_FILEFORMAT;תצורת קובץ +PREFERENCES_FORIMAGE;עבור קבצי ×¦×™×œ×•× +PREFERENCES_FORRAW;RAW עבור קבצי +PREFERENCES_GIMPPATH;GIMP installation directory +PREFERENCES_GTKTHEME;GTK default +PREFERENCES_HINT;רמז +PREFERENCES_HLTHRESHOLD;סף קיצוץ עליון +PREFERENCES_ICCDIR;ICC תיקיית פרופילי צבע +PREFERENCES_IMPROCPARAMS;נתוני עיבוד ברירת המחדל +PREFERENCES_INTENT_ABSOLUTE;קולורמטרית מוחלטת +PREFERENCES_INTENT_PERCEPTUAL;תפיסתית +PREFERENCES_INTENT_RELATIVE;קולורמטרית יחסית +PREFERENCES_INTENT_SATURATION;רויה +PREFERENCES_LIVETHUMBNAILS;Live Thumbnails (slower) +PREFERENCES_MONITORICC;פרופיל מסך +PREFERENCES_OUTDIRFOLDERHINT;Put the saved images to the seledted folder +PREFERENCES_OUTDIRFOLDER;Save to folder +PREFERENCES_OUTDIRHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Use Template +PREFERENCES_OUTDIR;תיקיית ×™×™×¦×•× +PREFERENCES_PARSEDEXTADD;Add Extension +PREFERENCES_PARSEDEXTADDHINT;Type an extension and press this button to append list +PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list +PREFERENCES_PARSEDEXT;Parsed Extensions +PREFERENCES_PROFILEHANDLING;Processing Profile Handling +PREFERENCES_PROFILELOADPR;Profile Loading Priority +PREFERENCES_PROFILEPRCACHE;Profile in Cache +PREFERENCES_PROFILEPRFILE;Profile Next to the Input File +PREFERENCES_PROFILESAVECACHE;Save Processing Parameters to the Cache +PREFERENCES_PROFILESAVEINPUT;Save Processing Parameters Next to the Input File +PREFERENCES_PSPATH;Adobe Photoshop installation directory +PREFERENCES_SELECTICCDIRDLG;ICC בחר תיקיית פרופילי צבע +PREFERENCES_SELECTLANG;בחר שפה +PREFERENCES_SELECTMONITORPROFDLG;של התצוגה ICC בחר פרופיל +PREFERENCES_SELECTTHEME;Select theme +PREFERENCES_SHOWBASICEXIF;Exif הר××” מידע +PREFERENCES_SHOWDATETIME;הר××” ת×ריך ושעה +PREFERENCES_SHOWONLYRAW;RAW הר××” רק קבצי +PREFERENCES_SHTHRESHOLD;סף קיצוץ תחתון +PREFERENCES_STARTUPIMDIR;תיקיית ×¦×™×œ×•×ž×™× ×‘×תחול +PREFERENCES_TAB_BROWSER;דפדפן ×§×‘×¦×™× +PREFERENCES_TAB_COLORMGR;ניהול ×¦×‘×¢×™× +PREFERENCES_TAB_GENERAL;כללי +PREFERENCES_TAB_IMPROC;עיבוד ×¦×™×œ×•× +PREFERENCES_TAB_OUTPUT;×פשרויות ×™×™×¦×•× +PREFERENCES_THUMBSIZE;גודל תמונות ממוזערות +PROFILEPANEL_FILEDLGFILTERANY;×§×‘×¦×™× ×›×œ×©×”× +PROFILEPANEL_FILEDLGFILTERPP;פרופילי עיבוד +PROFILEPANEL_LABEL;פרופילי עיבוד +PROFILEPANEL_LOADDLGLABEL;הטען נתוני עיבוד +PROFILEPANEL_PCUSTOM;מות×× +PROFILEPANEL_PFILE;מקובץ +PROFILEPANEL_PLASTPHOTO;×¦×™×œ×•× ×חרון +PROFILEPANEL_PLASTSAVED;נשמר ×חרון +PROFILEPANEL_PROFILE;פרופיל +PROFILEPANEL_SAVEDLGLABEL;שמור נתוני עיבוד +PROFILEPANEL_TOOLTIPCOPY;Copy current profile to clipboard +PROFILEPANEL_TOOLTIPLOAD;הטען פרופיל מקובץ +PROFILEPANEL_TOOLTIPPASTE; Paste profile from clipboard +PROFILEPANEL_TOOLTIPSAVE;שמור פרופיל נוכחי +PROGRESSBAR_DECODING;מפענח קובץ +PROGRESSBAR_DEMOSAICING;מעבד ×¦×™×œ×•× +PROGRESSBAR_LOADING;מטעין ×¦×™×œ×•× +PROGRESSBAR_LOADJPEG;JPG מטעין קובץ +PROGRESSBAR_LOADPNG;PNG מטעין קובץ +PROGRESSBAR_LOADTIFF;TIFF מטעין קובץ +PROGRESSBAR_PROCESSING;מעבד ×¦×™×œ×•× +PROGRESSBAR_READY;מוכן +PROGRESSBAR_SAVEJPEG;JPG שומר קובץ +PROGRESSBAR_SAVEPNG;PNG שומר קובץ +PROGRESSBAR_SAVETIFF;TIFF שומר קובץ +PROGRESSDLG_LOADING;Loading file... +PROGRESSDLG_PROCESSING;Processing image... +PROGRESSDLG_SAVING;Saving file... +QINFO_FOCALLENGTH;×ורך מוקד +QINFO_ISO;ISO +QINFO_LENS;Lens +QINFO_NOEXIF;המידע ×œ× ×–×ž×™×Ÿ +SAVEDLG_FILEFORMAT;תצורת קובץ +SAVEDLG_JPEGQUAL;JPEG ×יכות +SAVEDLG_JPGFILTER;JPEG קבצי +SAVEDLG_PNGCOMPR;PNG דחיסת +SAVEDLG_PNGFILTER;PNG קבצי +SAVEDLG_PUTTOQUEUEHEAD;Put to the head of the processing queue +SAVEDLG_PUTTOQUEUE;Put into processing queue +SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue +SAVEDLG_SAVEIMMEDIATELY;Save immediately +SAVEDLG_SAVESPP;שמור נתוני עיבוד ×¢× ×”×¦×™×œ×•× +SAVEDLG_TIFFFILTER;TIFF קבצי +TOOLBAR_TOOLTIP_CROP;בחירת גזירה (shortcut key: C) +TOOLBAR_TOOLTIP_HAND;כלי יד (shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;בחירת קו ישר (shortcut key: S) +TOOLBAR_TOOLTIP_WB;×יזון לבן נקודתי (shortcut key: W) +TP_CACORRECTION_BLUE;כחול +TP_CACORRECTION_LABEL;C/A תיקון +TP_CACORRECTION_RED;××“×•× +TP_CHMIXER_BLUE;כחול +TP_CHMIXER_GREEN;ירוק +TP_CHMIXER_LABEL;מערבב ×¢×¨×•×¦×™× +TP_CHMIXER_RED;××“×•× +TP_COARSETRAF_DEGREE;מעלות +TP_COARSETRAF_TOOLTIP_HFLIP;הפוך ×ופקי +TP_COARSETRAF_TOOLTIP_ROTLEFT;סובב שמ×לה +TP_COARSETRAF_TOOLTIP_ROTRIGHT;סובב ימינה +TP_COARSETRAF_TOOLTIP_VFLIP;הפוך ×× ×›×™ +TP_COLORBOOST_ACHANNEL;ערוץ × +TP_COLORBOOST_AMOUNT;כמות +TP_COLORBOOST_AVOIDCOLORCLIP;הימנע מקיצוץ צבע +TP_COLORBOOST_BCHANNEL;ערוץ ב +TP_COLORBOOST_CHAB;'×'/ב +TP_COLORBOOST_CHANNEL;ערוץ +TP_COLORBOOST_CHSEPARATE;ליחוד +TP_COLORBOOST_ENABLESATLIMITER;הגבל רויה +TP_COLORBOOST_LABEL;הגברת צבע +TP_COLORBOOST_SATLIMIT;גבול רויה +TP_COLORDENOISE_EDGESENSITIVE;רגישות לקצוות +TP_COLORDENOISE_EDGETOLERANCE;סבילות לקצוות +TP_COLORDENOISE_LABEL;הסרת רעש צבעוני +TP_COLORDENOISE_RADIUS;רדיוס +TP_COLORSHIFT_BLUEYELLOW;צהוב-כחול +TP_COLORSHIFT_GREENMAGENTA;מג'נטה-ירוק +TP_COLORSHIFT_LABEL;העברת צבע +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;קבע יחס +TP_CROP_GTDIAGONALS;כלל ×”×לכסון +TP_CROP_GTHARMMEANS1;×ž×ž×•×¦× ×”×¨×ž×•× ×™ 1 +TP_CROP_GTHARMMEANS2;×ž×ž×•×¦× ×”×¨×ž×•× ×™ 2 +TP_CROP_GTHARMMEANS3;×ž×ž×•×¦× ×”×¨×ž×•× ×™ 3 +TP_CROP_GTHARMMEANS4;×ž×ž×•×¦× ×”×¨×ž×•× ×™ 4 +TP_CROP_GTNONE;×œ×œ× +TP_CROP_GTRULETHIRDS;כלל השליש +TP_CROP_GUIDETYPE;סוג מדריך +TP_CROP_H;גובה +TP_CROP_LABEL;גזור +TP_CROP_SELECTCROP;בחור גזירה +TP_CROP_W;רוחב +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;כמות +TP_DISTORTION_LABEL;עיוות +TP_EXPOSURE_AUTOLEVELS;×ž×¤×œ×¡×™× ××•×˜×•×ž×˜×™× +TP_EXPOSURE_BLACKLEVEL;שחור +TP_EXPOSURE_BRIGHTNESS;בהירות +TP_EXPOSURE_CLIP;קצץ +TP_EXPOSURE_COMPRHIGHLIGHTS;דחיסת ×’×•×•× ×™× ×‘×”×™×¨×™× +TP_EXPOSURE_COMPRSHADOWS;דחיסת ×’×•×•× ×™× ×›×”×™× +TP_EXPOSURE_CONTRAST;ניגודיות +TP_EXPOSURE_CURVEEDITOR;עקמת ×’×•×•× ×™× +TP_EXPOSURE_EXPCOMP;פיצוי חשיפה +TP_EXPOSURE_LABEL;חשיפה +TP_HLREC_CIELAB;CIELab Blending +TP_HLREC_COLOR;הפצת צבע +TP_HLREC_LABEL;שחזור ×’×•×•× ×™× ×‘×”×™×¨×™× +TP_HLREC_LUMINANCE;שחזור בהירות +TP_HLREC_METHOD;שיטה +TP_ICM_FILEDLGFILTERANY;×§×‘×¦×™× ×›×œ×©×”× +TP_ICM_FILEDLGFILTERICM;ICC קבצי צבע +TP_ICM_GAMMABEFOREINPUT;Profile applies Gamma +TP_ICM_INPUTCAMERA;ברירת מחדל המצלמה +TP_ICM_INPUTCUSTOM;מות×× +TP_ICM_INPUTDLGLABEL;בחר בפרופיל צבע ×™×™×‘×•× +TP_ICM_INPUTEMBEDDED;השתמש בפרופיל משובץ,×× ×פשר +TP_ICM_INPUTPROFILE;פרופיל ×™×™×‘×•× +TP_ICM_LABEL;ניהול צבע +TP_ICM_NOICM;sRGB×œ×œ× × ×™×”×•×œ צבע - ×™×™×¦×•× ×‘ +TP_ICM_OUTPUTDLGLABEL;בחר בפרופיל צבע ×™×™×¦×•× +TP_ICM_OUTPUTPROFILE;פרופיל ×™×™×¦×•× +TP_ICM_SAVEREFERENCE;Save reference image for profiling +TP_ICM_WORKINGPROFILE;פרופיל עבודה +TP_LUMACURVE_BLACKLEVEL;שחור +TP_LUMACURVE_BRIGHTNESS;בהירות +TP_LUMACURVE_COMPRHIGHLIGHTS;דחיסת ×’×•×•× ×™× ×‘×”×™×¨×™× +TP_LUMACURVE_COMPRSHADOWS;דחיסת ×’×•×•× ×™× ×›×”×™× +TP_LUMACURVE_CONTRAST;ניגודיות +TP_LUMACURVE_CURVEEDITOR;עקמת בהירות +TP_LUMACURVE_LABEL;עקמת בהירות +TP_LUMADENOISE_EDGETOLERANCE;סבילות לקצוות +TP_LUMADENOISE_LABEL;הסרת רעש בהירות +TP_LUMADENOISE_RADIUS;רדיוס +TP_RESIZE_BICUBICSF;ביקובי חלק +TP_RESIZE_BICUBICSH;ביקובי חד +TP_RESIZE_BICUBIC;ביקובי +TP_RESIZE_BILINEAR;בילינ×רי +TP_RESIZE_FULLSIZE;גודל ×ž×œ× +TP_RESIZE_H;גובה +TP_RESIZE_LABEL;החלף גודל +TP_RESIZE_METHOD;שיטה +TP_RESIZE_NEAREST;הקרוב +TP_RESIZE_SCALE;מידה +TP_RESIZE_W;רוחב +TP_ROTATE_AUTOCROP;גזירה ×וטומטי +TP_ROTATE_DEGREE;מעלות +TP_ROTATE_FILL;×ž×œ× +TP_ROTATE_LABEL;סובב +TP_ROTATE_SELECTLINE;בחור קו ישר +TP_SHADOWSHLIGHTS_HIGHLIGHTS;×’×•×•× ×™× ×‘×”×™×¨×™× +TP_SHADOWSHLIGHTS_HLTONALW;רוחב ×’×•×•× ×™× +TP_SHADOWSHLIGHTS_LABEL;בהירי×\×›×”×™× +TP_SHADOWSHLIGHTS_LOCALCONTR;ניגודיות מקומית +TP_SHADOWSHLIGHTS_RADIUS;רדיוס +TP_SHADOWSHLIGHTS_SHADOWS;×’×•×•× ×™× ×›×”×™× +TP_SHADOWSHLIGHTS_SHTONALW;רוחב ×’×•×•× ×™× +TP_SHARPENING_AMOUNT;כמות +TP_SHARPENING_EDRADIUS;רדיוס +TP_SHARPENING_EDTOLERANCE;סבילות לקצוות +TP_SHARPENING_HALOCONTROL;בקרת הילה +TP_SHARPENING_HCAMOUNT;כמות +TP_SHARPENING_LABEL;חידוד +TP_SHARPENING_METHOD;שיטה +TP_SHARPENING_ONLYEDGES;חידוד רק בקצוות +TP_SHARPENING_RADIUS;רדיוס +TP_SHARPENING_RLD_AMOUNT;כמות +TP_SHARPENING_RLD_DAMPING;ריסון +TP_SHARPENING_RLD_ITERATIONS;חזרות +TP_SHARPENING_RLD;RL דיקונבולוציה +TP_SHARPENING_THRESHOLD;××£ +TP_SHARPENING_USM;מיסוך ××™-חדות +TP_VIGNETTING_AMOUNT;כמות +TP_VIGNETTING_LABEL;תיקון פינות כהות +TP_VIGNETTING_RADIUS;רדיוס +TP_WBALANCE_AUTO;×וטומטי +TP_WBALANCE_CAMERA;מצלמה +TP_WBALANCE_CUSTOM;מות×× +TP_WBALANCE_GREEN;גיוון +TP_WBALANCE_LABEL;×יזון לבן +TP_WBALANCE_METHOD;שיטה +TP_WBALANCE_SIZE;גודל +TP_WBALANCE_SPOTWB;לפי נקודה +TP_WBALANCE_TEMPERATURE;מידת ×—×•× +ZOOMBAR_DETAIL;×¤×¨×˜×™× +ZOOMBAR_HUGE;×¢× ×§ +ZOOMBAR_LARGE;גדול +ZOOMBAR_NORMAL;רגיל +ZOOMBAR_PREVIEW;תצוגה מקדימה +ZOOMBAR_SCALE;מידה +ZOOMBAR_SMALL;קטן + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Italian b/rtdata/languages/Italian new file mode 100644 index 000000000..b715d34f3 --- /dev/null +++ b/rtdata/languages/Italian @@ -0,0 +1,706 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# italian language file for rawtherapee +# UTF-8(unix mode) +# translated by breek, pantaraf, chelidon, roberto +# IMPORTANTE: facci sapere sul forum di rawtherapee nella sezione del locale italiano se ci sono errori, qui http://www.rawtherapee.com/forum/viewtopic.php?p=3354#3354 +# IMPORTANT: post on the italian locale in the rawtherapee if are any errors, here http://www.rawtherapee.com/forum/viewtopic.php?p=3354#3354 +# 01-11-2008 +ADJUSTER_RESET_TO_DEFAULT;Valori originali +CURVEEDITOR_FILEDLGFILTERANY;Qualsiasi file +CURVEEDITOR_FILEDLGFILTERCURVE;File curve +CURVEEDITOR_LINEAR;Lineare +CURVEEDITOR_LOADDLGLABEL;Carica curva... +CURVEEDITOR_SAVEDLGLABEL;Salva curva... +CURVEEDITOR_TOOLTIPLINEAR;Ripristina curva lineare +CURVEEDITOR_TOOLTIPLOAD;Carica curva da file +CURVEEDITOR_TOOLTIPSAVE;Salva curva corrente +EXIFFILTER_APERTURE;Diaframma +EXIFFILTER_CAMERA;Fotocamera +EXIFFILTER_DIALOGLABEL;Filtro Exif +EXIFFILTER_FOCALLEN;Lunghezza focale +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Obiettivo +EXIFFILTER_SHUTTER;Tempo d'esposizione +EXIFPANEL_ADDEDIT;Aggiungi/Modifica +EXIFPANEL_ADDEDITHINT;Aggiungi un nuovo campo o modificane uno esistente +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Inserisci valore +EXIFPANEL_ADDTAGDLG_SELECTTAG;Seleziona campo +EXIFPANEL_ADDTAGDLG_TITLE;Aggiungi/Modifica campo +EXIFPANEL_KEEPHINT;Mantieni il campo selezionato nel risultato finale +EXIFPANEL_KEEP;Mantieni +EXIFPANEL_REMOVEHINT;Rimuovi il campo selezionato dal risultato finale +EXIFPANEL_REMOVE;Rimuovi +EXIFPANEL_RESETALLHINT;Ripristina tutti i campi al loro valore originario +EXIFPANEL_RESETALL;Ripristina tutto +EXIFPANEL_RESETHINT;Ripristina i campi selezionati ai loro valori originari +EXIFPANEL_RESET;Ripristina +EXIFPANEL_SUBDIRECTORY;Sottocartella +FILEBROWSER_APPLYPROFILE;Applica un profilo +FILEBROWSER_ARRANGEMENTHINT;Commuta fra la disposizione verticale o orizzontale delle miniature +FILEBROWSER_CLEARPROFILE;Azzera il profilo +FILEBROWSER_COPYPROFILE;Copia il profilo +FILEBROWSER_DELETEDLGLABEL;Conferma eliminazione file +FILEBROWSER_DELETEDLGMSG;Sei certo di voler eliminare i %1 file selezionati? +FILEBROWSER_EMPTYTRASHHINT;Elimina permanentemente i file dal cestino +FILEBROWSER_EMPTYTRASH;Svuota cestino +FILEBROWSER_EXIFFILTERAPPLY;Applica +FILEBROWSER_EXIFFILTERAPPLYHINT;Accendi/Spegni il filtro exif nel navigatore +FILEBROWSER_EXIFFILTERLABEL;Filtro Exif +FILEBROWSER_EXIFFILTERSETTINGSHINT;Modifica le impostazioni del filtro exif +FILEBROWSER_EXIFFILTERSETTINGS;Imposta +FILEBROWSER_PARTIALPASTEPROFILE;Incolla parzialmente +FILEBROWSER_PASTEPROFILE;Incolla il profilo +FILEBROWSER_POPUPCANCELJOB;Cancella compito +FILEBROWSER_POPUPMOVEEND;Sposta in fondo alla coda +FILEBROWSER_POPUPMOVEHEAD;Sposta in cima alla coda +FILEBROWSER_POPUPOPEN;Apri +FILEBROWSER_POPUPPROCESS;Invia alla coda di sviluppo +FILEBROWSER_POPUPRANK1;Classificazione 1 +FILEBROWSER_POPUPRANK2;Classificazione 2 +FILEBROWSER_POPUPRANK3;Classificazione 3 +FILEBROWSER_POPUPRANK4;Classificazione 4 +FILEBROWSER_POPUPRANK5;Classificazione 5 +FILEBROWSER_POPUPREMOVE;Rimuovi definitivamente +FILEBROWSER_POPUPRENAME;Rinomina +FILEBROWSER_POPUPSELECTALL;Seleziona tutto +FILEBROWSER_POPUPTRASH;Butta nel cestino +FILEBROWSER_POPUPUNRANK;Declassifica +FILEBROWSER_POPUPUNTRASH;Togli dal cestino +FILEBROWSER_PROCESSINGSETTINGSHINT;Scegli il formato del file e la cartella di destinazione +FILEBROWSER_PROCESSINGSETTINGS;Impostazioni +FILEBROWSER_RENAMEDLGLABEL;Rinomina il file +FILEBROWSER_RENAMEDLGMSG;Rinomina il file "%1" in: +FILEBROWSER_SHOWDIRHINT;Mostra tutte le immagini della cartella +FILEBROWSER_SHOWQUEUEHINT;Mostra il contenuto della coda di sviluppo +FILEBROWSER_SHOWRANK1HINT;Mostra le immagini classificate con 1 stella +FILEBROWSER_SHOWRANK2HINT;Mostra le immagini classificate con 2 stelle +FILEBROWSER_SHOWRANK3HINT;Mostra le immagini classificate con 3 stelle +FILEBROWSER_SHOWRANK4HINT;Mostra le immagini classificate con 4 stelle +FILEBROWSER_SHOWRANK5HINT;Mostra le immagini classificate con 5 stelle +FILEBROWSER_SHOWTRASHHINT;Mostra il contenuto del cestino +FILEBROWSER_SHOWUNRANKHINT;Mostra le immagini non classificate +FILEBROWSER_STARTPROCESSING;Comincia a sviluppare +FILEBROWSER_STARTPROCESSINGHINT;Inizia lo sviluppo o il salvataggio delle immagini in coda +FILEBROWSER_STOPPROCESSINGHINT;Ferma lo sviluppo delle immagini +FILEBROWSER_STOPPROCESSING;Smetti di sviluppare +FILEBROWSER_THUMBSIZE;Dimensione miniature +FILEBROWSER_ZOOMINHINT;Aumenta la dimensione delle miniature +FILEBROWSER_ZOOMOUTHINT;Diminuisci la dimensione delle miniature +GENERAL_ABOUT;Informazioni +GENERAL_CANCEL;Annulla +GENERAL_DISABLED;Disabilitato +GENERAL_DISABLE;Disabilita +GENERAL_ENABLE;Abilita +GENERAL_ENABLED;Abilitato +GENERAL_LANDSCAPE;Panorama +GENERAL_LOAD;Carica +GENERAL_NA;n/d +GENERAL_NO;No +GENERAL_OK;OK +GENERAL_PORTRAIT;Ritratto +GENERAL_SAVE;Salva +GENERAL_YES;Sì +HISTOGRAM_LABEL;Istogramma +HISTOGRAM_TOOLTIP_B;Mostra/Nascondi istogramma del BLU +HISTOGRAM_TOOLTIP_G;Mostra/Nascondi istogramma del VERDE +HISTOGRAM_TOOLTIP_L;Mostra/Nascondi istogramma di luminanza CIELAB +HISTOGRAM_TOOLTIP_R;Mostra/Nascondi istogramma del ROSSO +HISTORY_CHANGED;Modificato +HISTORY_CUSTOMCURVE;Curva personalizzata +HISTORY_DELSNAPSHOT;Rimuovi +HISTORY_FROMCLIPBOARD;Dagli appunti +HISTORY_LABEL;Cronologia +HISTORY_MSG_10;Compressione ombre +HISTORY_MSG_11;Curva di tono +HISTORY_MSG_12;Esposizione automatica +HISTORY_MSG_13;Sovraesposizione +HISTORY_MSG_14;Luminosità luminanza +HISTORY_MSG_15;Contrasto luminanza +HISTORY_MSG_16;Punto del nero luminanza +HISTORY_MSG_17;Compressione alteluci luminanza +HISTORY_MSG_18;Compressione ombre luminanza +HISTORY_MSG_19;Curva di luminanza +HISTORY_MSG_1;Foto caricata +HISTORY_MSG_20;Nitidezza +HISTORY_MSG_21;Raggio nitidezza +HISTORY_MSG_22;Quantità nitidezza +HISTORY_MSG_23;Soglia nitidezza +HISTORY_MSG_24;Definisci solo i bordi +HISTORY_MSG_25;Raggio di rilevamento bordi nitidezza +HISTORY_MSG_26;Tolleranza bordi nitidezza +HISTORY_MSG_27;Controllo alone nitidezza +HISTORY_MSG_28;Quantità controllo alone +HISTORY_MSG_29;Metodo controllo nitidezza +HISTORY_MSG_2;Profilo caricato +HISTORY_MSG_30;Raggio deconvoluzione +HISTORY_MSG_31;Quantità deconvoluzione +HISTORY_MSG_32;Smorzamento deconvoluzione +HISTORY_MSG_33;Iterazioni deconvoluzione +HISTORY_MSG_34;Previeni tosaggio dei colori +HISTORY_MSG_35;Limitatore saturazione +HISTORY_MSG_36;Limite saturazione +HISTORY_MSG_37;Potenziamento colore +HISTORY_MSG_38;Metodo di bilanciamento del bianco +HISTORY_MSG_39;Temperatura colore +HISTORY_MSG_3;Profilo cambiato +HISTORY_MSG_40;Tinta bilanciamento del bianco +HISTORY_MSG_41;Spostamento colore "A" +HISTORY_MSG_42;Spostamento colore "B" +HISTORY_MSG_43;Riduzione rumore luminanza +HISTORY_MSG_44;Raggio rumore luminanza +HISTORY_MSG_45;Tolleranza bordi rumore luminanza +HISTORY_MSG_46;Riduzione rumore crominanza +HISTORY_MSG_47;Raggio rumore crominanza +HISTORY_MSG_48;Tolleranza bordi rumore crominanza +HISTORY_MSG_49;Sensibilità bordi rumore crominanza +HISTORY_MSG_4;Visualizzazione cronologia +HISTORY_MSG_50;Strumento ombre/alteluci +HISTORY_MSG_51;Miglioramento alteluci +HISTORY_MSG_52;Miglioramento ombre +HISTORY_MSG_53;Ampiezza tonale alteluci +HISTORY_MSG_54;Ampiezza tonale ombre +HISTORY_MSG_55;Contrasto locale +HISTORY_MSG_56;Raggio per ombre/alteluci +HISTORY_MSG_57;Rotazione arbitraria +HISTORY_MSG_58;Ribaltamento orizzontale +HISTORY_MSG_59;Ribaltamento verticale +HISTORY_MSG_5;Luminosità +HISTORY_MSG_60;Rotazione +HISTORY_MSG_61;Rotazione +HISTORY_MSG_62;Correzione distorsione dell'obiettivo +HISTORY_MSG_63;Istantanea selezionata +HISTORY_MSG_64;Ritaglio foto +HISTORY_MSG_65;Correzione aberrazioni cromatiche +HISTORY_MSG_66;Recupero alteluci +HISTORY_MSG_67;Quantità recupero alteluci +HISTORY_MSG_68;Metodo di recupero alteluci +HISTORY_MSG_69;Spazio colore di lavoro +HISTORY_MSG_6;Contrasto +HISTORY_MSG_70;Spazio colore di uscita +HISTORY_MSG_71;Spazio colore di ingresso +HISTORY_MSG_72;Correzione vignettatura +HISTORY_MSG_73;Miscelatore dei canali +HISTORY_MSG_74;Ridimensiona +HISTORY_MSG_75;Metodo di ridimensionamento +HISTORY_MSG_76;Metadati Exif +HISTORY_MSG_77;Metadati IPTC +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;Livello del nero +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;Compensazione dell'esposizione +HISTORY_MSG_9;Compressione alteluci +HISTORY_NEWSNAPSHOT;Aggiungi +HISTORY_NEWSNAPSHOTAS;Come... +HISTORY_NEWSSDIALOGLABEL;Etichetta dell'istantanea: +HISTORY_NEWSSDIALOGTITLE;Aggiungi nuova istantanea +HISTORY_SETTO;Impostato a +HISTORY_SNAPSHOT;Istantanea +HISTORY_SNAPSHOTS;Istantanee +ICMPANEL_FILEDLGFILTERANY;Qualsiasi file +ICMPANEL_FILEDLGFILTERICM;Profili ICC +ICMPANEL_GAMMABEFOREINPUT;Il profilo applica il gamma +ICMPANEL_INPUTCAMERA;Predefinito della fotocamera +ICMPANEL_INPUTCUSTOM;Personalizzato +ICMPANEL_INPUTDLGLABEL;Seleziona il profilo ICC di ingresso... +ICMPANEL_INPUTEMBEDDED;Incorporato, se possibile +ICMPANEL_INPUTPROFILE;Profilo di ingresso +ICMPANEL_NOICM;Nessun ICM: uscita in sRGB +ICMPANEL_OUTPUTDLGLABEL;Seleziona il profilo ICC di uscita... +ICMPANEL_OUTPUTPROFILE;Profilo di uscita +ICMPANEL_SAVEREFERENCE;Salva immagine di riferimento per la profilazione +ICMPANEL_WORKINGPROFILE;Profilo di lavoro +IMAGEAREA_DETAILVIEW;Visualizza dettaglio +IPTCPANEL_AUTHOR;Autore +IPTCPANEL_AUTHORHINT;Nome del creatore dell'opera, es. scrittore, fotografo o artista grafico (By-line). +IPTCPANEL_AUTHORSPOSITIONHINT;Titolo lavorativo del creatore o creatori dell'opera (By-line Title). +IPTCPANEL_AUTHORSPOSITION;Qualifica dell'Autore +IPTCPANEL_CAPTION;Didascalia +IPTCPANEL_CAPTIONHINT;Una descrizione testuale dei dati (Caption - Abstract). +IPTCPANEL_CAPTIONWRITER;Autore della didascalia +IPTCPANEL_CAPTIONWRITERHINT;Il nome della persona impegnata nella scrittura, modifica o correzione dell'immagine o della descrizione riassuntiva (Writer - Editor). +IPTCPANEL_CATEGORY;Categoria +IPTCPANEL_CATEGORYHINT;Identifica il soggetto dell'immagine secondo l'opinione del curatore (Category). +IPTCPANEL_CITY;Città +IPTCPANEL_CITYHINT;Città o luogo di origine dell'immagine (City). +IPTCPANEL_COPYHINT;Copia le impostazioni IPTC negli appunti +IPTCPANEL_COPYRIGHT;Diritto d'autore +IPTCPANEL_COPYRIGHTHINT;Qualsiasi annotazione necessaria riguardante il diritto d'autore (Copyright Notice). +IPTCPANEL_COUNTRYHINT;Il nome dello stato/confederazione in cui l'immagine è stata creata (Country - Primary Location Name). +IPTCPANEL_COUNTRY;Stato +IPTCPANEL_CREDITHINT;Identifica il fornitore dell'immagine, non necessariamente il possessore/creatore (Credit). +IPTCPANEL_CREDIT;Riconoscimento +IPTCPANEL_DATECREATED;Data di creazione +IPTCPANEL_DATECREATEDHINT;La data in cui è stato creato il contenuto intellettuale dell'immagine; Formato: AAAAMMTT (Date Created). +IPTCPANEL_EMBEDDEDHINT;Ripristina i dati IPTC incorporati nel file d'immagine +IPTCPANEL_EMBEDDED;Incorporato +IPTCPANEL_HEADLINEHINT;Una didascalia pubblicabile che esprime una sinossi del contenuto dell'immagine (Headline). +IPTCPANEL_HEADLINE;Intestazione +IPTCPANEL_INSTRUCTIONSHINT;Altre istruzioni editoriali riguardanti l'uso dell'immagine (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Istruzioni +IPTCPANEL_KEYWORDSHINT;Usate per indicare parole emblematiche per il recupero di informazioni specifiche (Keywords). +IPTCPANEL_KEYWORDS;Parole Chiave +IPTCPANEL_PASTEHINT;Incolla le impostazioni IPTC dagli appunti +IPTCPANEL_PROVINCEHINT;La provincia/regione da cui l'immagine proviene (Province-State). +IPTCPANEL_PROVINCE;Provincia +IPTCPANEL_RESETHINT;Ripristina il profilo predefinito +IPTCPANEL_RESET;Ripristina +IPTCPANEL_SOURCEHINT;Il possessore originario del contenuto intellettuale rappresentato nell'immagine (Source). +IPTCPANEL_SOURCE;Origine +IPTCPANEL_SUPPCATEGORIES;Categorie agg. +IPTCPANEL_SUPPCATEGORIESHINT;Ulteriore raffinamento del soggetto dell'immagine (Supplemental Categories). +IPTCPANEL_TITLEHINT;Un breve riferimento per l'immagine (Object Name). +IPTCPANEL_TITLE;Titolo +IPTCPANEL_TRANSREFERENCEHINT;Un codice che rappresenta la locazione da cui è avvenuta la trasmissione originaria (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Riferimento Trasm. +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Preferenze +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;Salva come... +MAIN_BUTTON_SAVE;Salva immagine +MAIN_BUTTON_SENDTOEDITOR;Passa al ritocco +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Il file esiste già! +MAIN_MSG_CANNOTLOAD;Impossibile caricare l'immagine +MAIN_MSG_CANNOTSAVE;Errore nel salvare il file! +MAIN_MSG_CANNOTSTARTEDITOR;Non riesco ad avviare il programma di ritocco. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Prego inserire il percorso corretto mediante l'impostazione delle "Preferenze". +MAIN_MSG_EXITJOBSINQUEUEINFO;Le immagini non ancora sviluppate dalla coda andranno perse all'uscita. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Sei certo di voler uscire? Ci sono immagini non ancora sviluppate rimaste nella coda. +MAIN_MSG_JOBSINQUEUE;operazione/i in coda +MAIN_MSG_QOVERWRITE;Vuoi sovrascriverlo? +MAIN_TAB_BASIC;Base +MAIN_TAB_COLOR;Colore +MAIN_TAB_DETAIL;Dettaglio +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Esposizione +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadati +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Trasformazione +MAIN_TOOLTIP_HIDEFP;Mostra/Nascondi il pannello dei pulsanti (cartelle e navigatore di file, tasto rapido: F) +MAIN_TOOLTIP_HIDEHP;Mostra/Nascondi il pannello sinistro (inclusa la cronologia, tasto rapido: H) +MAIN_TOOLTIP_INDCLIPPEDH;Indicazione delle alteluci tosate +MAIN_TOOLTIP_INDCLIPPEDS;Indicazione delle ombre tosate +MAIN_TOOLTIP_PREFERENCES;Imposta preferenze +MAIN_TOOLTIP_QINFO;Informazioni generali sullo scatto +MAIN_TOOLTIP_SAVEAS;Salva immagine nella cartella selezionata +MAIN_TOOLTIP_SAVE;Salva immagine nella cartella predefinita +PARTIALPASTE_BASICGROUP;Parametri di base +PARTIALPASTE_CACORRECTION;Correzione A/C +PARTIALPASTE_COARSETRANS;Rotazione di 90° / riflessione +PARTIALPASTE_COLORBOOST;Potenziamento colore +PARTIALPASTE_COLORDENOISE;Riduzione rumore di crominanza +PARTIALPASTE_COLORGROUP;Parametri relativi al colore +PARTIALPASTE_COLORMIXER;Miscelatore colore +PARTIALPASTE_COLORSHIFT;Spostamento colore +PARTIALPASTE_COMPOSITIONGROUP;Parametri di composizione +PARTIALPASTE_CROP;Ritaglio +PARTIALPASTE_DIALOGLABEL;Incolla una porzione del profilo +PARTIALPASTE_DISTORTION;Correzione distorsione +PARTIALPASTE_EXIFCHANGES;Cambiamenti nei dati exif +PARTIALPASTE_EXPOSURE;Esposizione +PARTIALPASTE_HLRECOVERY;Recupero alteluci +PARTIALPASTE_ICMSETTINGS;Parametri ICM +PARTIALPASTE_IPTCINFO;Informazioni IPTC +PARTIALPASTE_LENSGROUP;Parametri correlati all'ottica +PARTIALPASTE_LUMACURVE;Curva di luminanza +PARTIALPASTE_LUMADENOISE;Riduzione rumore di luminanza +PARTIALPASTE_LUMINANCEGROUP;Parametri riguardanti la luminanza +PARTIALPASTE_METAICMGROUP;Parametri di Metadati/ICM +PARTIALPASTE_RESIZE;Ridimensionamento +PARTIALPASTE_ROTATION;Rotazione +PARTIALPASTE_SHADOWSHIGHLIGHTS;Ombre/Alteluci +PARTIALPASTE_SHARPENING;Nitidezza +PARTIALPASTE_VIGNETTING;Correzione vignettatura +PARTIALPASTE_WHITEBALANCE;Bilanciamento del bianco +PREFERENCES_APPLNEXTSTARTUP;applicato al prossimo avvio +PREFERENCES_BLINKCLIPPED;Lampeggia le aree tosate +PREFERENCES_CACHECLEARALL;Ripulisci tutto +PREFERENCES_CACHECLEARPROFILES;Ripulisci i profili +PREFERENCES_CACHECLEARTHUMBS;Ripulisci le miniature +PREFERENCES_CACHEFORMAT1;Proprietario (più rapido e di migliore qualità) +PREFERENCES_CACHEFORMAT2;JPEG (minore impatto sul disco) +PREFERENCES_CACHEMAXENTRIES;Numero massimo di oggetti conservati in memoria +PREFERENCES_CACHEOPTS;Opzioni per il precaricamento +PREFERENCES_CACHESTRAT1;Privilegia la rapidità al minore consumo di memoria +PREFERENCES_CACHESTRAT2;Privilegia il minore consumo di memoria alla rapidità +PREFERENCES_CACHESTRAT;Strategia di precaricamento +PREFERENCES_CACHETHUMBFORM;Formato delle miniature precaricate +PREFERENCES_CACHETHUMBHEIGHT;Massima quantità di miniature +PREFERENCES_CLEARDLG_LINE1;Ripulitura dati in memoria +PREFERENCES_CLEARDLG_LINE2;Questa operazione potrebbe impiegare alcuni secondi. +PREFERENCES_CLEARDLG_TITLE;Prego attendere +PREFERENCES_CLIPPINGIND;Indicazione di tosaggio +PREFERENCES_CMETRICINTENT;Intento colorimetrico +PREFERENCES_DATEFORMAT;Formato data +PREFERENCES_DATEFORMATHINT;Puoi usare le seguenti stringhe di formattazione:\n%y : anno\n%m : mese\n%d : giorno\n\nPer esempio, il formato italiano per la data è:\n%d/%m/%y +PREFERENCES_DEFAULTLANG;Lingua predefinita +PREFERENCES_DEFAULTTHEME;Aspetto ordinario +PREFERENCES_DEMOSAICINGALGO;Algoritmo di demosaicizzazione +PREFERENCES_DIRHOME;Cartella personale dell'utente (home directory) +PREFERENCES_DIRLAST;Ultima cartella visitata +PREFERENCES_DIROTHER;Altra +PREFERENCES_DIRSELECTDLG;Seleziona la cartella delle immagini all'avvio... +PREFERENCES_DIRSOFTWARE;Cartella d'installazione +PREFERENCES_DMETHOD;Metodo +PREFERENCES_EDITORCMDLINE;Esegui altro da linea di comando +PREFERENCES_EXTERNALEDITOR;Programmi di ritocco esterni +PREFERENCES_FALSECOLOR;Iterazioni per la soppressione dei falsi colori +PREFERENCES_FBROWSEROPTS;Opzioni del navigatore di file +PREFERENCES_FILEFORMAT;Formato file +PREFERENCES_FORIMAGE;Per file immagine +PREFERENCES_FORRAW;Per file RAW +PREFERENCES_GIMPPATH;Cartella d'installazione di GIMP +PREFERENCES_GTKTHEME;Predefinito GTK +PREFERENCES_HINT;Suggerimento +PREFERENCES_HLTHRESHOLD;Soglia per le alteluci tosate +PREFERENCES_ICCDIR;Cartella profili ICC +PREFERENCES_IMPROCPARAMS;Parametri predefiniti di elaborazione dell'immagine +PREFERENCES_INTENT_ABSOLUTE;Colorimetrico Assoluto +PREFERENCES_INTENT_PERCEPTUAL;Percettivo +PREFERENCES_INTENT_RELATIVE;Colorimetrico Relativo +PREFERENCES_INTENT_SATURATION;Saturazione +PREFERENCES_LIVETHUMBNAILS;Miniature sincronizzate (maggiore lentezza) +PREFERENCES_MONITORICC;Profilo dello schermo +PREFERENCES_OUTDIR;Cartella di destinazione +PREFERENCES_OUTDIRFOLDERHINT;Mette le immagini salvate nella cartella scelta +PREFERENCES_OUTDIRFOLDER;Salva nella cartella +PREFERENCES_OUTDIRHINT;Puoi usare le seguenti stringhe di formattazione:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nQueste stringhe di formattazione si riferiscono alle cartelle e ai percorsi sottostanti la posizione del file raw.\n\nPer esempio, se si è aperto /home/tom/immagini/02-09-2006/dsc0012.nef, il senso delle stringhe di formattazione è:\n%f=dsc0012, %d1=02-09-2006, %d2=immagini, ...\n%p1=/home/tom/immagini/02-09-2006, %p2=/home/tom/immagini, p3=/home/tom, ...\n\nSe vuoi salvare l'immagine finale nella stessa posizione dove si trova l'originale, scrivi:\n%p1/%f\n\nSe vuoi salvare l'immagine finale in una cartella 'sviluppate' situata nella cartella degli originali, scrivi:\n%p1/sviluppate/%f\n\nSe intendi salvare l'immagine finale in una cartella '/home/tom/sviluppate' mantenendo la stessa sottocartella della data, scrivi:\n%p2/sviluppate/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;Puoi usare le seguenti stringhe di formattazione:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nQueste stringhe di formattazione si riferiscono alle cartelle e ai percorsi sottostanti la posizione del file raw.\n\nPer esempio, se si è aperto /home/tom/immagini/02-09-2006/dsc0012.nef, il senso delle stringhe di formattazione è:\n%f=dsc0012, %d1=02-09-2006, %d2=immagini, ...\n%p1=/home/tom/immagini/02-09-2006, %p2=/home/tom/immagini, p3=/home/tom, ...\n\nSe vuoi salvare l'immagine finale nella stessa posizione dove si trova l'originale, scrivi:\n%p1/%f\n\nSe vuoi salvare l'immagine finale in una cartella 'sviluppate' situata nella cartella degli originali, scrivi:\n%p1/sviluppate/%f\n\nSe intendi salvare l'immagine finale in una cartella '/home/tom/sviluppate' mantenendo la stessa sottocartella della data, scrivi:\n%p2/sviluppate/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Usa modello +PREFERENCES_PARSEDEXTADD;Aggiungi estensione +PREFERENCES_PARSEDEXTADDHINT;Immetti l'estensione e premi questo tasto per aggiungerla alla lista +PREFERENCES_PARSEDEXTDELHINT;Rimuovi l'estensione selezionata dalla lista +PREFERENCES_PARSEDEXT;Estensioni riconosciute +PREFERENCES_PROFILEHANDLING;Gestione dei profili di elaborazione +PREFERENCES_PROFILELOADPR;Priorità nel caricamento del profilo +PREFERENCES_PROFILEPRCACHE;Profilo situato nella memoria del programma +PREFERENCES_PROFILEPRFILE;Profilo presente a fianco del file originario +PREFERENCES_PROFILESAVECACHE;Salva i parametri di elaborazione nella memoria del programma +PREFERENCES_PROFILESAVEINPUT;Salva i parametri di elaborazione a fianco del file originario +PREFERENCES_PSPATH;Cartella d'installazione di Adobe Photoshop +PREFERENCES_SELECTICCDIRDLG;Seleziona la cartella dei profili ICC... +PREFERENCES_SELECTLANG;Seleziona lingua +PREFERENCES_SELECTMONITORPROFDLG;Seleziona il profilo ICC dello schermo... +PREFERENCES_SELECTTHEME;Seleziona un tema +PREFERENCES_SHOWBASICEXIF;Mostra informazioni Exif di base +PREFERENCES_SHOWDATETIME;Mostra data e ora +PREFERENCES_SHOWONLYRAW;Mostra solo file RAW +PREFERENCES_SHTHRESHOLD;Soglia per le ombre tosate +PREFERENCES_STARTUPIMDIR;Cartella delle immagini all'avvio +PREFERENCES_TAB_BROWSER;Navigatore di file +PREFERENCES_TAB_COLORMGR;Gestione colore +PREFERENCES_TAB_GENERAL;Generale +PREFERENCES_TAB_IMPROC;Elaborazione immagine +PREFERENCES_TAB_OUTPUT;Opzioni di salvataggio +PREFERENCES_THUMBSIZE;Dimensione miniature +PROFILEPANEL_FILEDLGFILTERANY;Qualsiasi file +PROFILEPANEL_FILEDLGFILTERPP;Profili di postelaborazione +PROFILEPANEL_LABEL;Profili di postelaborazione +PROFILEPANEL_LOADDLGLABEL;Carico i parametri di postelaborazione... +PROFILEPANEL_PCUSTOM;Personalizzato +PROFILEPANEL_PFILE;Da file +PROFILEPANEL_PLASTPHOTO;Ultima foto +PROFILEPANEL_PLASTSAVED;Ultimo salvato +PROFILEPANEL_PROFILE;Profilo +PROFILEPANEL_SAVEDLGLABEL;Salvo i parametri di postelaborazione... +PROFILEPANEL_TOOLTIPCOPY;Copia il profilo corrente negli appunti +PROFILEPANEL_TOOLTIPLOAD;Carica profilo da file +PROFILEPANEL_TOOLTIPPASTE;Incolla il profilo dagli appunti +PROFILEPANEL_TOOLTIPSAVE;Salva il profilo corrente +PROGRESSBAR_DECODING;Decodifica file raw... +PROGRESSBAR_DEMOSAICING;Demosaicizzazione... +PROGRESSBAR_LOADING;Caricamento immagine... +PROGRESSBAR_LOADJPEG;Caricamento file JPEG... +PROGRESSBAR_LOADPNG;Caricamento file PNG... +PROGRESSBAR_LOADTIFF;Caricamento file TIFF... +PROGRESSBAR_PROCESSING;Elaborazione immagine... +PROGRESSBAR_READY;Pronto. +PROGRESSBAR_SAVEJPEG;Salvataggio file JPEG... +PROGRESSBAR_SAVEPNG;Salvataggio file PNG... +PROGRESSBAR_SAVETIFF;Salvataggio file TIFF... +PROGRESSDLG_LOADING;Caricamento del file... +PROGRESSDLG_PROCESSING;Elaborazione dell'immagine... +PROGRESSDLG_SAVING;Salvataggio del file... +QINFO_FOCALLENGTH;Lunghezza focale +QINFO_ISO;ISO +QINFO_LENS;Obiettivo +QINFO_NOEXIF;Dati Exif non disponibili. +SAVEDLG_FILEFORMAT;Formato file +SAVEDLG_JPEGQUAL;Qualità JPEG +SAVEDLG_JPGFILTER;file JPEG +SAVEDLG_PNGCOMPR;Compressione PNG +SAVEDLG_PNGFILTER;file PNG +SAVEDLG_PUTTOQUEUEHEAD;Metti in cima alla coda di elaborazione +SAVEDLG_PUTTOQUEUE;Inserisci nella coda di sviluppo +SAVEDLG_PUTTOQUEUETAIL;Metti in fondo alla coda di elaborazione +SAVEDLG_SAVEIMMEDIATELY;Salva subito +SAVEDLG_SAVESPP;Salva i parametri di elaborazione assieme all'immagine +SAVEDLG_TIFFFILTER;file TIFF +TOOLBAR_TOOLTIP_CROP;Ritaglia selezione (tasto rapido: C) +TOOLBAR_TOOLTIP_HAND;Strumento mano (tasto rapido: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Seleziona linea dritta (tasto rapido: S) +TOOLBAR_TOOLTIP_WB;Bilanciamento del bianco puntuale (tasto rapido: W) +TP_CACORRECTION_BLUE;Blu +TP_CACORRECTION_LABEL;Correzione A/C +TP_CACORRECTION_RED;Rosso +TP_CHMIXER_BLUE;Blu +TP_CHMIXER_GREEN;Verde +TP_CHMIXER_LABEL;Miscelatore canali +TP_CHMIXER_RED;Rosso +TP_COARSETRAF_DEGREE;Angolo: +TP_COARSETRAF_TOOLTIP_HFLIP;Rifletti orizzontalmente +TP_COARSETRAF_TOOLTIP_ROTLEFT;Ruota a sinistra +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Ruota a destra +TP_COARSETRAF_TOOLTIP_VFLIP;Rifletti verticalmente +TP_COLORBOOST_ACHANNEL;canale "a" +TP_COLORBOOST_AMOUNT;Quantità +TP_COLORBOOST_AVOIDCOLORCLIP;Previeni tosaggio dei colori +TP_COLORBOOST_BCHANNEL;canale "b" +TP_COLORBOOST_CHAB;a & b +TP_COLORBOOST_CHANNEL;Canale +TP_COLORBOOST_CHSEPARATE;separati +TP_COLORBOOST_ENABLESATLIMITER;Abilita limite di saturazione +TP_COLORBOOST_LABEL;Potenziamento colore +TP_COLORBOOST_SATLIMIT;Limite di saturazione +TP_COLORDENOISE_EDGESENSITIVE;Sensibile ai bordi +TP_COLORDENOISE_EDGETOLERANCE;Tolleranza bordi +TP_COLORDENOISE_LABEL;Riduzione rumore crominanza +TP_COLORDENOISE_RADIUS;Raggio +TP_COLORSHIFT_BLUEYELLOW;Blu-Giallo +TP_COLORSHIFT_GREENMAGENTA;Verde-Magenta +TP_COLORSHIFT_LABEL;Spostamento colore +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Rapporto fisso: +TP_CROP_GTDIAGONALS;Regola delle diagonali +TP_CROP_GTHARMMEANS1;Media armonica 1 +TP_CROP_GTHARMMEANS2;Media armonica 2 +TP_CROP_GTHARMMEANS3;Media armonica 3 +TP_CROP_GTHARMMEANS4;Media armonica 4 +TP_CROP_GTNONE;Nessuna +TP_CROP_GTRULETHIRDS;Regola dei terzi +TP_CROP_GUIDETYPE;Tipo di guida: +TP_CROP_H;A +TP_CROP_LABEL;Ritaglia +TP_CROP_SELECTCROP; Seleziona Area +TP_CROP_W;L +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Quantità +TP_DISTORTION_LABEL;Distorsione +TP_EXPOSURE_AUTOLEVELS;Livelli automatici +TP_EXPOSURE_BLACKLEVEL;Nero +TP_EXPOSURE_BRIGHTNESS;Luminosità +TP_EXPOSURE_CLIP;Tosaggio +TP_EXPOSURE_COMPRHIGHLIGHTS;Compressione alteluci +TP_EXPOSURE_COMPRSHADOWS;Compressione ombre +TP_EXPOSURE_CONTRAST;Contrasto +TP_EXPOSURE_CURVEEDITOR;Curva di tono +TP_EXPOSURE_EXPCOMP;Compensazione esposizione +TP_EXPOSURE_LABEL;Esposizione +TP_HLREC_CIELAB;Miscelazione in CIELab +TP_HLREC_COLOR;Propagazione di crominanza +TP_HLREC_LABEL;Recupero alteluci +TP_HLREC_LUMINANCE;Recupero di luminanza +TP_HLREC_METHOD;Metodo: +TP_ICM_FILEDLGFILTERANY;Qualsiasi file +TP_ICM_FILEDLGFILTERICM;Profili ICC +TP_ICM_GAMMABEFOREINPUT;Il profilo applica il gamma +TP_ICM_INPUTCAMERA;Predefinito della fotocamera +TP_ICM_INPUTCUSTOM;Personalizzato +TP_ICM_INPUTDLGLABEL;Seleziona il profilo ICC di ingresso... +TP_ICM_INPUTEMBEDDED;Incorporato, se possibile +TP_ICM_INPUTPROFILE;Profilo di ingresso +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Nessun ICM: uscita in sRGB +TP_ICM_OUTPUTDLGLABEL;Seleziona il profilo ICC di uscita... +TP_ICM_OUTPUTPROFILE;Profilo di uscita +TP_ICM_SAVEREFERENCE;Salva immagine di riferimento per la profilazione +TP_ICM_WORKINGPROFILE;Profilo di lavoro +TP_LUMACURVE_BLACKLEVEL;Nero +TP_LUMACURVE_BRIGHTNESS;Luminosità +TP_LUMACURVE_COMPRHIGHLIGHTS;Compressione alteluci +TP_LUMACURVE_COMPRSHADOWS;Compressione ombre +TP_LUMACURVE_CONTRAST;Contrasto +TP_LUMACURVE_CURVEEDITOR;Curva di luminanza +TP_LUMACURVE_LABEL;Curva di luminanza +TP_LUMADENOISE_EDGETOLERANCE;Tolleranza bordi +TP_LUMADENOISE_LABEL;Riduzione rumore luminanza +TP_LUMADENOISE_RADIUS;Raggio +TP_RESIZE_BICUBIC;Bicubico +TP_RESIZE_BICUBICSF;Bicubico (più sfumato) +TP_RESIZE_BICUBICSH;Bicubico (più definito) +TP_RESIZE_BILINEAR;Bilineare +TP_RESIZE_FULLSIZE;Dimensione dell'intera immagine: +TP_RESIZE_H;A: +TP_RESIZE_LABEL;Ridimensiona +TP_RESIZE_METHOD;Metodo: +TP_RESIZE_NEAREST;Più fedele +TP_RESIZE_SCALE;Scala +TP_RESIZE_W;L: +TP_ROTATE_AUTOCROP;Ritaglio automatico +TP_ROTATE_DEGREE;Angolo +TP_ROTATE_FILL;Adatta +TP_ROTATE_LABEL;Ruota +TP_ROTATE_SELECTLINE; Seleziona linea dritta +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Alteluci +TP_SHADOWSHLIGHTS_HLTONALW;Ampiezza tonale +TP_SHADOWSHLIGHTS_LABEL;Ombre/Alteluci +TP_SHADOWSHLIGHTS_LOCALCONTR;Contrasto locale +TP_SHADOWSHLIGHTS_RADIUS;Raggio +TP_SHADOWSHLIGHTS_SHADOWS;Ombre +TP_SHADOWSHLIGHTS_SHTONALW;Ampiezza tonale +TP_SHARPENING_AMOUNT;Quantità +TP_SHARPENING_EDRADIUS;Raggio +TP_SHARPENING_EDTOLERANCE;Tolleranza bordi +TP_SHARPENING_HALOCONTROL;Controllo alone +TP_SHARPENING_HCAMOUNT;Quantità +TP_SHARPENING_LABEL;Nitidezza +TP_SHARPENING_METHOD;Metodo +TP_SHARPENING_ONLYEDGES;Definisci solo i bordi +TP_SHARPENING_RADIUS;Raggio +TP_SHARPENING_RLD_AMOUNT;Quantità +TP_SHARPENING_RLD_DAMPING;Smorzamento +TP_SHARPENING_RLD;Deconvoluzione RL +TP_SHARPENING_RLD_ITERATIONS;Iterazioni +TP_SHARPENING_THRESHOLD;Soglia +TP_SHARPENING_USM;Maschera di Contrasto +TP_VIGNETTING_AMOUNT;Quantità +TP_VIGNETTING_LABEL;Correzione vignettatura +TP_VIGNETTING_RADIUS;Raggio +TP_WBALANCE_AUTO;Automatico +TP_WBALANCE_CAMERA;Fotocamera +TP_WBALANCE_CUSTOM;Personalizzato +TP_WBALANCE_GREEN;Tinta +TP_WBALANCE_LABEL;Bilanciamento del bianco +TP_WBALANCE_METHOD;Metodo +TP_WBALANCE_SIZE;Dimensione: +TP_WBALANCE_SPOTWB;Punto BB manuale +TP_WBALANCE_TEMPERATURE;Temperatura +ZOOMBAR_DETAIL;Dettaglio +ZOOMBAR_HUGE;Enorme +ZOOMBAR_LARGE;Grande +ZOOMBAR_NORMAL;Normale +ZOOMBAR_PREVIEW;Anteprima +ZOOMBAR_SCALE;Scala +ZOOMBAR_SMALL;Piccola + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Japanese b/rtdata/languages/Japanese new file mode 100644 index 000000000..00adecdc2 --- /dev/null +++ b/rtdata/languages/Japanese @@ -0,0 +1,703 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# Japanese translation of RawTherapee V2.4 +# 2009-02-18 by A3novy +# +ADJUSTER_RESET_TO_DEFAULT;ãƒªã‚»ãƒƒãƒˆåˆæœŸåŒ– +CURVEEDITOR_FILEDLGFILTERANY;ã™ã¹ã¦ã®ãƒ•ァイル +CURVEEDITOR_FILEDLGFILTERCURVE;カーブ・ファイル +CURVEEDITOR_LINEAR;リニア +CURVEEDITOR_LOADDLGLABEL;カーブ読ã¿è¾¼ã¿... +CURVEEDITOR_SAVEDLGLABEL;カーブä¿å­˜... +CURVEEDITOR_TOOLTIPLINEAR;リニアã«ãƒªã‚»ãƒƒãƒˆ +CURVEEDITOR_TOOLTIPLOAD;ファイルã‹ã‚‰èª­ã¿è¾¼ã¿ +CURVEEDITOR_TOOLTIPSAVE;カーブä¿å­˜ +EXIFFILTER_APERTURE;絞り +EXIFFILTER_CAMERA;カメラ +EXIFFILTER_DIALOGLABEL;Exif情報 +EXIFFILTER_FOCALLEN;焦点è·é›¢ +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;レンズ +EXIFFILTER_SHUTTER;シャッター +EXIFPANEL_ADDEDITHINT;æ–°ã—ã„タグを追加ã€ã¾ãŸã¯ã‚¿ã‚°ã®ç·¨é›† +EXIFPANEL_ADDEDIT;追加/編集 +EXIFPANEL_ADDTAGDLG_ENTERVALUE;値 入力 +EXIFPANEL_ADDTAGDLG_SELECTTAG;ã‚¿ã‚°é¸æŠž +EXIFPANEL_ADDTAGDLG_TITLE;追加/タグ編集 +EXIFPANEL_KEEP;キープ +EXIFPANEL_KEEPHINT;é¸æŠžã‚¿ã‚°ã‚’å‡ºåŠ›ãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸ã込む場åˆã‚­ãƒ¼ãƒ—ã™ã‚‹ +EXIFPANEL_REMOVE;リムーブ +EXIFPANEL_REMOVEHINT;é¸æŠžã‚¿ã‚°ã‚’å‡ºåŠ›ãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸ã込む場åˆå–り除ã +EXIFPANEL_RESET;リセット +EXIFPANEL_RESETALL;ã™ã¹ã¦ãƒªã‚»ãƒƒãƒˆ +EXIFPANEL_RESETALLHINT;ã™ã¹ã¦å…ƒã®å€¤ã«ãƒªã‚»ãƒƒãƒˆ +EXIFPANEL_RESETHINT;é¸æŠžã‚¿ã‚°ã‚’å…ƒã®å€¤ã«ãƒªã‚»ãƒƒãƒˆ +EXIFPANEL_SUBDIRECTORY;サブディレクトリ +FILEBROWSER_APPLYPROFILE;プロファイルã®é©å¿œ +FILEBROWSER_ARRANGEMENTHINT;サムãƒã‚¤ãƒ«æ•´åˆ— 縦/横 +FILEBROWSER_CLEARPROFILE;プロファイルã®å‰Šé™¤ +FILEBROWSER_COPYPROFILE;プロファイルをコピー +FILEBROWSER_DELETEDLGLABEL;ãƒ•ã‚¡ã‚¤ãƒ«å‰Šé™¤ç¢ºèª +FILEBROWSER_DELETEDLGMSG;%1 を削除ã—ã¦ã‚‚ã„ã„ã§ã™ã‹ï¼Ÿ +FILEBROWSER_EMPTYTRASHHINT;ゴミ箱を完全ã«ç©ºã«ã™ã‚‹ +FILEBROWSER_EMPTYTRASH;ゴミ箱を空ã«ã™ã‚‹ +FILEBROWSER_EXIFFILTERAPPLYHINT;ファイルブラウザã®Exifフィルターã®on/off +FILEBROWSER_EXIFFILTERAPPLY;é©å¿œ +FILEBROWSER_EXIFFILTERLABEL;Exifフィルター +FILEBROWSER_EXIFFILTERSETTINGS;セットアップ +FILEBROWSER_EXIFFILTERSETTINGSHINT;Exifフィルターã®è¨­å®šã‚’変ãˆã‚‹ +FILEBROWSER_PARTIALPASTEPROFILE;部分的ã«è²¼ã‚Šä»˜ã‘ +FILEBROWSER_PASTEPROFILE;プロファイルã®è²¼ã‚Šä»˜ã‘ +FILEBROWSER_POPUPCANCELJOB;ジョブ キャンセル +FILEBROWSER_POPUPMOVEEND;処ç†å¾…ã¡ã®æœ€å¾Œã«ç§»å‹• +FILEBROWSER_POPUPMOVEHEAD;処ç†å¾…ã¡ã®æœ€åˆã«ç§»å‹• +FILEBROWSER_POPUPOPEN;é–‹ã +FILEBROWSER_POPUPPROCESS;処ç†å¾…ã¡ã®åˆ—ã«å…¥ã‚Œã‚‹ +FILEBROWSER_POPUPRANK1;ランク 1 +FILEBROWSER_POPUPRANK2;ランク 2 +FILEBROWSER_POPUPRANK3;ランク 3 +FILEBROWSER_POPUPRANK4;ランク 4 +FILEBROWSER_POPUPRANK5;ランク 5 +FILEBROWSER_POPUPREMOVE;ファイルシステムã‹ã‚‰å‰Šé™¤ +FILEBROWSER_POPUPRENAME;åå‰å¤‰æ›´ +FILEBROWSER_POPUPSELECTALL;å…¨é¸æŠž +FILEBROWSER_POPUPTRASH;ゴミ箱ã¸ç§»å‹• +FILEBROWSER_POPUPUNRANK;格付ã‘ãªã— +FILEBROWSER_POPUPUNTRASH;ゴミ箱ã‹ã‚‰ç§»å‹• +FILEBROWSER_PROCESSINGSETTINGSHINT;ファイル形å¼ã¨å‡ºåŠ›ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’è¨­å®š +FILEBROWSER_PROCESSINGSETTINGS;設定 +FILEBROWSER_RENAMEDLGLABEL;ファイルå変更 +FILEBROWSER_RENAMEDLGMSG;"%1" ã«ãƒ•ァイルå変更: +FILEBROWSER_SHOWDIRHINT;ディレクトリã®ã™ã¹ã¦ã®ç”»åƒã‚’表示 +FILEBROWSER_SHOWQUEUEHINT;処ç†å¾…ã¡ã®å†…容を表示 +FILEBROWSER_SHOWRANK1HINT;ï¼‘ã¤æ˜Ÿãƒ©ãƒ³ã‚¯ã‚’表示 +FILEBROWSER_SHOWRANK2HINT;ï¼’ã¤æ˜Ÿãƒ©ãƒ³ã‚¯ã‚’表示 +FILEBROWSER_SHOWRANK3HINT;ï¼“ã¤æ˜Ÿãƒ©ãƒ³ã‚¯ã‚’表示 +FILEBROWSER_SHOWRANK4HINT;ï¼”ã¤æ˜Ÿãƒ©ãƒ³ã‚¯ã‚’表示 +FILEBROWSER_SHOWRANK5HINT;ï¼•ã¤æ˜Ÿãƒ©ãƒ³ã‚¯ã‚’表示 +FILEBROWSER_SHOWTRASHHINT;ゴミ箱ã®å†…容を表示 +FILEBROWSER_SHOWUNRANKHINT;格付ã‘ãªã—を表示 +FILEBROWSER_STARTPROCESSINGHINT;処ç†é–‹å§‹/å¾…ã¡è¡Œåˆ—ã®ä¿å­˜ +FILEBROWSER_STARTPROCESSING;処ç†é–‹å§‹ +FILEBROWSER_STOPPROCESSINGHINT;ç”»åƒå‡¦ç†ã®ä¸­æ­¢ +FILEBROWSER_STOPPROCESSING;処ç†ä¸­æ­¢ +FILEBROWSER_THUMBSIZE;サムãƒã‚¤ãƒ«.サイズ +FILEBROWSER_ZOOMINHINT;サムãƒã‚¤ãƒ«ã‚µã‚¤ã‚ºã®æ‹¡å¤§ +FILEBROWSER_ZOOMOUTHINT;サムãƒã‚¤ãƒ«ã‚µã‚¤ã‚ºã®ç¸®å° +GENERAL_ABOUT;ã«ã¤ã„㦠+GENERAL_CANCEL;キャンセル +GENERAL_DISABLED;無効 +GENERAL_DISABLE;無効 +GENERAL_ENABLED;有効 +GENERAL_ENABLE;有効 +GENERAL_LANDSCAPE;横 +GENERAL_LOAD;読ã¿è¾¼ã¿ +GENERAL_NA;n/a +GENERAL_NO;No +GENERAL_OK;OK +GENERAL_PORTRAIT;縦 +GENERAL_SAVE;ä¿å­˜ +GENERAL_YES;Yes +HISTOGRAM_LABEL;ヒストグラム +HISTOGRAM_TOOLTIP_B;ブルー・ヒストグラム 表示/éžè¡¨ç¤º +HISTOGRAM_TOOLTIP_G;グリーン・ヒストグラム 表示/éžè¡¨ç¤º +HISTOGRAM_TOOLTIP_L;CIELABè¼åº¦ãƒ»ãƒ’ストグラム 表示/éžè¡¨ç¤º +HISTOGRAM_TOOLTIP_R;レッド・ヒストグラム 表示/éžè¡¨ç¤º +HISTORY_CHANGED;変更ã•れã¾ã—㟠+HISTORY_CUSTOMCURVE;カスタムカーブ +HISTORY_DELSNAPSHOT;削除 +HISTORY_FROMCLIPBOARD;クリップボードã‹ã‚‰ +HISTORY_LABEL;履歴 +HISTORY_MSG_10;シャドウ補正 +HISTORY_MSG_11;トーンカーブ +HISTORY_MSG_12;露出 オート +HISTORY_MSG_13;露出 クリッピング +HISTORY_MSG_14;è¼åº¦ 明る㕠+HISTORY_MSG_15;è¼åº¦ コントラスト +HISTORY_MSG_16;è¼åº¦ 黒レベル +HISTORY_MSG_17;è¼åº¦ ãƒã‚¤ãƒ©ã‚¤ãƒˆåœ§ç¸® +HISTORY_MSG_18;è¼åº¦ シャドウ圧縮 +HISTORY_MSG_19;è¼åº¦ カーブ +HISTORY_MSG_1;写真を読ã¿è¾¼ã¿ã¾ã—㟠+HISTORY_MSG_20;シャープ +HISTORY_MSG_21;シャープ åŠå¾„ +HISTORY_MSG_22;シャープ é‡ +HISTORY_MSG_23;シャープ ã—ãã„値 +HISTORY_MSG_24;シャープ エッジã®ã¿ +HISTORY_MSG_25;シャープ エッジ検出 åŠå¾„ +HISTORY_MSG_26;シャープ エッジ許容 +HISTORY_MSG_27;シャープ フレア抑制 +HISTORY_MSG_28;フレア抑制 é‡ +HISTORY_MSG_29;シャープ æ–¹å¼ +HISTORY_MSG_2;プロファイルを読ã¿ã“ã¿ã¾ã—㟠+HISTORY_MSG_30;RL デコンボリューション åŠå¾„ +HISTORY_MSG_31;RL デコンボリューション é‡ +HISTORY_MSG_32;RL デコンボリューション 減衰 +HISTORY_MSG_33;RL デコンボリューション 繰返㗠+HISTORY_MSG_34;カラークリッピングãªã— +HISTORY_MSG_35;発色制é™ãƒ»æœ‰åй +HISTORY_MSG_36;ç™ºè‰²åˆ¶é™ +HISTORY_MSG_37;彩度 +HISTORY_MSG_38;ホワイトãƒãƒ©ãƒ³ã‚¹ æ–¹å¼ +HISTORY_MSG_39;色温度 +HISTORY_MSG_3;プロファイル変更 +HISTORY_MSG_40;ホワイトãƒãƒ©ãƒ³ã‚¹ 色åˆã„ +HISTORY_MSG_41;カラー シフト "A" +HISTORY_MSG_42;カラー シフト "B" +HISTORY_MSG_43;è¼åº¦ãƒŽã‚¤ã‚ºé™¤åŽ» +HISTORY_MSG_44;è¼åº¦ãƒŽã‚¤ã‚ºé™¤åŽ» åŠå¾„ +HISTORY_MSG_45;è¼åº¦ãƒŽã‚¤ã‚ºé™¤åŽ» エッジã®è¨±å®¹åº¦ +HISTORY_MSG_46;カラー ノイズ除去 +HISTORY_MSG_47;カラー ノイズ除去 åŠå¾„ +HISTORY_MSG_48;カラー ノイズ除去 エッジã®è¨±å®¹åº¦ +HISTORY_MSG_49;カラー ノイズ除去 ã‚¨ãƒƒã‚¸ã®æ„Ÿåº¦ +HISTORY_MSG_4;履歴ブラウジング +HISTORY_MSG_50;シャドウ/ãƒã‚¤ãƒ©ã‚¤ãƒˆãƒ»ãƒ„ール +HISTORY_MSG_51;ãƒã‚¤ãƒ©ã‚¤ãƒˆã‚’æš—ã +HISTORY_MSG_52;シャドウを明るã +HISTORY_MSG_53;ãƒã‚¤ãƒ©ã‚¤ãƒˆ トーンã®å¹… +HISTORY_MSG_54;シャドウ トーンã®å¹… +HISTORY_MSG_55;ローカルコントラスト +HISTORY_MSG_56;シャドウ/ãƒã‚¤ãƒ©ã‚¤ãƒˆ åŠå¾„ +HISTORY_MSG_57;90度 回転 +HISTORY_MSG_58;æ°´å¹³ã«å転 +HISTORY_MSG_59;垂直ã«å転 +HISTORY_MSG_5;明る㕠+HISTORY_MSG_6;コントラスト +HISTORY_MSG_60;回転 +HISTORY_MSG_61;回転 +HISTORY_MSG_62;歪曲åŽå·®è£œæ­£ +HISTORY_MSG_63;ã‚¹ãƒŠãƒƒãƒ—ã‚·ãƒ§ãƒƒãƒˆé¸æŠž +HISTORY_MSG_64;写真切り抜ã +HISTORY_MSG_65;色åŽå·®è£œæ­£ +HISTORY_MSG_66;ãƒã‚¤ãƒ©ã‚¤ãƒˆä¿®å¾© +HISTORY_MSG_67;ãƒã‚¤ãƒ©ã‚¤ãƒˆä¿®å¾© é‡ +HISTORY_MSG_68;ãƒã‚¤ãƒ©ã‚¤ãƒˆä¿®å¾© æ–¹å¼ +HISTORY_MSG_69;作業カラースペース +HISTORY_MSG_70;出力カラースペース +HISTORY_MSG_71;入力カラースペース +HISTORY_MSG_72;周辺光é‡è£œæ­£ +HISTORY_MSG_73;ãƒãƒ£ãƒ³ãƒãƒ«ãƒŸã‚­ã‚µãƒ¼ +HISTORY_MSG_74;リサイズ スケール +HISTORY_MSG_75;リサイズ æ–¹å¼ +HISTORY_MSG_76;Exif メタデータ +HISTORY_MSG_77;IPTC メタデータ +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;黒レベル +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;露出補正 +HISTORY_MSG_9;ãƒã‚¤ãƒ©ã‚¤ãƒˆè£œæ­£ +HISTORY_NEWSNAPSHOTAS;ラベル +HISTORY_NEWSNAPSHOT;追加 +HISTORY_NEWSSDIALOGLABEL;スナップã®ãƒ©ãƒ™ãƒ«: +HISTORY_NEWSSDIALOGTITLE;æ–°è¦ã‚¹ãƒŠãƒƒãƒ—追加 +HISTORY_SETTO;セット: +HISTORY_SNAPSHOT;スナップショット +HISTORY_SNAPSHOTS;スナップショット +ICMPANEL_FILEDLGFILTERANY;ã™ã¹ã¦ã®ãƒ•ァイル +ICMPANEL_FILEDLGFILTERICM;ICCプロファイル ファイル +ICMPANEL_GAMMABEFOREINPUT;プロファイルã«ã‚¬ãƒ³ãƒžé©å¿œ +ICMPANEL_INPUTCAMERA;カメラã®è¨­å®šå€¤ +ICMPANEL_INPUTCUSTOM;カスタム +ICMPANEL_INPUTDLGLABEL;入力 ICC ãƒ—ãƒ­ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž... +ICMPANEL_INPUTEMBEDDED;埋ã‚è¾¼ã¿ä½¿ç”¨, å¯èƒ½ãªã‚‰ +ICMPANEL_INPUTPROFILE;入力プロファイル +ICMPANEL_NOICM;No ICM: sRGB 出力 +ICMPANEL_OUTPUTDLGLABEL;出力 ICC ãƒ—ãƒ­ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž... +ICMPANEL_OUTPUTPROFILE;出力プロファイル +ICMPANEL_SAVEREFERENCE;プロファイリングã®å‚ç…§ã™ã‚‹ç”»åƒã‚’ä¿å­˜ +ICMPANEL_WORKINGPROFILE;作業プロファイル +IMAGEAREA_DETAILVIEW;詳細 +IPTCPANEL_AUTHORHINT;作æˆè€…ã®åå‰ã€ãŸã¨ãˆã°ç­†è€…ã€ã‚«ãƒ¡ãƒ©ãƒžãƒ³ã€ã‚°ãƒ©ãƒ•ィックス作æˆè€…(作æˆè€…). +IPTCPANEL_AUTHORSPOSITIONHINT;作æˆè€…ã®è‚©æ›¸ã‹ä½œå“ã®ä½œæˆè€…é”(作æˆè€… 肩書). +IPTCPANEL_AUTHORSPOSITION;作æˆè€…ã®è‚©æ›¸ +IPTCPANEL_AUTHOR;作æˆè€… +IPTCPANEL_CAPTIONHINT;ãƒ‡ãƒ¼ã‚¿ã®æœ¬æ–‡ã®è¨˜è¿°(説明--è¦ç´„) +IPTCPANEL_CAPTIONWRITERHINT;ç”»åƒã‚’編集修正ã™ã‚‹ã€ã¾ãŸã¯èª¬æ˜Ž/è¦ç´„ã®åŸ·ç­†ã«ã‹ã‹ã‚る人ã®åå‰ (記入者--編集者). +IPTCPANEL_CAPTIONWRITER;説明記入者 +IPTCPANEL_CAPTION;説明 +IPTCPANEL_CATEGORY;カテゴリ +IPTCPANEL_CATEGORYHINT;ç”»åƒã®ä¸»é¡Œã‚’識別ã™ã‚‹3文字コード (カテゴリ). +IPTCPANEL_CITYHINT;撮影ã•れãŸå¸‚ç”ºæ‘ (市町æ‘). +IPTCPANEL_CITY;å¸‚ç”ºæ‘ +IPTCPANEL_COPYHINT;IPTC設定をクリップボードã«ã‚³ãƒ”ー +IPTCPANEL_COPYRIGHTHINT;著作権情報ã«å¿…è¦ãªäº‹æŸ„ (著作権情報). +IPTCPANEL_COPYRIGHT;著作権 +IPTCPANEL_COUNTRYHINT;国åã€/ç”»åƒãŒæ’®å½±ãƒ»ä½œæˆã•れãŸå›½ (国--撮影国). +IPTCPANEL_COUNTRY;国 +IPTCPANEL_CREDIT;クレジット +IPTCPANEL_CREDITHINT;ç”»åƒã®æä¾›å…ƒã®è­˜åˆ¥, å¿…ãšã—も所有者/作æˆè€…ã§ã¯ãªã„ (クレジット). +IPTCPANEL_DATECREATEDHINT;ç”»åƒã®çŸ¥çš„内容ãŒä½œæˆã•ã‚ŒãŸæ—¥ä»˜; フォーマット: JJJJMMTT (ä½œæˆæ—¥). +IPTCPANEL_DATECREATED;ä½œæˆæ—¥ +IPTCPANEL_EMBEDDEDHINT;ç”»åƒã«åŸ‹ã‚è¾¼ã¾ã‚ŒãŸIPTCデータã«ãƒªã‚»ãƒƒãƒˆ +IPTCPANEL_EMBEDDED;埋ã‚込㿠+IPTCPANEL_HEADLINEHINT;ç”»åƒã®å†…å®¹ã®æ¦‚è¦ã‚’示ã™è¨˜å…¥é …ç›® (見出ã—). +IPTCPANEL_HEADLINE;見出㗠+IPTCPANEL_INSTRUCTIONSHINT;ç”»åƒã®ä½¿ç”¨ã«é–¢ã™ã‚‹ãã®ä»–ã®ç‰¹è¨˜äº‹é … (編集注記). +IPTCPANEL_INSTRUCTIONS;編集注記 +IPTCPANEL_KEYWORDS;キーワード +IPTCPANEL_KEYWORDSHINT;情報検索ã«ä½¿ç”¨ã™ã‚‹å˜èªž (キーワード). +IPTCPANEL_PASTEHINT;IPTC設定をクリップボードã‹ã‚‰è²¼ã‚Šä»˜ã‘ +IPTCPANEL_PROVINCEHINT;撮影ã•れãŸåœ°åŸŸ/州・県(地域--州・県). +IPTCPANEL_PROVINCE;州・都é“府県 +IPTCPANEL_RESET;リセット +IPTCPANEL_RESETHINT;デフォルトã®ãƒ—ロファイルã«ãƒªã‚»ãƒƒãƒˆ +IPTCPANEL_SOURCE;ソース +IPTCPANEL_SOURCEHINT;ç”»åƒã®è‘—ä½œæ¨©ä¿æœ‰è€… (ソース). +IPTCPANEL_SUPPCATEGORIESHINT;ã•らã«ç´°ã‹ãç”»åƒã®ä¸»é¡Œ (カテゴリ補助). +IPTCPANEL_SUPPCATEGORIES;カテゴリ補助 +IPTCPANEL_TITLE;タイトル +IPTCPANEL_TITLEHINT;ç”»åƒã®è¡¨é¡Œã‚’簡略㫠(タイトル). +IPTCPANEL_TRANSREFERENCEHINT;オリジナルã®é€ä¿¡è¨¼æ˜Žã®ä½ç½®ã‚’表ã™ã‚³ãƒ¼ãƒ‰ (オリジナル é€ä¿¡è¨¼æ˜Ž). +IPTCPANEL_TRANSREFERENCE;é€ä¿¡è¨¼æ˜Ž +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;環境設定 +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;別途ä¿å­˜ +MAIN_BUTTON_SAVE;ç”»åƒã®ä¿å­˜ +MAIN_BUTTON_SENDTOEDITOR;エディターã«é€ã‚‹ +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;ファイルã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ +MAIN_MSG_CANNOTLOAD;ç”»åƒã‚’読ã¿è¾¼ã¿ã§ãã¾ã›ã‚“ +MAIN_MSG_CANNOTSAVE;ファイルä¿å­˜ã‚¨ãƒ©ãƒ¼ +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;"環境設定"ã®æ­£ã—ã„パスを設定ã—ã¦ãã ã•ã„ +MAIN_MSG_CANNOTSTARTEDITOR;エディタを開始ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“. +MAIN_MSG_EXITJOBSINQUEUEINFO;未処ç†ç”»åƒã®é †ç•ªã¯çµ‚了時ã«å¤±ã‚れã¾ã™ +MAIN_MSG_EXITJOBSINQUEUEQUEST;処ç†å¾…ã¡ã®ç”»åƒãŒã‚りã¾ã™ãŒã€çµ‚了ã—ã¾ã™ã‹ï¼Ÿ +MAIN_MSG_JOBSINQUEUE; 作業中・・・ +MAIN_MSG_QOVERWRITE;上書ãã—ã¾ã™ã‹ï¼Ÿ +MAIN_TAB_BASIC;ベーシック +MAIN_TAB_COLOR;カラー +MAIN_TAB_DETAIL;ディテール +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;露出 +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;メタデータ +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;変形 +MAIN_TOOLTIP_HIDEFP;ボタンパãƒãƒ« 表示/éžè¡¨ç¤º(ディレクトリã¨ãƒ•ァイルブラウザ, ショートカット キー: F) +MAIN_TOOLTIP_HIDEHP;左パãƒãƒ« 表示/éžè¡¨ç¤º (履歴å«ã‚€, ショートカット キー: H) +MAIN_TOOLTIP_INDCLIPPEDH;ãƒã‚¤ãƒ©ã‚¤ãƒˆãƒ»ã‚¯ãƒªãƒƒãƒ”ング領域ã®è¡¨ç¤º +MAIN_TOOLTIP_INDCLIPPEDS;シャドウ・クリッピング領域ã®è¡¨ç¤º +MAIN_TOOLTIP_PREFERENCES;設定ã™ã‚‹ +MAIN_TOOLTIP_QINFO;ç”»åƒã®æƒ…å ± +MAIN_TOOLTIP_SAVEAS;ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã‚’é¸æŠžã—ã¦ä¿å­˜ +MAIN_TOOLTIP_SAVE;デフォルトã®ãƒ•ォルダーã«ä¿å­˜ +PARTIALPASTE_BASICGROUP;基本設定 +PARTIALPASTE_CACORRECTION;色åŽå·®è£œæ­£ +PARTIALPASTE_COARSETRANS;90度 回転 / å転 +PARTIALPASTE_COLORBOOST;発色補正 +PARTIALPASTE_COLORDENOISE;カラー ノイズ除去 +PARTIALPASTE_COLORGROUP;カラー 設定 +PARTIALPASTE_COLORMIXER;カラー ミキサー +PARTIALPASTE_COLORSHIFT;カラー シフト +PARTIALPASTE_COMPOSITIONGROUP;変形 設定 +PARTIALPASTE_CROP;切り抜ã +PARTIALPASTE_DIALOGLABEL;å‡¦ç†æ¸ˆã¿ãƒ—ロファイルã®éƒ¨åˆ†ãƒšãƒ¼ã‚¹ãƒˆ +PARTIALPASTE_DISTORTION;歪曲補正 +PARTIALPASTE_EXIFCHANGES;exifデータを変ãˆã‚‹ +PARTIALPASTE_EXPOSURE;露出 +PARTIALPASTE_HLRECOVERY;ãƒã‚¤ãƒ©ã‚¤ãƒˆä¿®å¾© +PARTIALPASTE_ICMSETTINGS;ICM 設定 +PARTIALPASTE_IPTCINFO;IPTC 情報 +PARTIALPASTE_LENSGROUP;レンズ設定 +PARTIALPASTE_LUMACURVE;è¼åº¦ã‚«ãƒ¼ãƒ– +PARTIALPASTE_LUMADENOISE;è¼åº¦ ノイズ除去 +PARTIALPASTE_LUMINANCEGROUP;è¼åº¦è¨­å®š +PARTIALPASTE_METAICMGROUP;メタデータ/ICM 設定 +PARTIALPASTE_RESIZE;リサイズ +PARTIALPASTE_ROTATION;回転 +PARTIALPASTE_SHADOWSHIGHLIGHTS;シャドウ/ãƒã‚¤ãƒ©ã‚¤ãƒˆ +PARTIALPASTE_SHARPENING;シャープ化 +PARTIALPASTE_VIGNETTING;周辺光é‡è£œæ­£ +PARTIALPASTE_WHITEBALANCE;ホワイトãƒãƒ©ãƒ³ã‚¹ +PREFERENCES_APPLNEXTSTARTUP;次ã®èµ·å‹•時ã«é©å¿œ +PREFERENCES_BLINKCLIPPED;クリッピング領域ã®ç‚¹æ»… +PREFERENCES_CACHECLEARALL;ã™ã¹ã¦å‰Šé™¤ +PREFERENCES_CACHECLEARPROFILES;プロファイルã®å‰Šé™¤ +PREFERENCES_CACHECLEARTHUMBS;サムãƒã‚¤ãƒ«ã®å‰Šé™¤ +PREFERENCES_CACHEFORMAT1;独自仕様 (速ã 良質) +PREFERENCES_CACHEFORMAT2;JPEG (å°‘ãªã„ãƒ‡ã‚£ã‚¹ã‚¯å æœ‰) +PREFERENCES_CACHEMAXENTRIES;最大キャッシュエントリー数 +PREFERENCES_CACHEOPTS;キャッシュ オプション +PREFERENCES_CACHESTRAT1;スピードé‡è¦– +PREFERENCES_CACHESTRAT2;メモリ消費é‡è¦– +PREFERENCES_CACHESTRAT;キャッシュé‹ç”¨ã®æ–¹é‡ +PREFERENCES_CACHETHUMBFORM;キャッシュã®ã‚µãƒ ãƒã‚¤ãƒ«å½¢å¼ +PREFERENCES_CACHETHUMBHEIGHT;サムãƒã‚¤ãƒ«ç¸¦ã®æœ€å¤§å€¤ +PREFERENCES_CLEARDLG_LINE1;キャッシュã®å‰Šé™¤ +PREFERENCES_CLEARDLG_LINE2;数秒掛ã‹ã‚‹ã‹ã‚‚・・ +PREFERENCES_CLEARDLG_TITLE;ã¡ã‚‡ã£ã¨å¾…ã£ã¦ãƒ»ãƒ» +PREFERENCES_CLIPPINGIND;クリッピング領域ã®è¡¨ç¤º +PREFERENCES_CMETRICINTENT;レンダリング・インテント +PREFERENCES_DATEFORMAT;データフォーマット +PREFERENCES_DATEFORMATHINT;æ¬¡ã®æ›¸å¼ã‚’使用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™:\n%y : å¹´\n%m : 月\n%d : æ—¥\n\n例ã¨ã—ã¦, ãƒãƒ³ã‚¬ãƒªã‚¢ãƒ³è¨˜æ³•:\n%y/%m/%d +PREFERENCES_DEFAULTLANG;デフォルトã®è¨€èªž +PREFERENCES_DEFAULTTHEME;デフォルト テーマ +PREFERENCES_DEMOSAICINGALGO;ãƒ‡ãƒ¢ã‚¶ã‚¤ã‚¯å‡¦ç† +PREFERENCES_DIRHOME;ホーム・ディレクトリ +PREFERENCES_DIRLAST;最近å‚ç…§ã—ãŸãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª +PREFERENCES_DIROTHER;ä»– +PREFERENCES_DIRSELECTDLG;起動時ã®ç”»åƒãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªé¸æŠž... +PREFERENCES_DIRSOFTWARE;インストール・ディレクトリ +PREFERENCES_DMETHOD;方法 +PREFERENCES_EDITORCMDLINE;ãã®ä»–・コマンド入力 +PREFERENCES_EXTERNALEDITOR;外部エディター +PREFERENCES_FALSECOLOR;å½è‰² 補間ステップ +PREFERENCES_FBROWSEROPTS;ファイルブラウザã®ã‚ªãƒ—ション +PREFERENCES_FILEFORMAT;ãƒ•ã‚¡ã‚¤ãƒ«å½¢å¼ +PREFERENCES_FORIMAGE;ç”»åƒãƒ•ァイル +PREFERENCES_FORRAW;RAW ファイル +PREFERENCES_GIMPPATH;GIMP インストール ディレクトリ +PREFERENCES_GTKTHEME;GTK デフォルト +PREFERENCES_HINT;ヒント +PREFERENCES_HLTHRESHOLD;ãƒã‚¤ãƒ©ã‚¤ãƒˆãƒ»ã‚¯ãƒªãƒƒãƒ”ング領域ã®ã—ãã„値 +PREFERENCES_ICCDIR;ICCプロファイルã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª +PREFERENCES_IMPROCPARAMS;ç”»åƒå‡¦ç†ã®è¦å®šå€¤ +PREFERENCES_INTENT_ABSOLUTE;絶対的ãªè‰²åŸŸã‚’ç¶­æŒ +PREFERENCES_INTENT_PERCEPTUAL;知覚的 +PREFERENCES_INTENT_RELATIVE;相対的ãªè‰²åŸŸã‚’ç¶­æŒ +PREFERENCES_INTENT_SATURATION;彩度 +PREFERENCES_LIVETHUMBNAILS;ライブ・サムãƒã‚¤ãƒ« (é…ã„) +PREFERENCES_MONITORICC;モニタープロファイル +PREFERENCES_OUTDIRFOLDERHINT;é¸æŠžã—ãŸãƒ•ォルダーã«ç”»åƒã‚’ä¿å­˜ã—ã¾ã™ +PREFERENCES_OUTDIRFOLDER;フォルダーã«ä¿å­˜ +PREFERENCES_OUTDIRHINT;æ¬¡ã®æ›¸å¼ã‚’使用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nã“ã‚Œã‚‰ã®æ›¸å¼ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¨rawファイルã®ã‚µãƒ–パスを示ã—ã¾ã™.\n\n例ãˆã°, /home/tom/image/02-09-2006/dsc0012.nefã‚’é–‹ã„ã¦ã„ãŸãªã‚‰, æ›¸å¼æ–‡å­—ã®æ„味ã¯:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nå…ƒã®ã¨ã“ã‚ã«å‡ºåŠ›ç”»åƒã‚’ä¿å­˜ã—ãŸã„ãªã‚‰, ã“ã®ã‚ˆã†ã«æ›¸ãã¾ã™:\n%p1/%f\n\nå…ƒã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®'converted'ディレクトリã®ä¸­ã«å‡ºåŠ›ç”»åƒã‚’ä¿å­˜ã—ãŸã„ãªã‚‰, ã“ã®ã‚ˆã†ã«æ›¸ãã¾ã™:\n%p1/converted/%f\n\nåŒã˜æ—¥ä»˜ã®ã‚µãƒ–ディレクトリをä¿ã£ãŸã¾ã¾'/home/tom/converted'ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®ä¸­ã«å‡ºåŠ›ç”»åƒã‚’ä¿å­˜ã—ãŸã„ã®ãªã‚‰, ã“ã®ã‚ˆã†ã«æ›¸ãã¾ã™:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;æ¬¡ã®æ›¸å¼ã‚’使用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nã“ã‚Œã‚‰ã®æ›¸å¼ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¨rawファイルã®ã‚µãƒ–パスを示ã—ã¾ã™.\n\n例ãˆã°, /home/tom/image/02-09-2006/dsc0012.nefã‚’é–‹ã„ã¦ã„ãŸãªã‚‰, æ›¸å¼æ–‡å­—ã®æ„味ã¯:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nå…ƒã®ã¨ã“ã‚ã«å‡ºåŠ›ç”»åƒã‚’ä¿å­˜ã—ãŸã„ãªã‚‰, ã“ã®ã‚ˆã†ã«æ›¸ãã¾ã™:\n%p1/%f\n\nå…ƒã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®'converted'ディレクトリã®ä¸­ã«å‡ºåŠ›ç”»åƒã‚’ä¿å­˜ã—ãŸã„ãªã‚‰, ã“ã®ã‚ˆã†ã«æ›¸ãã¾ã™:\n%p1/converted/%f\n\nåŒã˜æ—¥ä»˜ã®ã‚µãƒ–ディレクトリをä¿ã£ãŸã¾ã¾'/home/tom/converted'ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®ä¸­ã«å‡ºåŠ›ç”»åƒã‚’ä¿å­˜ã—ãŸã„ã®ãªã‚‰, ã“ã®ã‚ˆã†ã«æ›¸ãã¾ã™:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;テンプレートを使ㆠ+PREFERENCES_OUTDIR;出力ディレクトリ +PREFERENCES_PARSEDEXTADDHINT;æ‹¡å¼µå­ã‚’記入㗠ã“ã®ãƒœã‚¿ãƒ³ã§ãƒªã‚¹ãƒˆã«è¿½åŠ ã—ã¾ã™ +PREFERENCES_PARSEDEXTADD;æ‹¡å¼µå­ã‚’加ãˆã‚‹ +PREFERENCES_PARSEDEXTDELHINT;é¸æŠžã—ãŸæ‹¡å¼µå­ã‚’リストã‹ã‚‰å‰Šé™¤ã—ã¾ã™ +PREFERENCES_PARSEDEXT;æ‹¡å¼µå­ +PREFERENCES_PROFILEHANDLING;処ç†ãƒ—ロファイルã®å–扱ㄠ+PREFERENCES_PROFILELOADPR;プロファイル読ã¿è¾¼ã¿ã®å„ªå…ˆæ¨© +PREFERENCES_PROFILEPRCACHE;キャッシュã®ãƒ—ロファイル +PREFERENCES_PROFILEPRFILE;入力ファイル・ディレクトリã®ãƒ—ロファイル +PREFERENCES_PROFILESAVECACHE;å‡¦ç†æ¸ˆã¿ã®ãƒ—ロファイル・パラメータをキャッシュã«ä¿å­˜ +PREFERENCES_PROFILESAVEINPUT;å‡¦ç†æ¸ˆã¿ãƒ—ロファイル・パラメータを入力ファイルã¨åŒã˜ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«ä¿å­˜ +PREFERENCES_PSPATH;Adobe Photoshop ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª +PREFERENCES_SELECTICCDIRDLG;ICCãƒ—ãƒ­ãƒ•ã‚¡ã‚¤ãƒ«ãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªé¸æŠž... +PREFERENCES_SELECTLANG;è¨€èªžé¸æŠž +PREFERENCES_SELECTMONITORPROFDLG;ディスプレイã®ICCãƒ—ãƒ­ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž... +PREFERENCES_SELECTTHEME;é¸æŠž テーマ +PREFERENCES_SHOWBASICEXIF;基本Exif情報 表示 +PREFERENCES_SHOWDATETIME;日付表示 +PREFERENCES_SHOWONLYRAW;RAWファイルã®ã¿è¡¨ç¤º +PREFERENCES_SHTHRESHOLD;シャドウ・クリッピング領域ã®ã—ãã„値 +PREFERENCES_STARTUPIMDIR;起動時ã®ç”»åƒãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª +PREFERENCES_TAB_BROWSER;ファイルブラウザ +PREFERENCES_TAB_COLORMGR;カラーマãƒã‚¸ãƒ¡ãƒ³ãƒˆ +PREFERENCES_TAB_GENERAL;一般 +PREFERENCES_TAB_IMPROC;ç”»åƒå‡¦ç† +PREFERENCES_TAB_OUTPUT;出力オプション +PREFERENCES_THUMBSIZE;サムãƒã‚¤ãƒ«ãƒ»ã‚µã‚¤ã‚º +PROFILEPANEL_FILEDLGFILTERANY;ã™ã¹ã¦ã®ãƒ•ァイル +PROFILEPANEL_FILEDLGFILTERPP;å‡¦ç†æ¸ˆã¿ãƒ—ロファイル +PROFILEPANEL_LABEL;å‡¦ç†æ¸ˆã¿ãƒ—ロファイル +PROFILEPANEL_LOADDLGLABEL;å‡¦ç†æ¸ˆã¿ãƒ—ロファイルを読ã¿è¾¼ã‚€... +PROFILEPANEL_PCUSTOM;カスタム +PROFILEPANEL_PFILE;ファイルã‹ã‚‰ +PROFILEPANEL_PLASTPHOTO;更新済ã®å†™çœŸ +PROFILEPANEL_PLASTSAVED;更新済 +PROFILEPANEL_PROFILE;プロファイル +PROFILEPANEL_SAVEDLGLABEL;å‡¦ç†æ¸ˆã¿ãƒ—ロファイルをä¿å­˜... +PROFILEPANEL_TOOLTIPCOPY;クリップボードã«ãƒ—ロファイルをコピー +PROFILEPANEL_TOOLTIPLOAD;ファイルã‹ã‚‰ãƒ—ロファイルを読ã¿è¾¼ã‚€ +PROFILEPANEL_TOOLTIPPASTE; クリップボードã‹ã‚‰ãƒ—ロファイルを貼り付㑠+PROFILEPANEL_TOOLTIPSAVE;ç¾åœ¨ã®ãƒ—ロファイルをä¿å­˜ +PROGRESSBAR_DECODING;rawファイルデコード中... +PROGRESSBAR_DEMOSAICING;デモザイク処ç†ä¸­... +PROGRESSBAR_LOADING;ç”»åƒèª­ã¿è¾¼ã¿ä¸­... +PROGRESSBAR_LOADJPEG;JPEGファイル読ã¿è¾¼ã¿ä¸­... +PROGRESSBAR_LOADPNG;;PNGファイル読ã¿è¾¼ã¿ä¸­... +PROGRESSBAR_LOADTIFF;TIFFファイル読ã¿è¾¼ã¿ä¸­... +PROGRESSBAR_PROCESSING;ç”»åƒå‡¦ç†ä¸­... +PROGRESSBAR_READY;準備ãŒã§ãã¾ã—㟠+PROGRESSBAR_SAVEJPEG;JPEGファイルä¿å­˜ä¸­... +PROGRESSBAR_SAVEPNG;PNGファイルä¿å­˜ä¸­... +PROGRESSBAR_SAVETIFF;TIFFファイルä¿å­˜ä¸­... +PROGRESSDLG_LOADING;ç”»åƒã®èª­ã¿è¾¼ã¿ä¸­... +PROGRESSDLG_PROCESSING;ç”»åƒã®å‡¦ç†ä¸­... +PROGRESSDLG_SAVING;ファイルä¿å­˜ä¸­... +QINFO_FOCALLENGTH;焦点è·é›¢ +QINFO_ISO;ISO +QINFO_LENS;レンズ +QINFO_NOEXIF;ExifデータãŒã‚りã¾ã›ã‚“ +SAVEDLG_FILEFORMAT;ãƒ•ã‚¡ã‚¤ãƒ«å½¢å¼ +SAVEDLG_JPEGQUAL;JPEG å“質 +SAVEDLG_JPGFILTER;JPEG ファイル +SAVEDLG_PNGCOMPR;PNG 圧縮 +SAVEDLG_PNGFILTER;PNG ファイル +SAVEDLG_PUTTOQUEUEHEAD;処ç†å¾…ã¡ã®æœ€åˆã«å…¥ã‚Œã‚‹ +SAVEDLG_PUTTOQUEUETAIL;処ç†å¾…ã¡ã®æœ€å¾Œã«å…¥ã‚Œã‚‹ +SAVEDLG_PUTTOQUEUE;処ç†å¾…ã¡ã«å…¥ã‚Œã‚‹ +SAVEDLG_SAVEIMMEDIATELY;ã™ãã«ä¿å­˜ +SAVEDLG_SAVESPP;設定値もä¿å­˜ã™ã‚‹ +SAVEDLG_TIFFFILTER;TIFF ファイル +TOOLBAR_TOOLTIP_CROP;切り抜ãç¯„å›²é¸æŠž (ショートカット キー: C) +TOOLBAR_TOOLTIP_HAND;手ã®å¹³ãƒ„ール (ショートカット キー: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;ç›´ç·šé¸æŠž (ショートカット キー: S) +TOOLBAR_TOOLTIP_WB;スãƒãƒƒãƒˆãƒ»ãƒ›ãƒ¯ã‚¤ãƒˆãƒãƒ©ãƒ³ã‚¹ (ショートカット キー: W) +TP_CACORRECTION_BLUE;ブルー +TP_CACORRECTION_LABEL;色åŽå·®è£œæ­£ +TP_CACORRECTION_RED;レッド +TP_CHMIXER_BLUE;ブルー +TP_CHMIXER_GREEN;グリーン +TP_CHMIXER_LABEL;ãƒãƒ£ãƒ³ãƒãƒ«ãƒŸã‚­ã‚µãƒ¼ +TP_CHMIXER_RED;レッド +TP_COARSETRAF_DEGREE;度: +TP_COARSETRAF_TOOLTIP_HFLIP;æ°´å¹³ã«å転 +TP_COARSETRAF_TOOLTIP_ROTLEFT;90度左回転 +TP_COARSETRAF_TOOLTIP_ROTRIGHT;90度å³å›žè»¢ +TP_COARSETRAF_TOOLTIP_VFLIP;垂直ã«å転 +TP_COLORBOOST_ACHANNEL;a ãƒãƒ£ãƒ³ãƒãƒ« +TP_COLORBOOST_AMOUNT;é‡ +TP_COLORBOOST_AVOIDCOLORCLIP;カラークリッピングãªã— +TP_COLORBOOST_BCHANNEL;b ãƒãƒ£ãƒ³ãƒãƒ« +TP_COLORBOOST_CHAB;a & b +TP_COLORBOOST_CHANNEL;ãƒãƒ£ãƒ³ãƒãƒ« +TP_COLORBOOST_CHSEPARATE;a/b分離 +TP_COLORBOOST_ENABLESATLIMITER;発色制é™ãƒ»æœ‰åй +TP_COLORBOOST_LABEL;彩度 +TP_COLORBOOST_SATLIMIT;ç™ºè‰²åˆ¶é™ +TP_COLORDENOISE_EDGESENSITIVE;ã‚¨ãƒƒã‚¸ã®æ„Ÿåº¦ +TP_COLORDENOISE_EDGETOLERANCE;エッジã®è¨±å®¹åº¦ +TP_COLORDENOISE_LABEL;カラー ノイズ除去 +TP_COLORDENOISE_RADIUS;åŠå¾„ +TP_COLORSHIFT_BLUEYELLOW;ブルー-イエロー +TP_COLORSHIFT_GREENMAGENTA;グリーン-マゼンタ +TP_COLORSHIFT_LABEL;カラー シフト +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;縦横比 固定: +TP_CROP_GTDIAGONALS;対角線 +TP_CROP_GTHARMMEANS1;èª¿å’Œå¹³å‡ 1 +TP_CROP_GTHARMMEANS2;èª¿å’Œå¹³å‡ 2 +TP_CROP_GTHARMMEANS3;èª¿å’Œå¹³å‡ 3 +TP_CROP_GTHARMMEANS4;èª¿å’Œå¹³å‡ 4 +TP_CROP_GTNONE;ãªã— +TP_CROP_GTRULETHIRDS;三分割 +TP_CROP_GUIDETYPE;ガイドタイプ: +TP_CROP_H;H +TP_CROP_LABEL;切り抜ã +TP_CROP_SELECTCROP; é¸æŠžç¯„å›²åˆ‡ã‚ŠæŠœã +TP_CROP_W;W +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;é‡ +TP_DISTORTION_LABEL;歪曲åŽå·®è£œæ­£ +TP_EXPOSURE_AUTOLEVELS;オートレベル +TP_EXPOSURE_BLACKLEVEL;黒レベル +TP_EXPOSURE_BRIGHTNESS;明る㕠+TP_EXPOSURE_CLIP;クリップ +TP_EXPOSURE_COMPRHIGHLIGHTS;ãƒã‚¤ãƒ©ã‚¤ãƒˆåœ§ç¸® +TP_EXPOSURE_COMPRSHADOWS;シャドウ圧縮 +TP_EXPOSURE_CONTRAST;コントラスト +TP_EXPOSURE_CURVEEDITOR;トーンカーブ +TP_EXPOSURE_EXPCOMP;露出補正 +TP_EXPOSURE_LABEL;露出 +TP_HLREC_CIELAB;CIELab ブレンディング +TP_HLREC_COLOR;è‰²ã®æ³¢åŠ +TP_HLREC_LABEL;ãƒã‚¤ãƒ©ã‚¤ãƒˆä¿®å¾© +TP_HLREC_LUMINANCE;è¼åº¦ä¿®å¾© +TP_HLREC_METHOD;æ–¹å¼: +TP_ICM_FILEDLGFILTERANY;ã™ã¹ã¦ã®ãƒ•ァイル +TP_ICM_FILEDLGFILTERICM;ICCプロファイル ファイル +TP_ICM_GAMMABEFOREINPUT;プロファイルã«ã‚¬ãƒ³ãƒžé©å¿œ +TP_ICM_INPUTCAMERA;カメラã®è¨­å®šå€¤ +TP_ICM_INPUTCUSTOM;カスタム +TP_ICM_INPUTDLGLABEL;入力 ICC ãƒ—ãƒ­ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž... +TP_ICM_INPUTEMBEDDED;埋ã‚è¾¼ã¿ä½¿ç”¨, å¯èƒ½ãªã‚‰ +TP_ICM_INPUTPROFILE;入力プロファイル +TP_ICM_LABEL;ICM +TP_ICM_NOICM;No ICM: sRGB 出力 +TP_ICM_OUTPUTDLGLABEL;出力 ICC ãƒ—ãƒ­ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž... +TP_ICM_OUTPUTPROFILE;出力プロファイル +TP_ICM_SAVEREFERENCE;プロファイリングã®å‚ç…§ã™ã‚‹ç”»åƒã‚’ä¿å­˜ +TP_ICM_WORKINGPROFILE;作業プロファイル +TP_LUMACURVE_BLACKLEVEL;黒レベル +TP_LUMACURVE_BRIGHTNESS;明る㕠+TP_LUMACURVE_COMPRHIGHLIGHTS;ãƒã‚¤ãƒ©ã‚¤ãƒˆåœ§ç¸® +TP_LUMACURVE_COMPRSHADOWS;シャドウ圧縮 +TP_LUMACURVE_CONTRAST;コントラスト +TP_LUMACURVE_CURVEEDITOR;è¼åº¦ã‚«ãƒ¼ãƒ–エディター +TP_LUMACURVE_LABEL;è¼åº¦ã‚«ãƒ¼ãƒ– +TP_LUMADENOISE_EDGETOLERANCE;エッジã®è¨±å®¹åº¦ +TP_LUMADENOISE_LABEL;è¼åº¦ ノイズ除去 +TP_LUMADENOISE_RADIUS;åŠå¾„ +TP_RESIZE_BICUBIC;ãƒã‚¤ã‚­ãƒ¥ãƒ¼ãƒ“ック +TP_RESIZE_BICUBICSF;ãƒã‚¤ã‚­ãƒ¥ãƒ¼ãƒ“ック (ソフトã«) +TP_RESIZE_BICUBICSH;ãƒã‚¤ã‚­ãƒ¥ãƒ¼ãƒ“ック (シャープã«) +TP_RESIZE_BILINEAR;ãƒã‚¤ãƒªãƒ‹ã‚¢ +TP_RESIZE_FULLSIZE;フル ç”»åƒ ã‚µã‚¤ã‚º: +TP_RESIZE_H;H: +TP_RESIZE_LABEL;リサイズ +TP_RESIZE_METHOD;æ–¹å¼: +TP_RESIZE_NEAREST;ニアリスト +TP_RESIZE_SCALE;スケール +TP_RESIZE_W;W: +TP_ROTATE_AUTOCROP;自動的ã«åˆ‡ã‚ŠæŠœãé¸æŠž +TP_ROTATE_DEGREE;度 +TP_ROTATE_FILL;塗り +TP_ROTATE_LABEL;回転 +TP_ROTATE_SELECTLINE;ç›´ç·šé¸æŠž +TP_SHADOWSHLIGHTS_HIGHLIGHTS;ãƒã‚¤ãƒ©ã‚¤ãƒˆã‚’æš—ã +TP_SHADOWSHLIGHTS_HLTONALW;ãƒã‚¤ãƒ©ã‚¤ãƒˆ トーンã®å¹… +TP_SHADOWSHLIGHTS_LABEL;シャドウ/ãƒã‚¤ãƒ©ã‚¤ãƒˆ +TP_SHADOWSHLIGHTS_LOCALCONTR;ローカルコントラスト +TP_SHADOWSHLIGHTS_RADIUS;åŠå¾„ +TP_SHADOWSHLIGHTS_SHADOWS;シャドウを明るã +TP_SHADOWSHLIGHTS_SHTONALW;シャドウ トーンã®å¹… +TP_SHARPENING_AMOUNT;é‡ +TP_SHARPENING_EDRADIUS;åŠå¾„ +TP_SHARPENING_EDTOLERANCE;エッジ許容 +TP_SHARPENING_HALOCONTROL;フレア抑制 +TP_SHARPENING_HCAMOUNT;é‡ +TP_SHARPENING_LABEL;シャープ化 +TP_SHARPENING_METHOD;æ–¹å¼ +TP_SHARPENING_ONLYEDGES;エッジã®ã¿ +TP_SHARPENING_RADIUS;åŠå¾„ +TP_SHARPENING_RLD_AMOUNT;é‡ +TP_SHARPENING_RLD_DAMPING;減衰 +TP_SHARPENING_RLD_ITERATIONS;繰返㗠+TP_SHARPENING_RLD;RL デコンボリューション +TP_SHARPENING_THRESHOLD;ã—ãã„値 +TP_SHARPENING_USM;アンシャープマスク +TP_VIGNETTING_AMOUNT;é‡ +TP_VIGNETTING_LABEL;周辺光é‡è£œæ­£ +TP_VIGNETTING_RADIUS;åŠå¾„ +TP_WBALANCE_AUTO;オート +TP_WBALANCE_CAMERA;カメラ +TP_WBALANCE_CUSTOM;カスタム +TP_WBALANCE_GREEN;色åˆã„ +TP_WBALANCE_LABEL;ホワイトãƒãƒ©ãƒ³ã‚¹ +TP_WBALANCE_METHOD;æ–¹å¼ +TP_WBALANCE_SIZE;サイズ: +TP_WBALANCE_SPOTWB;スãƒãƒƒãƒˆWB +TP_WBALANCE_TEMPERATURE;色温度 +ZOOMBAR_DETAIL;ディテール +ZOOMBAR_HUGE;特大 +ZOOMBAR_LARGE;大 +ZOOMBAR_NORMAL;標準 +ZOOMBAR_PREVIEW;プレビュー +ZOOMBAR_SCALE;スケール +ZOOMBAR_SMALL;å° + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Latvian b/rtdata/languages/Latvian new file mode 100644 index 000000000..3d1f3bde9 --- /dev/null +++ b/rtdata/languages/Latvian @@ -0,0 +1,703 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# +# Latvian language file +# +ADJUSTER_RESET_TO_DEFAULT;Atmest uz noklusÄ“to +CURVEEDITOR_FILEDLGFILTERANY;Visi faili +CURVEEDITOR_FILEDLGFILTERCURVE;LÄ«kņu faili +CURVEEDITOR_LINEAR;LineÄri +CURVEEDITOR_LOADDLGLABEL;IelÄdÄ“t lÄ«kni... +CURVEEDITOR_SAVEDLGLABEL;SaglabÄt lÄ«kni... +CURVEEDITOR_TOOLTIPLINEAR;Iztaisnot lÄ«kni +CURVEEDITOR_TOOLTIPLOAD;IelÄdÄ“t lÄ«kni no faila +CURVEEDITOR_TOOLTIPSAVE;SaglabÄt esoÅ¡o lÄ«kni +EXIFFILTER_APERTURE;AtvÄ“rums +EXIFFILTER_CAMERA;Kamera +EXIFFILTER_DIALOGLABEL;Exif Filtrs +EXIFFILTER_FOCALLEN;Fokusa garums +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;LÄ“ca +EXIFFILTER_SHUTTER;SlÄ“dzis +EXIFPANEL_ADDEDITHINT;Pielikt jaunu birku vai labot birku +EXIFPANEL_ADDEDIT;Pielikt/Labot +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Ievadiet vÄ“rtÄ«bu +EXIFPANEL_ADDTAGDLG_SELECTTAG;IzvÄ“lÄ“t birku +EXIFPANEL_ADDTAGDLG_TITLE;Pielikt/Labot birku +EXIFPANEL_KEEP;AtstÄt +EXIFPANEL_KEEPHINT;AtstÄt izvÄ“lÄ“tÄs birkas kad raksta izvades failu +EXIFPANEL_REMOVEHINT;Noņemt izvÄ“lÄ“tÄs birkas kad raksta izvades failu +EXIFPANEL_REMOVE;Noņemt +EXIFPANEL_RESETALL;Atmest visu +EXIFPANEL_RESETALLHINT;Atmest visas birkas uz to noklusÄ“tajÄm vÄ“rtÄ«bÄm +EXIFPANEL_RESET;Atmest +EXIFPANEL_RESETHINT;Atmest izvÄ“lÄ“tÄs birkas uz to noklusÄ“tajÄm vÄ“rtÄ«bÄm +EXIFPANEL_SUBDIRECTORY;Subdirektorijs +FILEBROWSER_APPLYPROFILE;Lietot profilu +FILEBROWSER_ARRANGEMENTHINT;PÄrslÄ“gt sÄ«ktÄ“lu izvietojumu vertikÄli/horizontÄli +FILEBROWSER_CLEARPROFILE;NotÄ«rÄ«t profilu +FILEBROWSER_COPYPROFILE;KopÄ“t profilu +FILEBROWSER_DELETEDLGLABEL;Faila dzēšanas apstiprinÄjums +FILEBROWSER_DELETEDLGMSG;Vai tieÅ¡Äm dzÄ“st %1 atzÄ«mÄ“tos filus? +FILEBROWSER_EMPTYTRASHHINT;GalÄ«gi izdzÄ“st atkritnes failus +FILEBROWSER_EMPTYTRASH;Izmest atkritumus +FILEBROWSER_EXIFFILTERAPPLYHINT;PÄrslÄ“gt failu pÄrlÅ«ka exif filtru +FILEBROWSER_EXIFFILTERAPPLY;Lietot +FILEBROWSER_EXIFFILTERLABEL;Exif filtrs +FILEBROWSER_EXIFFILTERSETTINGSHINT;MainÄ«t exif filtra uzstÄdÄ«jumus +FILEBROWSER_EXIFFILTERSETTINGS;UzstÄdÄ«jumi +FILEBROWSER_PARTIALPASTEPROFILE;Daļēja ielÄ«mēšana +FILEBROWSER_PASTEPROFILE;IelÄ«mÄ“t profilu +FILEBROWSER_POPUPCANCELJOB;Atcelt darbu +FILEBROWSER_POPUPMOVEEND;PÄrvietot uz rindas beigÄm +FILEBROWSER_POPUPMOVEHEAD;PÄrvietot uz rindas sÄkumu +FILEBROWSER_POPUPOPEN;AtvÄ“rt +FILEBROWSER_POPUPPROCESS;Ielikt apstrÄdes rindÄ +FILEBROWSER_POPUPRANK1;VÄ“rtÄ“t 1 +FILEBROWSER_POPUPRANK2;VÄ“rtÄ“t 2 +FILEBROWSER_POPUPRANK3;VÄ“rtÄ“t 3 +FILEBROWSER_POPUPRANK4;VÄ“rtÄ“t 4 +FILEBROWSER_POPUPRANK5;VÄ“rtÄ“t 5 +FILEBROWSER_POPUPREMOVE;DzÄ“st no failu sistÄ“mas +FILEBROWSER_POPUPRENAME;PÄrsaukt +FILEBROWSER_POPUPSELECTALL;AtzÄ«mÄ“t visu +FILEBROWSER_POPUPTRASH;Izmest atkritnÄ“ +FILEBROWSER_POPUPUNRANK;NevÄ“rtÄ“t +FILEBROWSER_POPUPUNTRASH;Izņemt no atkritnes +FILEBROWSER_PROCESSINGSETTINGSHINT;UzstÄdÄ«t failu formÄtu un izvades direktoriju +FILEBROWSER_PROCESSINGSETTINGS;UzstÄdÄ«jumi +FILEBROWSER_RENAMEDLGLABEL;PÄrsaukt failu +FILEBROWSER_RENAMEDLGMSG;PÄrsaukt failu "%1" uz: +FILEBROWSER_SHOWDIRHINT;RÄdÄ«t visus direktorija attÄ“lus +FILEBROWSER_SHOWQUEUEHINT;RÄdÄ«t apstrÄdes rindu +FILEBROWSER_SHOWRANK1HINT;RÄdÄ«t attÄ“lus ar 1 zvaigzni +FILEBROWSER_SHOWRANK2HINT;RÄdÄ«t attÄ“lus ar 2 zvaigznÄ“m +FILEBROWSER_SHOWRANK3HINT;RÄdÄ«t attÄ“lus ar 3 zvaigznÄ“m +FILEBROWSER_SHOWRANK4HINT;RÄdÄ«t attÄ“lus ar 4 zvaigznÄ“m +FILEBROWSER_SHOWRANK5HINT;RÄdÄ«t attÄ“lus ar 5 zvaigznÄ“m +FILEBROWSER_SHOWTRASHHINT;RÄdÄ«t atkritni +FILEBROWSER_SHOWUNRANKHINT;RÄdÄ«t nevÄ“rtÄ“tus attÄ“lus +FILEBROWSER_STARTPROCESSINGHINT;SÄkt attÄ“lu rindas apstrÄdi/saglabÄÅ¡anu +FILEBROWSER_STARTPROCESSING;SÄkt apstrÄdi +FILEBROWSER_STOPPROCESSING;ApturÄ“t apstrÄdi +FILEBROWSER_STOPPROCESSINGHINT;ApturÄ“t attÄ“lu apstrÄdi +FILEBROWSER_THUMBSIZE;SÄ«ktÄ“lu izmÄ“rs +FILEBROWSER_ZOOMINHINT;PalielinÄt sÄ«ktÄ“lus +FILEBROWSER_ZOOMOUTHINT;SamazinÄt sÄ«ktÄ“lus +GENERAL_ABOUT;Par +GENERAL_CANCEL;Atcelt +GENERAL_DISABLE;AtslÄ“gt +GENERAL_DISABLED;AtslÄ“gts +GENERAL_ENABLED;IeslÄ“gts +GENERAL_ENABLE;IeslÄ“gt +GENERAL_LANDSCAPE;Ainava +GENERAL_LOAD;IelÄdÄ“t +GENERAL_NA;n/a +GENERAL_NO;NÄ“ +GENERAL_OK;Labi +GENERAL_PORTRAIT;Portrets +GENERAL_SAVE;SaglabÄt +GENERAL_YES;JÄ +HISTOGRAM_LABEL;Histogramma +HISTOGRAM_TOOLTIP_B;RÄdÄ«t/SlÄ“pt ZilÄ histogrammu +HISTOGRAM_TOOLTIP_G;RÄdÄ«t/SlÄ“pt ZaÄ¼Ä histogrammu +HISTOGRAM_TOOLTIP_L;RÄdÄ«t/SlÄ“pt CIELAB SpÄ«duma histogrammu +HISTOGRAM_TOOLTIP_R;RÄdÄ«t/SlÄ“pt SarkanÄ histogrammu +HISTORY_CHANGED;MainÄ«ts +HISTORY_CUSTOMCURVE;PielÄgota lÄ«kne +HISTORY_DELSNAPSHOT;Noņemt grÄmtzÄ«mi +HISTORY_FROMCLIPBOARD;No starplikas +HISTORY_LABEL;VÄ“sture +HISTORY_MSG_10;Ä’nu spieÅ¡ana +HISTORY_MSG_11;Toņa lÄ«kne +HISTORY_MSG_12;Auto EkspozÄ«cija +HISTORY_MSG_13;EkspozÄ«cijas cirpÅ¡ana +HISTORY_MSG_14;SpÄ«duma GaiÅ¡ums +HISTORY_MSG_15;SpÄ«duma Kontrasts +HISTORY_MSG_16;SpÄ«duma Melnais +HISTORY_MSG_17;SpÄ«duma Izgaismojumu spieÅ¡ana +HISTORY_MSG_18;SpÄ«duma Ä’nu spieÅ¡ana +HISTORY_MSG_19;SpÄ«duma LÄ«kne +HISTORY_MSG_1;AttÄ“ls ielÄdÄ“ts +HISTORY_MSG_20;AsinÄÅ¡ana +HISTORY_MSG_21;AsinÄÅ¡anas radiuss +HISTORY_MSG_22;AsinÄÅ¡anas apjoms +HISTORY_MSG_23;AsinÄÅ¡anas slieksnis +HISTORY_MSG_24;AsinÄt tikai malas +HISTORY_MSG_25;AsinÄÅ¡anas malu meklēšanas radiuss +HISTORY_MSG_26;AsinÄÅ¡anas malu iecietÄ«ba +HISTORY_MSG_27;AsinÄÅ¡anas caurumu kontrole +HISTORY_MSG_28;Caurumu kontroles apjoms +HISTORY_MSG_29;AsinÄÅ¡anas metode +HISTORY_MSG_2;Profils ielÄdÄ“ts +HISTORY_MSG_30;AtritinÄÅ¡anas radiuss +HISTORY_MSG_31;AtritinÄÅ¡anas apjoms +HISTORY_MSG_32;AtritinÄÅ¡anas slÄpēšana +HISTORY_MSG_33;AtritinÄÅ¡anas soļi +HISTORY_MSG_34;IzvairÄ«ties no krÄsu cirpÅ¡anas +HISTORY_MSG_35;PiesÄtinÄjuma ierobežojums +HISTORY_MSG_36;PiesÄtinÄjuma robeža +HISTORY_MSG_37;KrÄsu pastiprinÄÅ¡ana +HISTORY_MSG_38;BaltÄ lÄ«dzsvara metode +HISTORY_MSG_39;KrÄsu temperatÅ«ra +HISTORY_MSG_3;Profils izmainÄ«ts +HISTORY_MSG_40;BaltÄ lÄ«dzsvara nokrÄsa +HISTORY_MSG_41;KrÄsu nobÄ«de "A" +HISTORY_MSG_42;KrÄsu nobÄ«de "B" +HISTORY_MSG_43;SpÄ«duma trokšņu slÄpēšana +HISTORY_MSG_44;Spož. trokšņu slÄpēšanas radiuss +HISTORY_MSG_45;Spož. trokšņu slÄpēšanas malu iecietÄ«ba +HISTORY_MSG_46;KrÄsu trokšņu slÄpēšana +HISTORY_MSG_47;KrÄsu trokšņu slÄpēšanas radiuss +HISTORY_MSG_48;KrÄsu trokšņu slÄpēšanas malu iecietÄ«ba +HISTORY_MSG_49;KrÄsu trokšņu slÄpēšanas malu jutÄ«gums +HISTORY_MSG_4;VÄ“stures pÄrlÅ«koÅ¡ana +HISTORY_MSG_50;Ä’nu/Izgaismojumu rÄ«ks +HISTORY_MSG_51;Izgaismojumu pastiprinÄÅ¡ana +HISTORY_MSG_52;Ä’nu pastiprinÄÅ¡ana +HISTORY_MSG_53;Izgaismojumu toņa platums +HISTORY_MSG_54;Ä’nu toņa platums +HISTORY_MSG_55;VietÄ“jais kontrasts +HISTORY_MSG_56;Ä’nu/Izgaismojumu radiuss +HISTORY_MSG_57;Raupja pagrieÅ¡ana +HISTORY_MSG_58;HorizontÄla apmeÅ¡ana +HISTORY_MSG_59;VertikÄla apmeÅ¡ana +HISTORY_MSG_5;GaiÅ¡ums +HISTORY_MSG_60;PagrieÅ¡ana +HISTORY_MSG_61;PagrieÅ¡ana +HISTORY_MSG_62;LÄ“cu kropļojumu laboÅ¡ana +HISTORY_MSG_63;GrÄmatzÄ«me izvÄ“lÄ“ta +HISTORY_MSG_64;KadrÄ“jums +HISTORY_MSG_65;KrÄsu nobÄ«des laboÅ¡ana +HISTORY_MSG_66;Izgaismojumu atgūšana +HISTORY_MSG_67;Izgaismojumu atgūšanas apjoms +HISTORY_MSG_68;Izgaismojumu atgūšanas metode +HISTORY_MSG_69;KrÄsu telpa darbam +HISTORY_MSG_6;Kontrasts +HISTORY_MSG_70;KrÄsu telpa izvadei +HISTORY_MSG_71;Ievades krÄsu telpa +HISTORY_MSG_72;Vinjetes laboÅ¡ana +HISTORY_MSG_73;KanÄlu jaucÄ“js +HISTORY_MSG_74;IzmÄ“ra mÄ“rogs +HISTORY_MSG_75;IzmÄ“rmaiņas metode +HISTORY_MSG_76;Exif metadati +HISTORY_MSG_77;IPTC metadati +HISTORY_MSG_78;NorÄdÄ«ti izmÄ“rmaiņas dati +HISTORY_MSG_79;IzmÄ“rmaiņas platums +HISTORY_MSG_7;Melnais +HISTORY_MSG_80;IzmÄ“rmaiņas augstums +HISTORY_MSG_81;IzmÄ“rmaiņa ieslÄ“gta +HISTORY_MSG_8;EkspozÄ«cijas laboÅ¡ana +HISTORY_MSG_9;Izgaismojumu spieÅ¡ana +HISTORY_NEWSNAPSHOTAS;KÄ... +HISTORY_NEWSNAPSHOT;Jauna grÄmtzÄ«me +HISTORY_NEWSSDIALOGLABEL;GrÄmtzÄ«mes nosaukums: +HISTORY_NEWSSDIALOGTITLE;Pielikt grÄmtzÄ«mi +HISTORY_SETTO;IestatÄ«ts uz +HISTORY_SNAPSHOT;GrÄmtzÄ«me +HISTORY_SNAPSHOTS;GrÄmtzÄ«mes +ICMPANEL_FILEDLGFILTERANY;Visi faili +ICMPANEL_FILEDLGFILTERICM;ICC Profilu faili +ICMPANEL_GAMMABEFOREINPUT;Uzlikta Gammu pirms Ievades profila +ICMPANEL_INPUTCAMERA;Kameras noklusÄ“tais +ICMPANEL_INPUTCUSTOM;PielÄgots +ICMPANEL_INPUTDLGLABEL;IzvÄ“lies Ievades ICC Profilu... +ICMPANEL_INPUTEMBEDDED;Lietot iegulto, ja var +ICMPANEL_INPUTPROFILE;Ievades profils +ICMPANEL_NOICM;Bez ICM: sRGB izvade +ICMPANEL_OUTPUTDLGLABEL;IzvÄ“lies Izvades ICC Profilu... +ICMPANEL_OUTPUTPROFILE;Izvades profils +ICMPANEL_SAVEREFERENCE;SaglabÄt atsauces attÄ“lu profila izveidei +ICMPANEL_WORKINGPROFILE;Darba profils +IMAGEAREA_DETAILVIEW;Tuvskats +IPTCPANEL_AUTHOR;Autors +IPTCPANEL_AUTHORHINT;Objekta radÄ«tÄjs vÄrds, t.i. rakstnieks, fotogrÄfs vai mÄkslinieks (By-line). +IPTCPANEL_AUTHORSPOSITION;Autora amats +IPTCPANEL_AUTHORSPOSITIONHINT;Objekta radÄ«tÄja amapts (By-line Title). +IPTCPANEL_CAPTIONHINT;Datu tekstveida apraksts (Caption - Abstract) +IPTCPANEL_CAPTION;Virsraksts +IPTCPANEL_CAPTIONWRITERHINT;Personas vÄrfds, kura ir iesaistÄ«ta attÄ“la, virsraksta vai kopsavilkuma rakstīšanÄ, rediģēšanÄ vai laboÅ¡ÄnÄ (Writer - Editor) +IPTCPANEL_CAPTIONWRITER;Virsraksta autors +IPTCPANEL_CATEGORYHINT;AttÄ“la radÄ«tÄjs identificÄ“ attÄ“la subjektu (Category). +IPTCPANEL_CATEGORY;Kategorija +IPTCPANEL_CITYHINT;AttÄ“la izcelsmes pilsÄ“ta (City). +IPTCPANEL_CITY;PilsÄ“ta +IPTCPANEL_COPYHINT;KopÄ“t IPTC iestatÄ«jumus uz starpliku +IPTCPANEL_COPYRIGHT;AutortiesÄ«bas +IPTCPANEL_COPYRIGHTHINT;JebkÄds nepiecieÅ¡amais brÄ«dinÄjums par autortiesÄ«bÄm (Copyright Notice). +IPTCPANEL_COUNTRYHINT;AttÄ“la sÄkotnÄ“jÄs izveidoÅ¡anas valsts (Country - Primary Location Name). +IPTCPANEL_COUNTRY;Valsts +IPTCPANEL_CREDITHINT;IdentificÄ“ attÄ“la sniedzÄ“ju, nav obligÄti radÄ«tÄjs vai Ä«paÅ¡nieks (Credit). +IPTCPANEL_CREDIT;PateicÄ«ba +IPTCPANEL_DATECREATEDHINT;AttÄ“la intelektuÄlÄ satura radīšanas datums; FormÄts: ggggmmdd (Date Created). +IPTCPANEL_DATECREATED;IzveidoÅ¡anas datums +IPTCPANEL_EMBEDDEDHINT;AttiestatÄ«t uz attÄ“la iegultajiem IPTC datiem +IPTCPANEL_EMBEDDED;Iegultais +IPTCPANEL_HEADLINEHINT;PublicÄ“jams raksts, kas satur attÄ“la konspektu (Headline). +IPTCPANEL_HEADLINE;Konspekts +IPTCPANEL_INSTRUCTIONSHINT;Citi redaktora norÄdÄ«jumi par attÄ“la lietoÅ¡anu (Special Instructions). +IPTCPANEL_INSTRUCTIONS;NorÄdÄ«jumi +IPTCPANEL_KEYWORDS;AtslÄ“gvÄrdi +IPTCPANEL_KEYWORDSHINT;NorÄda vÄrdus specifiskas informÄcijas iegūšanai (Keywords). +IPTCPANEL_PASTEHINT;IelÄ«mÄ“t IPTC iestatÄ«jumus no starplikas +IPTCPANEL_PROVINCEHINT;AttÄ“la izcelsmes valsts vai province (Province-State). +IPTCPANEL_PROVINCE;Province +IPTCPANEL_RESET;Atiestate +IPTCPANEL_RESETHINT;AtiestatÄ«t uz profila noklusÄ“jumu +IPTCPANEL_SOURCE;Avots +IPTCPANEL_SOURCEHINT;AttÄ“la intelektuÄlÄ Ä«paÅ¡uma Ä«paÅ¡nieks (Source). +IPTCPANEL_SUPPCATEGORIES;ApakÅ¡kategorija +IPTCPANEL_SUPPCATEGORIESHINT;PrecizÄ“ attÄ“la subjektu (Supplemental Categories). +IPTCPANEL_TITLEHINT;AttÄ“la saÄ«sinÄts nosaukums (Object Name). +IPTCPANEL_TITLE;Nosaukums +IPTCPANEL_TRANSREFERENCEHINT;Kods, kas norÄda uz attÄ“la sÄkotnÄ“jas pÄrneses vietu (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;PÄrneses atsauce +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;IestatÄ«jumi +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;KÄ... +MAIN_BUTTON_SAVE;SaglabÄt attÄ“lu +MAIN_BUTTON_SENDTOEDITOR;SÅ«tÄ«t uz redaktoru +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Fails jau ir. +MAIN_MSG_CANNOTLOAD;Nevaru ielÄdÄ“t attÄ“lu +MAIN_MSG_CANNOTSAVE;Faila saglabÄÅ¡anas kļūda +MAIN_MSG_CANNOTSTARTEDITOR;Nevar uzsÄkt redaktoru. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;LÅ«dzu ievadiet pareizu ceļu dialogÄ "UzstÄdÄ«jumi". +MAIN_MSG_EXITJOBSINQUEUEINFO;Beidzot neapstrÄdÄtie attÄ“li no rindas pazudÄ«s. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Vai tieÅ¡Äm beigt? ApstrÄdes rindÄ ir neapstrÄdÄti attÄ“li. +MAIN_MSG_JOBSINQUEUE;darbs(i) rindÄ +MAIN_MSG_QOVERWRITE;Vai pÄrrakstÄ«t to? +MAIN_TAB_BASIC;Pamats +MAIN_TAB_COLOR;KrÄsa +MAIN_TAB_DETAIL;Detaļas +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;EkspozÄ«cija +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadati +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;PÄrveidot +MAIN_TOOLTIP_HIDEFP;RÄdÄ«t/slÄ“pt apakšējo ielaidumu (mapju un failu pÄrlÅ«ks, saÄ«sne: F)) +MAIN_TOOLTIP_HIDEHP;RÄdÄ«t/slÄ“pt kreiso ielaidumu (ieskaitot vÄ“sturi, saÄ«sne: H) +MAIN_TOOLTIP_INDCLIPPEDH;Izgaismojumu cirpÅ¡anas pazÄ«me +MAIN_TOOLTIP_INDCLIPPEDS;Ä’nu cirpÅ¡anas pazÄ«me +MAIN_TOOLTIP_PREFERENCES;MainÄ«t iestatÄ«jumus +MAIN_TOOLTIP_QINFO;Ä€trÄ info uz attÄ“la +MAIN_TOOLTIP_SAVEAS;SaglabÄt attÄ“lu izvÄ“lÄ“tajÄ mapÄ“ +MAIN_TOOLTIP_SAVE;SaglabÄt attÄ“lu noklusÄ“tajÄ mapÄ“ +PARTIALPASTE_BASICGROUP;Pamata uzstÄdÄ«jumi +PARTIALPASTE_CACORRECTION;KrÄsu novirzes laboÅ¡ana +PARTIALPASTE_COARSETRANS;90 grÄdu rotēšana / apmeÅ¡ana +PARTIALPASTE_COLORBOOST;KrÄsu pastiprinÄÅ¡ana +PARTIALPASTE_COLORDENOISE;KrÄsu attÄ«rīšana +PARTIALPASTE_COLORGROUP;KrÄsu uzstÄdÄ«jumi +PARTIALPASTE_COLORMIXER;KrÄsu jaucÄ“js +PARTIALPASTE_COLORSHIFT;KrÄsu nobÄ«de +PARTIALPASTE_COMPOSITIONGROUP;KompozÄ«cijas uzstÄdÄ«jumi +PARTIALPASTE_CROP;Apcirpt +PARTIALPASTE_DIALOGLABEL;Daļēji ielÄ«mÄ“t apstrÄdes profilu +PARTIALPASTE_DISTORTION;Kropļojumu laboÅ¡ana +PARTIALPASTE_EXIFCHANGES;exif datu izmaiņas +PARTIALPASTE_EXPOSURE;EkspozÄ«cija +PARTIALPASTE_HLRECOVERY;Izgaismojumu atgūšana +PARTIALPASTE_ICMSETTINGS;ICM uzstÄdÄ«jumi +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;LÄ“cas uzstÄdÄ«jumi +PARTIALPASTE_LUMACURVE;SpÄ«duma lÄ«kne +PARTIALPASTE_LUMADENOISE;SpÄ«duma trokšņu slÄpēšana +PARTIALPASTE_LUMINANCEGROUP;SpÄ«duma uzstÄdÄ«jumi +PARTIALPASTE_METAICMGROUP;Metadati/ICM uzstÄdÄ«jumi +PARTIALPASTE_RESIZE;IzmÄ“rmaiņa +PARTIALPASTE_ROTATION;RotÄcija +PARTIALPASTE_SHADOWSHIGHLIGHTS;Ä’nas/izgaismojumi +PARTIALPASTE_SHARPENING;AsinÄÅ¡ana +PARTIALPASTE_VIGNETTING;Vinjetes laboÅ¡ana +PARTIALPASTE_WHITEBALANCE;BaltÄ lÄ«dzsvarss +PREFERENCES_APPLNEXTSTARTUP;lietos nÄkamÄ reizÄ“ +PREFERENCES_BLINKCLIPPED;Mirgot cirptos laukumus +PREFERENCES_CACHECLEARALL;AttÄ«rÄ«t visu +PREFERENCES_CACHECLEARPROFILES;AttÄ«rÄ«t Profilus +PREFERENCES_CACHECLEARTHUMBS;AttÄ«rÄ«t sÄ«ktÄ“lus +PREFERENCES_CACHEFORMAT1;Savs (ÄtrÄks un kvalitatÄ«vÄks) +PREFERENCES_CACHEFORMAT2;JPEG (mazÄka diska vieta) +PREFERENCES_CACHEMAXENTRIES;MaksimÄlais keÅ¡a ierakstu skaits +PREFERENCES_CACHEOPTS;KeÅ¡a opcijas +PREFERENCES_CACHESTRAT1;PriekÅ¡roka Ätrumam pret mazu atmiņas patÄ“riņu +PREFERENCES_CACHESTRAT2;PriekÅ¡roka mazam atmiņas patÄ“riņam pret Ätrumu +PREFERENCES_CACHESTRAT;KeÅ¡a stratēģija +PREFERENCES_CACHETHUMBFORM;KeÅ¡a sÄ«ktÄ“lu formÄts +PREFERENCES_CACHETHUMBHEIGHT;KeÅ¡a maksimÄlais sÄ«ktÄ“la augstums +PREFERENCES_CLEARDLG_LINE1;AttÄ«rÄ«t keÅ¡u +PREFERENCES_CLEARDLG_LINE2;Tas var aizņemt dažas sekundes. +PREFERENCES_CLEARDLG_TITLE;LÅ«dzu uzgaidiet +PREFERENCES_CLIPPINGIND;CirpÅ¡anas pazÄ«me +PREFERENCES_CMETRICINTENT;Kolorimetrijas nolÅ«ks +PREFERENCES_DATEFORMAT;Datuma formÄts +PREFERENCES_DATEFORMATHINT;JÅ«s varat lietot Å¡Äduas formatēšanas parametrus:\n%y : gads\n%m : mÄ“nesis\n%d : diena\n\nPiemÄ“ram, ungÄru datuma formÄts ir:\n%y/%m/%d +PREFERENCES_DEFAULTLANG;NoklusÄ“tÄ valoda +PREFERENCES_DEFAULTTHEME;NoklusÄ“tÄ tÄ“ma +PREFERENCES_DEMOSAICINGALGO;MozaÄ«kas interpolÄcijas algoritms +PREFERENCES_DIRHOME;MÄjas mape +PREFERENCES_DIRLAST;PÄ“dÄ“jÄ lietotÄ mape +PREFERENCES_DIROTHER;Cita +PREFERENCES_DIRSELECTDLG;IzvÄ“lies attÄ“lu mapi sÄkumam... +PREFERENCES_DIRSOFTWARE;UzstÄdīšanas mape +PREFERENCES_DMETHOD;Metode +PREFERENCES_EDITORCMDLINE;Cita komandrinda +PREFERENCES_EXTERNALEDITOR;Ä€rÄ“jais redaktors +PREFERENCES_FALSECOLOR;NeÄ«sto krÄsu slÄpēšanas soļi +PREFERENCES_FBROWSEROPTS;Failu pÄrlÅ«ka iespÄ“jas +PREFERENCES_FILEFORMAT;Faila formÄts +PREFERENCES_FORIMAGE;AttÄ“lu failiem +PREFERENCES_FORRAW;RAW failiem +PREFERENCES_GIMPPATH;GIMP instalÄcijas direktorijs +PREFERENCES_GTKTHEME;GTK noklusÄ“tÄ +PREFERENCES_HINT;MÄjiens +PREFERENCES_HLTHRESHOLD;Cirpto izgaismojumu slieksnis +PREFERENCES_ICCDIR;ICC profilu mape +PREFERENCES_IMPROCPARAMS;NoklusÄ“tie attÄ“la apstrÄdes parametri +PREFERENCES_INTENT_ABSOLUTE;AbsolÅ«tÄ kolorimetrija +PREFERENCES_INTENT_PERCEPTUAL;Uztverams +PREFERENCES_INTENT_RELATIVE;RelatÄ«vÄ kolorimetrija +PREFERENCES_INTENT_SATURATION;PiesÄtinÄjums +PREFERENCES_LIVETHUMBNAILS;DzÄ«vie sÄ«ktÄ“li (lÄ“nÄk) +PREFERENCES_MONITORICC;Monitora Profils +PREFERENCES_OUTDIRFOLDERHINT;Likt saglabÄtos attÄ“lus norÄdÄ«tajÄ mapÄ“ +PREFERENCES_OUTDIRFOLDER;SaglabÄt mapÄ“ +PREFERENCES_OUTDIRHINT;JÅ«s varat lietot Å¡Äduas formatēšanas parametrus:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nÅ ie formatēšanas parametri attiecas uz raw faila direktoriju un apakÅ¡ceļiem.\n\nPiemÄ“ram, ja /home/tom/image/02-09-2006/dsc0012.nef ir atvÄ“rts, formatēšanas parametri nozÄ«mÄ“:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nJa JÅ«s vÄ“laties saglabÄt rezultÄtu tur pat kur ir oriÄ£inÄls, rakstiet:\n%p1/%f\n\nJa JÅ«s vÄ“laties saglabÄt rezultÄtu direktorijÄ 'converted', kas novietota oriÄ£inÄla direktorijÄ, rakstiet:\n%p1/converted/%f\n\nJa JÅ«s vÄ“laties saglabÄt rezultÄtu '/home/tom/converted' paturot tÄdu paÅ¡u apakÅ¡direktoriju datumu struktÅ«ru, rakstiet:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIR;Izvades mape +PREFERENCES_OUTDIRTEMPLATEHINT;JÅ«s varat lietot Å¡Ädas formatēšanas virknes:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nÅ Ä«s formatēšanas virknes attiecas uz direktorijiem un RAW faila apakÅ¡ceļiem.\n\nPiemÄ“ram, ja ir atvÄ“rts /home/tom/image/02-09-2006/dsc0012.nef, formatÄ“juma virkņu nozÄ«me ir:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nJa vÄ“laties rezultÄtu saglabÄt turpat pie oriÄ£inÄla, rakstiet:\n%p1/%f\n\nJa vÄ“laties rezultÄtu saglabÄt direktorijÄ 'converted' pie oriÄ£inÄla, rakstiet:\n%p1/converted/%f\n\nJa vÄ“laties rezultÄtu saglabÄt direktorijÄ '/home/tom/converted' paturot to paÅ¡u datumu apakÅ¡direktoriju, rakstiet:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Lietot veidni +PREFERENCES_PARSEDEXTADDHINT;Ierakstiet paplaÅ¡inÄjumu un nospiediet Å¡o pogu lai pievienotu sarakstam +PREFERENCES_PARSEDEXTADD;Pielikt paplaÅ¡inÄjumu +PREFERENCES_PARSEDEXTDELHINT;DzÄ“st atzÄ«mÄ“to paplaÅ¡inÄjumu no saraksta +PREFERENCES_PARSEDEXT;ParsÄ“tie paplašīnÄjumi +PREFERENCES_PROFILEHANDLING;ApstrÄdes profilu politika +PREFERENCES_PROFILELOADPR;Profilu ielÄdes prioritÄte +PREFERENCES_PROFILEPRCACHE;Profils keÅ¡Ä +PREFERENCES_PROFILEPRFILE;Profils pie ievades faila +PREFERENCES_PROFILESAVECACHE;SaglabÄt apstrÄdes profilu keÅ¡Ä +PREFERENCES_PROFILESAVEINPUT;SaglabÄt apstrÄdes profilu pie ievades faila +PREFERENCES_PSPATH;Adobe Photoshop instalÄcijas direktorijs +PREFERENCES_SELECTICCDIRDLG;IzvÄ“lies ICC Profilu mapi... +PREFERENCES_SELECTLANG;IzvÄ“lies valodu +PREFERENCES_SELECTMONITORPROFDLG;IzvÄ“lies displeja ICC profilu... +PREFERENCES_SELECTTHEME;IzvÄ“lieties tÄ“mu +PREFERENCES_SHOWBASICEXIF;RÄdÄ«t Exif pamatdatus +PREFERENCES_SHOWDATETIME;RÄdÄ«t datumu un laiku +PREFERENCES_SHOWONLYRAW;RÄdÄ«t tikai RAW failus +PREFERENCES_SHTHRESHOLD;Cirpto Ä“nu slieksnis +PREFERENCES_STARTUPIMDIR;AttÄ“lu mape sÄkumÄ +PREFERENCES_TAB_BROWSER;Failu pÄrlÅ«ks +PREFERENCES_TAB_COLORMGR;KrÄsu pÄrvaldÄ«ba +PREFERENCES_TAB_GENERAL;VispÄrÄ«gi +PREFERENCES_TAB_IMPROC;AttÄ“lu apstrÄde +PREFERENCES_TAB_OUTPUT;Izvades iespÄ“jas +PREFERENCES_THUMBSIZE;SÄ«ktÄ“la izmÄ“rs +PROFILEPANEL_FILEDLGFILTERANY;Visus failus +PROFILEPANEL_FILEDLGFILTERPP;ApstrÄdes profili +PROFILEPANEL_LABEL;ApstrÄdes profili +PROFILEPANEL_LOADDLGLABEL;IelÄdÄ“t apstrÄdes profilu... +PROFILEPANEL_PCUSTOM;PielÄgots +PROFILEPANEL_PFILE;No faila +PROFILEPANEL_PLASTPHOTO;Iepriekšējais attÄ“ls +PROFILEPANEL_PLASTSAVED;PÄ“dÄ“jais saglabÄtais +PROFILEPANEL_PROFILE;Profils +PROFILEPANEL_SAVEDLGLABEL;SaglabÄt apstrÄdes profilu... +PROFILEPANEL_TOOLTIPCOPY;KopÄ“t esoÅ¡o profilu uz starpliku +PROFILEPANEL_TOOLTIPLOAD;IelÄdÄ“t profilu no faila +PROFILEPANEL_TOOLTIPPASTE;IelÄ«mÄ“t profilu no starplikas +PROFILEPANEL_TOOLTIPSAVE;SaglabÄt šībrīža profilu +PROGRESSBAR_DECODING;DekodÄ“ju raw failu... +PROGRESSBAR_DEMOSAICING;MozaÄ«kas interpolÄcija... +PROGRESSBAR_LOADING;AttÄ“la ielÄde... +PROGRESSBAR_LOADJPEG;IelÄdÄ“ju JPEG failu... +PROGRESSBAR_LOADPNG;IelÄdÄ“ju PNG failu... +PROGRESSBAR_LOADTIFF;IelÄdÄ“ju TIFF failu... +PROGRESSBAR_PROCESSING;AttÄ“la apstrÄde... +PROGRESSBAR_READY;Gatavs. +PROGRESSBAR_SAVEJPEG;SaglabÄju JPEG failu... +PROGRESSBAR_SAVEPNG;SaglabÄju PNG failu... +PROGRESSBAR_SAVETIFF;SaglabÄju TIFF failu... +PROGRESSDLG_LOADING;IelÄdÄ“ju failu... +PROGRESSDLG_PROCESSING;ApstrÄdÄju attÄ“lu... +PROGRESSDLG_SAVING;SaglabÄju failu... +QINFO_FOCALLENGTH;Fokusa garums +QINFO_ISO;ISO +QINFO_LENS;LÄ“ca +QINFO_NOEXIF;Exif dati nav pieejami. +SAVEDLG_FILEFORMAT;Faila formÄts +SAVEDLG_JPEGQUAL;JPEG KvalitÄte +SAVEDLG_JPGFILTER;JPEG faili +SAVEDLG_PNGCOMPR;PNG SpieÅ¡ana +SAVEDLG_PNGFILTER;PNG faili +SAVEDLG_PUTTOQUEUEHEAD;Likt apstrÄdes rindas sÄkumÄ +SAVEDLG_PUTTOQUEUE;Likt apstrÄdes rindÄ +SAVEDLG_PUTTOQUEUETAIL;Likt apstrÄdes rindas beigÄs +SAVEDLG_SAVEIMMEDIATELY;SaglabÄt tÅ«lÄ«t +SAVEDLG_SAVESPP;SaglabÄt apstrÄdes profilu ar attÄ“lu +SAVEDLG_TIFFFILTER;TIFF faili +TOOLBAR_TOOLTIP_CROP;Kadrēšanas rÄ«ks (saÄ«sne: C) +TOOLBAR_TOOLTIP_HAND;Plaukstas rÄ«ks (saÄ«sne: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;LÄ«meņoÅ¡anas rÄ«ks (saÄ«sne: S) +TOOLBAR_TOOLTIP_WB;Punkta baltÄ lÄ«dzsvara rÄ«ks (saÄ«sne: W) +TP_CACORRECTION_BLUE;Zils +TP_CACORRECTION_LABEL;LÄ“cas krÄsu nobÄ«des +TP_CACORRECTION_RED;Sarkans +TP_CHMIXER_BLUE;Zils +TP_CHMIXER_GREEN;Zaļš +TP_CHMIXER_LABEL;KanÄlu jaucÄ“js +TP_CHMIXER_RED;Sarkans +TP_COARSETRAF_DEGREE;grÄdi: +TP_COARSETRAF_TOOLTIP_HFLIP;Apmest horizontÄli +TP_COARSETRAF_TOOLTIP_ROTLEFT;Pagriezt pa kreisi +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Pagriezt pa labi +TP_COARSETRAF_TOOLTIP_VFLIP;Apmest vertikÄli +TP_COLORBOOST_ACHANNEL;kanÄls "a" +TP_COLORBOOST_AMOUNT;Apjoms +TP_COLORBOOST_AVOIDCOLORCLIP;IzvairÄ«ties no krÄsu cirpÅ¡anas +TP_COLORBOOST_BCHANNEL;kanÄls "b" +TP_COLORBOOST_CHAB;a un b +TP_COLORBOOST_CHANNEL;KanÄls +TP_COLORBOOST_CHSEPARATE;atsevišķi +TP_COLORBOOST_ENABLESATLIMITER;Ierobežot piesÄtinÄjumu +TP_COLORBOOST_LABEL;KrÄsu pastiprinÄÅ¡ana +TP_COLORBOOST_SATLIMIT;PiesÄtinÄjuma robeža +TP_COLORDENOISE_EDGESENSITIVE;JutÄ«gs uz malÄm +TP_COLORDENOISE_EDGETOLERANCE;IecietÄ«ba pret malÄm +TP_COLORDENOISE_LABEL;KrÄsu trokšņu slÄpēšana +TP_COLORDENOISE_RADIUS;Radius +TP_COLORSHIFT_BLUEYELLOW;Zils-Dzeltens +TP_COLORSHIFT_GREENMAGENTA;Zaļš-FuksÄ«ns +TP_COLORSHIFT_LABEL;KrÄsu nobÄ«de +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;AttiecÄ«ba: +TP_CROP_GTDIAGONALS;DiagonÄles +TP_CROP_GTHARMMEANS1;Harmon. vidÄ“jais 1 +TP_CROP_GTHARMMEANS2;Harmon. vidÄ“jais 2 +TP_CROP_GTHARMMEANS3;Harmon. vidÄ“jais 3 +TP_CROP_GTHARMMEANS4;Harmon. vidÄ“jais 4 +TP_CROP_GTNONE;NekÄdas +TP_CROP_GTRULETHIRDS;TreÅ¡daļas +TP_CROP_GUIDETYPE;VadlÄ«nijas: +TP_CROP_H;A +TP_CROP_LABEL;KadrÄ“jums +TP_CROP_SELECTCROP; NorÄdÄ«t kadrÄ“jumu +TP_CROP_W;P +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Apjoms +TP_DISTORTION_LABEL;LÄ“cas kropļojums +TP_EXPOSURE_AUTOLEVELS;Auto LÄ«meņi +TP_EXPOSURE_BLACKLEVEL;Melnais +TP_EXPOSURE_BRIGHTNESS;GaiÅ¡ums +TP_EXPOSURE_CLIP;Cirpt +TP_EXPOSURE_COMPRHIGHLIGHTS;Izgaismojumu spieÅ¡ana +TP_EXPOSURE_COMPRSHADOWS;Ä’nu spieÅ¡ana +TP_EXPOSURE_CONTRAST;Kontrasts +TP_EXPOSURE_CURVEEDITOR;Toņa lÄ«kne +TP_EXPOSURE_EXPCOMP;Eksp. nobÄ«de +TP_EXPOSURE_LABEL;EkspozÄ«cija +TP_HLREC_CIELAB;CIELab maisÄ«jums +TP_HLREC_COLOR;KrÄsu pavairoÅ¡ana +TP_HLREC_LABEL;Izgaismojumu atgūšana +TP_HLREC_LUMINANCE;SpÄ«duma atgūšana +TP_HLREC_METHOD;Metode: +TP_ICM_FILEDLGFILTERANY;Visi faili +TP_ICM_FILEDLGFILTERICM;ICC Profilu faili +TP_ICM_GAMMABEFOREINPUT;Uzlikta Gammu pirms Ievades profila +TP_ICM_INPUTCAMERA;Kameras noklusÄ“tais +TP_ICM_INPUTCUSTOM;PielÄgots +TP_ICM_INPUTDLGLABEL;IzvÄ“lies Ievades ICC Profilu... +TP_ICM_INPUTEMBEDDED;Lietot iegulto, ja var +TP_ICM_INPUTPROFILE;Ievades profils +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Bez ICM: sRGB izvade +TP_ICM_OUTPUTDLGLABEL;IzvÄ“lies Izvades ICC Profilu... +TP_ICM_OUTPUTPROFILE;Izvades profils +TP_ICM_SAVEREFERENCE;SaglabÄt atsauces attÄ“lu profila izveidei +TP_ICM_WORKINGPROFILE;Darba profils +TP_LUMACURVE_BLACKLEVEL;Melnais +TP_LUMACURVE_BRIGHTNESS;GaiÅ¡ums +TP_LUMACURVE_COMPRHIGHLIGHTS;Izgaismojumu spieÅ¡ana +TP_LUMACURVE_COMPRSHADOWS;Ä’nu spieÅ¡ana +TP_LUMACURVE_CONTRAST;Kontrasts +TP_LUMACURVE_CURVEEDITOR;SpÄ«duma lÄ«kne +TP_LUMACURVE_LABEL;SpÄ«duma lÄ«kne +TP_LUMADENOISE_EDGETOLERANCE;IecietÄ«ba pret malÄm +TP_LUMADENOISE_LABEL;SpÄ«duma trokšņu slÄpēšana +TP_LUMADENOISE_RADIUS;Radiuss +TP_RESIZE_BICUBIC;Bikubiski +TP_RESIZE_BICUBICSF;Bikubiski (MÄ«kstÄk) +TP_RESIZE_BICUBICSH;Bikubiski (AsÄk) +TP_RESIZE_BILINEAR;BilineÄri +TP_RESIZE_FULLSIZE;Pilns attÄ“la izmÄ“rs: +TP_RESIZE_H;A: +TP_RESIZE_LABEL;IzmÄ“rmaiņa +TP_RESIZE_METHOD;Metode: +TP_RESIZE_NEAREST;TuvÄkais +TP_RESIZE_SCALE;MÄ“rogs +TP_RESIZE_W;P: +TP_ROTATE_AUTOCROP;Auto Kardēšana +TP_ROTATE_DEGREE;GrÄdi +TP_ROTATE_FILL;AizpildÄ«t +TP_ROTATE_LABEL;Pagriezt +TP_ROTATE_SELECTLINE; NorÄdÄ«t lÄ«meni +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Izgaismojumi +TP_SHADOWSHLIGHTS_HLTONALW;Toņa platums +TP_SHADOWSHLIGHTS_LABEL;Ä’nas/Izgaismojumi +TP_SHADOWSHLIGHTS_LOCALCONTR;VietÄ“jais kontrasts +TP_SHADOWSHLIGHTS_RADIUS;Radiuss +TP_SHADOWSHLIGHTS_SHADOWS;Ä’nas +TP_SHADOWSHLIGHTS_SHTONALW;Toņa platums +TP_SHARPENING_AMOUNT;Apjoms +TP_SHARPENING_EDRADIUS;Radiuss +TP_SHARPENING_EDTOLERANCE;IecietÄ«ba pret malÄm +TP_SHARPENING_HALOCONTROL;Caurumu kontole +TP_SHARPENING_HCAMOUNT;Apjoms +TP_SHARPENING_LABEL;AsinÄÅ¡ana +TP_SHARPENING_METHOD;Metode +TP_SHARPENING_ONLYEDGES;AsinÄt tikai malas +TP_SHARPENING_RADIUS;Radiuss +TP_SHARPENING_RLD_AMOUNT;Apjoms +TP_SHARPENING_RLD_DAMPING;SlÄpēšana +TP_SHARPENING_RLD_ITERATIONS;Soļi +TP_SHARPENING_RLD;RL atritinÄÅ¡ana +TP_SHARPENING_THRESHOLD;Slieksnis +TP_SHARPENING_USM;NeasÄ maska +TP_VIGNETTING_AMOUNT;Apjoms +TP_VIGNETTING_LABEL;Vinjetes LaboÅ¡ana +TP_VIGNETTING_RADIUS;Radiuss +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Kamera +TP_WBALANCE_CUSTOM;PielÄgots +TP_WBALANCE_GREEN;NokrÄsa +TP_WBALANCE_LABEL;BaltÄ lÄ«dzsvars +TP_WBALANCE_METHOD;Metode +TP_WBALANCE_SIZE;izmÄ“rs: +TP_WBALANCE_SPOTWB;Punkta BL +TP_WBALANCE_TEMPERATURE;TemperatÅ«ra +ZOOMBAR_DETAIL;Tuvskats +ZOOMBAR_HUGE;MilzÄ«gs +ZOOMBAR_LARGE;Liels +ZOOMBAR_NORMAL;NormÄls +ZOOMBAR_PREVIEW;Pirmsskats +ZOOMBAR_SCALE;MÄ“rogs +ZOOMBAR_SMALL;Mazs + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Magyar b/rtdata/languages/Magyar new file mode 100644 index 000000000..d26d6b964 --- /dev/null +++ b/rtdata/languages/Magyar @@ -0,0 +1,703 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# +# +# +ADJUSTER_RESET_TO_DEFAULT;Alaphelyzetbe állítás +CURVEEDITOR_FILEDLGFILTERANY;Minden fájl +CURVEEDITOR_FILEDLGFILTERCURVE;Görbe fájlok +CURVEEDITOR_LINEAR;Lineáris +CURVEEDITOR_LOADDLGLABEL;Görbe betöltése... +CURVEEDITOR_SAVEDLGLABEL;Görbe mentése... +CURVEEDITOR_TOOLTIPLINEAR;Lineáris görbe visszaállítása +CURVEEDITOR_TOOLTIPLOAD;Görbe betöltése +CURVEEDITOR_TOOLTIPSAVE;Görbe mentése +EXIFFILTER_APERTURE;Blende +EXIFFILTER_CAMERA;FényképezÅ‘gép +EXIFFILTER_DIALOGLABEL;Exif SzűrÅ‘ +EXIFFILTER_FOCALLEN;Fókusztávolság +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objektív +EXIFFILTER_SHUTTER;ZáridÅ‘ +EXIFPANEL_ADDEDITHINT;Új tagok hozzáadása, szerkesztése +EXIFPANEL_ADDEDIT;Hozzáad/Szerkeszt +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Érték megadása +EXIFPANEL_ADDTAGDLG_SELECTTAG;Tag kijelölése +EXIFPANEL_ADDTAGDLG_TITLE;Új tagok hozzáadása / Tagok szerkesztése +EXIFPANEL_KEEPHINT;A kijelölt adatok megtartása a végsÅ‘ fájl mentésekor +EXIFPANEL_KEEP;Megtart +EXIFPANEL_REMOVE;Eltávolít +EXIFPANEL_REMOVEHINT;A kijelölt adatok eldobása a végsÅ‘ fájl mentésekor +EXIFPANEL_RESETALLHINT;Az összes meta-adat visszaáttítása az eredeti állapotba +EXIFPANEL_RESETALL;Mindent visszaállít +EXIFPANEL_RESETHINT;A kijelölt adatok visszaáttítása az eredeti állapotba +EXIFPANEL_RESET;Visszaállít +EXIFPANEL_SUBDIRECTORY;Alkönyvtár +FILEBROWSER_APPLYPROFILE;Feldolgozási paraméter hozzárendelés +FILEBROWSER_ARRANGEMENTHINT;Váltás az elÅ‘nézeti képek függÅ‘leges/vízszintes elrendezése között +FILEBROWSER_CLEARPROFILE;Feldolgozási paraméter törlése +FILEBROWSER_COPYPROFILE;Feldolgozási paraméterek másolása +FILEBROWSER_DELETEDLGLABEL;Fájl törlés megerÅ‘sítése +FILEBROWSER_DELETEDLGMSG;Biztosan törölni kívánja a kijelölt %1 képet? +FILEBROWSER_EMPTYTRASHHINT;Véglegesen letörli a kukában lévÅ‘ képeket +FILEBROWSER_EMPTYTRASH;Kuka ürítése +FILEBROWSER_EXIFFILTERAPPLY;Aktív +FILEBROWSER_EXIFFILTERAPPLYHINT;Az exif szűrÅ‘ ki/bekapcsolása +FILEBROWSER_EXIFFILTERLABEL;Exif SzűrÅ‘ +FILEBROWSER_EXIFFILTERSETTINGS;Beállítások +FILEBROWSER_EXIFFILTERSETTINGSHINT;Az exif szűrÅ‘ beállítása +FILEBROWSER_PARTIALPASTEPROFILE;Részleges beillesztés +FILEBROWSER_PASTEPROFILE;Feldolgozási paraméterek beillesztése +FILEBROWSER_POPUPCANCELJOB;Eltávolítás a sorból +FILEBROWSER_POPUPMOVEEND;Végére mozgatás +FILEBROWSER_POPUPMOVEHEAD;Elejére mozgatás +FILEBROWSER_POPUPOPEN;Megnyitás szerkesztésre +FILEBROWSER_POPUPPROCESS;Feldolgozási sorba helyezés +FILEBROWSER_POPUPRANK1;Jelölés 1 csillaggal +FILEBROWSER_POPUPRANK2;Jelölés 2 csillaggal +FILEBROWSER_POPUPRANK3;Jelölés 3 csillaggal +FILEBROWSER_POPUPRANK4;Jelölés 4 csillaggal +FILEBROWSER_POPUPRANK5;Jelölés 5 csillaggal +FILEBROWSER_POPUPREMOVE;Törlés (végleges) +FILEBROWSER_POPUPRENAME;Ãtnevezés +FILEBROWSER_POPUPSELECTALL;Mindent kijelöl +FILEBROWSER_POPUPTRASH;Kukába dobás +FILEBROWSER_POPUPUNRANK;Jelölés megszüntetése +FILEBROWSER_POPUPUNTRASH;Visszaállítás a kukából +FILEBROWSER_PROCESSINGSETTINGS;Beállítások +FILEBROWSER_PROCESSINGSETTINGSHINT;A fájl formátum és a célkönyvtár beállítása +FILEBROWSER_RENAMEDLGLABEL;Fájl átnevezése +FILEBROWSER_RENAMEDLGMSG;%1 új neve: +FILEBROWSER_SHOWDIRHINT;A könyvtárban lévÅ‘ összes kép mutatása +FILEBROWSER_SHOWQUEUEHINT;A feldolgozási sor tartalmának mutatása +FILEBROWSER_SHOWRANK1HINT;1 csillaggal jelölt képek mutatása +FILEBROWSER_SHOWRANK2HINT;2 csillaggal jelölt képek mutatása +FILEBROWSER_SHOWRANK3HINT;3 csillaggal jelölt képek mutatása +FILEBROWSER_SHOWRANK4HINT;4 csillaggal jelölt képek mutatása +FILEBROWSER_SHOWRANK5HINT;5 csillaggal jelölt képek mutatása +FILEBROWSER_SHOWTRASHHINT;A kuka tartalmának mutatása +FILEBROWSER_SHOWUNRANKHINT;Meg nem jelölt képek mutatása +FILEBROWSER_STARTPROCESSING;Feldolgozás indítása +FILEBROWSER_STARTPROCESSINGHINT;A sorban álló képek feldolgozásának elindítása +FILEBROWSER_STOPPROCESSING;Feldolgozás leállítása +FILEBROWSER_STOPPROCESSINGHINT;A sorban álló képek feldolgozásának leállítása +FILEBROWSER_THUMBSIZE;Bélyegméret +FILEBROWSER_ZOOMINHINT;Növelés +FILEBROWSER_ZOOMOUTHINT;Csökkentés +GENERAL_ABOUT;Névjegy +GENERAL_CANCEL;Mégsem +GENERAL_DISABLED;Kikapcsolva +GENERAL_DISABLE;Kikapcsol +GENERAL_ENABLED;Engedélyezve +GENERAL_ENABLE;Engedélyez +GENERAL_LANDSCAPE;FekvÅ‘ +GENERAL_LOAD;Betöltés +GENERAL_NA;n/a +GENERAL_NO;Nem +GENERAL_OK;OK +GENERAL_PORTRAIT;Ãlló +GENERAL_SAVE;Mentés +GENERAL_YES;Igen +HISTOGRAM_LABEL;Hisztogram +HISTOGRAM_TOOLTIP_B;Kék csatorna hisztogrammja (mutat/elrejt) +HISTOGRAM_TOOLTIP_G;Zöld csatorna hisztogrammja (mutat/elrejt) +HISTOGRAM_TOOLTIP_L;CIELAB Luminancia hisztogramm (mutat/elrejt) +HISTOGRAM_TOOLTIP_R;Piros csatorna hisztogrammja (mutat/elrejt) +HISTORY_CHANGED;Megváltozott +HISTORY_CUSTOMCURVE;Saját görbe +HISTORY_DELSNAPSHOT;Töröl +HISTORY_FROMCLIPBOARD;Vágólapról +HISTORY_LABEL;ElÅ‘zmények +HISTORY_MSG_10;Sötét tónus tömörítés +HISTORY_MSG_11;Tónusgörbe +HISTORY_MSG_12;Auto szint +HISTORY_MSG_13;Vágás +HISTORY_MSG_14;Luminancia fényerÅ‘ +HISTORY_MSG_15;Luminancia kontraszt +HISTORY_MSG_16;Luminancia fekete szint +HISTORY_MSG_17;Luminancia világos tónus tömörítés +HISTORY_MSG_18;Luminancia sötét tónus tömörítés +HISTORY_MSG_19;Luminancia görbe +HISTORY_MSG_1;Kép betöltve +HISTORY_MSG_20;Élesítés +HISTORY_MSG_21;Élesítés sugara +HISTORY_MSG_22;Élesítés mértéke +HISTORY_MSG_23;Élesítés küszöb +HISTORY_MSG_24;Csak az élek élesítése +HISTORY_MSG_25;Élesítés élferismerési sugár +HISTORY_MSG_26;Élesítés élferismerési tolerancia +HISTORY_MSG_27;Élesítés mellékhatás csökkentés +HISTORY_MSG_28;Élesítés mellékhatás csökkentés mértéke +HISTORY_MSG_29;Élesítés algoritmusa +HISTORY_MSG_2;Beállítások betöltése +HISTORY_MSG_30;Dekonvolúciós sugár +HISTORY_MSG_31;Deconvolúció mértéke +HISTORY_MSG_32;Deconvolúció zajelnyomás +HISTORY_MSG_33;Deconvolúció iterációszám +HISTORY_MSG_34;SzíntelítÅ‘dés megelÅ‘zés +HISTORY_MSG_35;Telítettség korlátozó +HISTORY_MSG_36;Telítettség korlát +HISTORY_MSG_37;Színtelítettség +HISTORY_MSG_38;Fehéregyensúly beállítás +HISTORY_MSG_39;SzínhÅ‘mérséklet +HISTORY_MSG_3;Beállítások változtatása +HISTORY_MSG_40;Fehér árnyalat +HISTORY_MSG_41;Színeltolás "A" +HISTORY_MSG_42;Színeltolás "B" +HISTORY_MSG_43;Luminanciazaj-csökkentés +HISTORY_MSG_44;Lum. zajcsökkentés sugár +HISTORY_MSG_45;Lum. zajcsökkentés éltolerancia +HISTORY_MSG_46;Színzaj-csökkentés +HISTORY_MSG_47;Színzaj-csökkentés sugár +HISTORY_MSG_48;Színzaj-csökkentés éltolerancia +HISTORY_MSG_49;Élérzékeny színzaj-csökkentés +HISTORY_MSG_4;ElÅ‘zmény böngészés +HISTORY_MSG_50;Ãrnyékok/Fények korrekció +HISTORY_MSG_51;Fényes részek +HISTORY_MSG_52;Sötét részek +HISTORY_MSG_53;Világos tonális szélesség +HISTORY_MSG_54;Sötét tonális szélesség +HISTORY_MSG_55;Lokális kontraszt +HISTORY_MSG_56;Ãrnyékok/Fények sugár +HISTORY_MSG_57;Durva forgatás +HISTORY_MSG_58;Vízszintes tükrözés +HISTORY_MSG_59;FüggÅ‘leges tükrözés +HISTORY_MSG_5;FényerÅ‘ +HISTORY_MSG_60;Forgatás +HISTORY_MSG_61;Forgatás +HISTORY_MSG_62;Torzítás korrekció +HISTORY_MSG_63;Pillanatkép kiválasztás +HISTORY_MSG_64;Képkivágás +HISTORY_MSG_65;Kromatikus aberráció korrigálás +HISTORY_MSG_66;Beégett részek megmentése +HISTORY_MSG_67;Beégett részek visszaállítása +HISTORY_MSG_68;Beégett részek algoritmus +HISTORY_MSG_69;Munka színprofil +HISTORY_MSG_6;Kontraszt +HISTORY_MSG_70;Kimeneti színprofil +HISTORY_MSG_71;Bemeneti színprofil +HISTORY_MSG_72;Saroksötétedés +HISTORY_MSG_73;Szín keverÅ‘ +HISTORY_MSG_74;Ãtméretezés szorzó +HISTORY_MSG_75;Ãtméretezés algoritmus +HISTORY_MSG_76;Exif Meta-adatok +HISTORY_MSG_77;IPTC Meta-adatok +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;Fekete szint +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;Expozíció kompenzáció +HISTORY_MSG_9;Világos tónus tömörítés +HISTORY_NEWSNAPSHOTAS;cimkével... +HISTORY_NEWSNAPSHOT;Új +HISTORY_NEWSSDIALOGLABEL;Pillanatkép cimkéje: +HISTORY_NEWSSDIALOGTITLE;Új pillanatkép +HISTORY_SETTO;új érték: +HISTORY_SNAPSHOT;Pillanatkép +HISTORY_SNAPSHOTS;Pillanatképek +ICMPANEL_FILEDLGFILTERANY;inden fájl +ICMPANEL_FILEDLGFILTERICM;ICC színprofil fájl +ICMPANEL_GAMMABEFOREINPUT;Gamma korrekció a bemeneti profil elÅ‘tt +ICMPANEL_INPUTCAMERA;FényképezÅ‘gép alapértelmezése +ICMPANEL_INPUTCUSTOM;Saját +ICMPANEL_INPUTDLGLABEL;Bemeneti színprofil kiválasztása... +ICMPANEL_INPUTEMBEDDED;Beágyazott profil, ha van +ICMPANEL_INPUTPROFILE;Bemeneti színprofil +ICMPANEL_NOICM;Nincs színmenedzsment: sRGB kimenet +ICMPANEL_OUTPUTDLGLABEL;Kimeneti színprofil kiválasztása... +ICMPANEL_OUTPUTPROFILE;Kimeneti színprofil +ICMPANEL_SAVEREFERENCE;Referencia kép mentése profil kalibráláshoz +ICMPANEL_WORKINGPROFILE;Munka színprofil +IMAGEAREA_DETAILVIEW;Részlet nézet +IPTCPANEL_AUTHORHINT;A kép létrehozójának neve, pl. író, fényképész, grafikus művész (By-line) +IPTCPANEL_AUTHORSPOSITIONHINT;A kép létrehozójának munkaköre illetve titulusa (By-line Title) +IPTCPANEL_AUTHORSPOSITION;SzerzÅ‘ titulusa +IPTCPANEL_AUTHOR;SzerzÅ‘ +IPTCPANEL_CAPTIONHINT;A kép szöveges leírása (Caption - Abstract) +IPTCPANEL_CAPTION;Leírás +IPTCPANEL_CAPTIONWRITERHINT;A leírást és az adatok rögzítését/szerkesztését/javítását végzÅ‘ személy neve (Writer - Editor) +IPTCPANEL_CAPTIONWRITER;Ãró +IPTCPANEL_CATEGORYHINT;A kép témáját azonosítja (Category) +IPTCPANEL_CATEGORY;Kategória +IPTCPANEL_CITYHINT;A város, ahonnan a kép származik (City) +IPTCPANEL_CITY;Város +IPTCPANEL_COPYHINT;IPTC beállítások másolása a vágólapra +IPTCPANEL_COPYRIGHTHINT;SzerzÅ‘i joggal kapcsolatos megjegyzések (Copyright Notice) +IPTCPANEL_COPYRIGHT;SzerzÅ‘i jog +IPTCPANEL_COUNTRYHINT;Az ország, ahonnan a kép származik (Country - Primary Location Name) +IPTCPANEL_COUNTRY;Ország +IPTCPANEL_CREDITHINT;A kép kibocsájtójának neve (nem feltétlenül a szerzÅ‘) (Credit) +IPTCPANEL_CREDIT;RendelkezÅ‘ +IPTCPANEL_DATECREATED;Dátum +IPTCPANEL_DATECREATEDHINT;A kép rögzítésének dátuma; formátum: ééééhhnn (Date Created) +IPTCPANEL_EMBEDDED;Beágyazott +IPTCPANEL_EMBEDDEDHINT;A betöltött képbe ágyazott információk kiolvasása +IPTCPANEL_HEADLINE;FÅ‘cím +IPTCPANEL_HEADLINEHINT;A kép témájának összegzése (Headline) +IPTCPANEL_INSTRUCTIONSHINT;Egyéb, a képre vonatkozó szerkesztési útmutatás (Special Instructions) +IPTCPANEL_INSTRUCTIONS;Útmutatás +IPTCPANEL_KEYWORDSHINT;Kategorizáláshoz/szűréshez használatos, a képre vonatkozó kulcsszavak (Keywords) +IPTCPANEL_KEYWORDS;Kulcsszavak +IPTCPANEL_PASTEHINT;IPTC beállítások beillesztése a vágólapról +IPTCPANEL_PROVINCEHINT;A megye/állam/régió, ahonnan a kép származik (Province-State) +IPTCPANEL_PROVINCE;Régió +IPTCPANEL_RESETHINT;Visszatérés az aktuális profil alapértékéhez +IPTCPANEL_RESET;Visszaállítás +IPTCPANEL_SOURCE;Forrás +IPTCPANEL_SOURCEHINT;A kép szellemi tartalmának eredeti tulajdonosa (Source) +IPTCPANEL_SUPPCATEGORIESHINT;A kép finomabb, részletesebb kategorizálását teszi lehetÅ‘vé (Supplemental Categories) +IPTCPANEL_SUPPCATEGORIES;További kategóriák +IPTCPANEL_TITLE;Címke +IPTCPANEL_TITLEHINT;A kép rövid azonosítója (Object Name) +IPTCPANEL_TRANSREFERENCEHINT;A továbbítás helyének megjelölése (Original Transmission Reference) +IPTCPANEL_TRANSREFERENCE;Továbbítás helye +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Beállítások +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;másként... +MAIN_BUTTON_SAVE;Kép mentése +MAIN_BUTTON_SENDTOEDITOR;Megnyitás külsÅ‘ programmal +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Ilyen nevü fájl már létezik. +MAIN_MSG_CANNOTLOAD;A képet nem sikerült betölteni. +MAIN_MSG_CANNOTSAVE;Hiba történt a fájl mentése közben. +MAIN_MSG_CANNOTSTARTEDITOR;A meadott külsÅ‘ program nem indítható. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Ãllítsa be a helyes elérési útat a "Beállítások" ablakban. +MAIN_MSG_EXITJOBSINQUEUEINFO;A sorban álló feldolgozatlan képek kilépéskor el fognak veszni. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Biztos, hogy ki akar lépni? Feldolgozatlan képek vannak a feldolgozási sorban. +MAIN_MSG_JOBSINQUEUE;tennivaló vár a sorban +MAIN_MSG_QOVERWRITE;Felülírjam? +MAIN_TAB_BASIC;Alap +MAIN_TAB_COLOR;Színek +MAIN_TAB_DETAIL;Részletek +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Expozíció +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Meta-adatok +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Transzformáció +MAIN_TOOLTIP_HIDEFP;A fájlkezelÅ‘ alsó panel elrejtése/megjelenítése (Gyorsbillentyű: F) +MAIN_TOOLTIP_HIDEHP;Az elÅ‘zményeket is tartalmazó bal panel elrejtése/megjelenítése (Gyorsbillentyű: H) +MAIN_TOOLTIP_INDCLIPPEDH;Túlexponált területek jelzése +MAIN_TOOLTIP_INDCLIPPEDS;Alulexponált területek jelzése +MAIN_TOOLTIP_PREFERENCES;Beállítások megváltoztatása +MAIN_TOOLTIP_QINFO;Néhány fontos információ megjelenítése a képrÅ‘l +MAIN_TOOLTIP_SAVE;A kép mentése az alapértelmezett könyvtárba az alapértelmezett néven +MAIN_TOOLTIP_SAVEAS;A kép mentése a kiválasztott könyvtárba +PARTIALPASTE_BASICGROUP;Alapbeállítások +PARTIALPASTE_CACORRECTION;Kromatikus aberráció +PARTIALPASTE_COARSETRANS;90 fokonkénti forgatás/tükrözés +PARTIALPASTE_COLORBOOST;Színtelítettség +PARTIALPASTE_COLORDENOISE;Színzaj-csökkentés +PARTIALPASTE_COLORGROUP;Színeket érintÅ‘ beállítások +PARTIALPASTE_COLORMIXER;SzínkeverÅ‘ +PARTIALPASTE_COLORSHIFT;Színeltolás +PARTIALPASTE_COMPOSITIONGROUP;Kompozíciós beállítások +PARTIALPASTE_CROP;Crop +PARTIALPASTE_DIALOGLABEL;Feldolgozási beállítások részleges alkalmazása +PARTIALPASTE_DISTORTION;Torzítás +PARTIALPASTE_EXIFCHANGES;Exif változtatások +PARTIALPASTE_EXPOSURE;Expozíció +PARTIALPASTE_HLRECOVERY;Beégett részletek megmentése +PARTIALPASTE_ICMSETTINGS;ICM beállítások +PARTIALPASTE_IPTCINFO;IPTC információk +PARTIALPASTE_LENSGROUP;Objektív optikai hibáinak javítása +PARTIALPASTE_LUMACURVE;Luminancia görbe +PARTIALPASTE_LUMADENOISE;Luminanciazaj-csökkentés +PARTIALPASTE_LUMINANCEGROUP;Luminanciát érintÅ‘ beállítások +PARTIALPASTE_METAICMGROUP;Meta-adat/Színprofil beállítások +PARTIALPASTE_RESIZE;Ãtméretezés +PARTIALPASTE_ROTATION;Forgatás +PARTIALPASTE_SHADOWSHIGHLIGHTS;Ãrnyékos/Fényes részek +PARTIALPASTE_SHARPENING;Élesítés +PARTIALPASTE_VIGNETTING;Saroksötétedés +PARTIALPASTE_WHITEBALANCE;Fehéregyensúly +PREFERENCES_APPLNEXTSTARTUP;újraindítás után érvényes +PREFERENCES_BLINKCLIPPED;Beégett részek villogtatása +PREFERENCES_CACHECLEARALL;Teljes gyorsítótár törlése +PREFERENCES_CACHECLEARPROFILES;Feldolgozási paraméterek törlése +PREFERENCES_CACHECLEARTHUMBS;ElÅ‘nézeti képek törlése +PREFERENCES_CACHEFORMAT1;Egyebi (gyorsabb és szebb) +PREFERENCES_CACHEFORMAT2;JPEG (kisebb a háttértáron) +PREFERENCES_CACHEMAXENTRIES;Gyorsítótárban tárolt képek max. száma +PREFERENCES_CACHEOPTS;Gyorsítótár beállítások +PREFERENCES_CACHESTRAT1;Inkább gyors mint memóriatakarékos +PREFERENCES_CACHESTRAT2;Inkább memóriatakarékos mint gyors +PREFERENCES_CACHESTRAT;Gyorsítótár stratégia +PREFERENCES_CACHETHUMBFORM;ElÅ‘nézeti kép formátuma +PREFERENCES_CACHETHUMBHEIGHT;ElÅ‘nézeti kép maximális magassága +PREFERENCES_CLEARDLG_LINE1;Gyorsítótár ürítése +PREFERENCES_CLEARDLG_LINE2;Ez eltarthat pár másodpercig. +PREFERENCES_CLEARDLG_TITLE;Kérem várjon +PREFERENCES_CLIPPINGIND;Beégett részek jelzése +PREFERENCES_CMETRICINTENT;Intent +PREFERENCES_DATEFORMAT;Dátumformátum +PREFERENCES_DATEFORMATHINT;A következÅ‘ jeleket lehet használni:\n%y : év\n%m : hónap\n%d : nap\n\nPéldául a magyar dátumformátum:\n%y/%m/%d +PREFERENCES_DEFAULTLANG;Alapértelmezett nyelv +PREFERENCES_DEFAULTTHEME;Alapértelmezett kinézet +PREFERENCES_DEMOSAICINGALGO;Bayer interpoláció +PREFERENCES_DIRHOME;Saját könyvtár +PREFERENCES_DIRLAST;Utoljára látogatott könyvtár +PREFERENCES_DIROTHER;Más +PREFERENCES_DIRSELECTDLG;Képek könyvtára induláskor... +PREFERENCES_DIRSOFTWARE;Telepítés helye +PREFERENCES_DMETHOD;Algoritmus +PREFERENCES_EDITORCMDLINE;Egyéb parancssor +PREFERENCES_EXTERNALEDITOR;KülsÅ‘ képszerkesztÅ‘ program +PREFERENCES_FALSECOLOR;Színhiba-elnyomási lépések +PREFERENCES_FBROWSEROPTS;Fájl böngészÅ‘ beállítások +PREFERENCES_FILEFORMAT;Fájl formátum +PREFERENCES_FORIMAGE;Egyéb képekre +PREFERENCES_FORRAW;RAW fájlokra +PREFERENCES_GIMPPATH;GIMP telepítési könyvtára +PREFERENCES_GTKTHEME;Alap GTK kinézet +PREFERENCES_HINT;Tipp +PREFERENCES_HLTHRESHOLD;Küszöbérték kiégett fényekhez +PREFERENCES_ICCDIR;ICC profilok könyvtára +PREFERENCES_IMPROCPARAMS;Alapértelmezett feldolgozási paraméterek +PREFERENCES_INTENT_ABSOLUTE;Absolute Colorimetric +PREFERENCES_INTENT_PERCEPTUAL;Perceptual +PREFERENCES_INTENT_RELATIVE;Relative Colorimetric +PREFERENCES_INTENT_SATURATION;Saturation +PREFERENCES_LIVETHUMBNAILS;ÉlÅ‘ elÅ‘nézeti képek (lassabb) +PREFERENCES_MONITORICC;Monitor ICC profilja +PREFERENCES_OUTDIRFOLDERHINT;Ha ezt a lehetÅ‘séget választja, az összes feldolgozott képek ebbe a könyvtárba kerül +PREFERENCES_OUTDIRFOLDER;Mentés ebbe a könyvtárba: +PREFERENCES_OUTDIRHINT;A következÅ‘ jeleket lehet használni:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nEzek a jelek a megnyitott kép elérési útvonalának részeire vonatkoznak.\n\nPéldául, ha a /home/tom/image/02-09-2006/dsc0012.nef képet nyitjuk meg, ezek a jelek a következÅ‘ket jelentik:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nHa oda kívánja menteni a kész képet, ahol az eredeti volt, az alábbiakat kell beírni:\n%p1/%f\n\nHa a kész képet az eredeti könyvtárán belül egy "converted" alkönyvtárba kívánja menteni, az alábbiakat kell beírni:\n%p1/converted/%f\n\nHa a kész képeket a '/home/tom/converted' könyvtárba kívánja menteni az eredeti, dátumot tartalmazó alkönyvtár megtartásával, írja ezt:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIR;Kimeneti alapértelmezett könyvtár +PREFERENCES_OUTDIRTEMPLATEHINT;A következÅ‘ jeleket lehet használni:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nEzek a jelek a megnyitott kép elérési útvonalának részeire vonatkoznak.\n\nPéldául, ha a /home/tom/image/02-09-2006/dsc0012.nef képet nyitjuk meg, ezek a jelek a következÅ‘ket jelentik:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nHa oda kívánja menteni a kész képet, ahol az eredeti volt, az alábbiakat kell beírni:\n%p1/%f\n\nHa a kész képet az eredeti könyvtárán belül egy "converted" alkönyvtárba kívánja menteni, az alábbiakat kell beírni:\n%p1/converted/%f\n\nHa a kész képeket a '/home/tom/converted' könyvtárba kívánja menteni az eredeti, dátumot tartalmazó alkönyvtár megtartásával, írja ezt:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Sablon használata +PREFERENCES_PARSEDEXTADDHINT;A kiterjesztés beírása után ez a gomb felveszi a listára +PREFERENCES_PARSEDEXTADD;Kiterjesztés hozzáadása +PREFERENCES_PARSEDEXTDELHINT;A kiválasztott sor törlése a listából +PREFERENCES_PARSEDEXT;Felismert kiterjesztések +PREFERENCES_PROFILEHANDLING;Feldolgozási paraméterek kezelése +PREFERENCES_PROFILELOADPR;Ha mindkét helyen van feldolgozási paraméter +PREFERENCES_PROFILEPRCACHE;A gyorsítótárban lévÅ‘t használja +PREFERENCES_PROFILEPRFILE;A kép mellettit használja +PREFERENCES_PROFILESAVECACHE;Feldolgozási paraméterek mentése a gyorsítótárba +PREFERENCES_PROFILESAVEINPUT;Feldolgozási paraméterek mentése a kép mellé +PREFERENCES_PSPATH;Adobe Photoshop telepítési könyvtára +PREFERENCES_SELECTICCDIRDLG;ICC profilok könyvtárának kiválasztása... +PREFERENCES_SELECTLANG;Nyelv kiválasztása +PREFERENCES_SELECTMONITORPROFDLG;Monitor ICC profiljának kiválasztása... +PREFERENCES_SELECTTHEME;Kinézet kiválasztása +PREFERENCES_SHOWBASICEXIF;Fontosabb Exif információk megjelenítése +PREFERENCES_SHOWDATETIME;Felvétel dátumának és idejének megjelenítése +PREFERENCES_SHOWONLYRAW;Csak a RAW fájok megjelenítése +PREFERENCES_SHTHRESHOLD;Küszöbérték elveszett árnyékokhoz +PREFERENCES_STARTUPIMDIR;Képek könyvtára induláskor +PREFERENCES_TAB_BROWSER;Fájl böngészÅ‘ +PREFERENCES_TAB_COLORMGR;Szín menedzsment +PREFERENCES_TAB_GENERAL;Ãltalános +PREFERENCES_TAB_IMPROC;Képfeldolgozás +PREFERENCES_TAB_OUTPUT;Fájl mentési beállítások +PREFERENCES_THUMBSIZE;Képek mérete a böngészÅ‘ben +PROFILEPANEL_FILEDLGFILTERANY;Minden fájl +PROFILEPANEL_FILEDLGFILTERPP;Feldolgozási beállítások +PROFILEPANEL_LABEL;Feldolgozási beállítások +PROFILEPANEL_LOADDLGLABEL;Feldolgozási beállítások betöltése... +PROFILEPANEL_PCUSTOM;Egyedi +PROFILEPANEL_PFILE;Fáljból +PROFILEPANEL_PLASTPHOTO;ElÅ‘zÅ‘ fotó +PROFILEPANEL_PLASTSAVED;Legutóbb használt +PROFILEPANEL_PROFILE;Beállítások +PROFILEPANEL_SAVEDLGLABEL;Feldolgozási beállítások mentése... +PROFILEPANEL_TOOLTIPCOPY;Feldolgozási beállítások vágólapra mentése +PROFILEPANEL_TOOLTIPLOAD;Feldolgozási beállítások betöltése +PROFILEPANEL_TOOLTIPPASTE;Feldolgozási beállítások beillesztése a vágólapról +PROFILEPANEL_TOOLTIPSAVE;Feldolgozási beállítások mentése +PROGRESSBAR_DECODING;Raw fájl dekódolása... +PROGRESSBAR_DEMOSAICING;Bayer interpoláció... +PROGRESSBAR_LOADING;Kép betöltése... +PROGRESSBAR_LOADJPEG;JPEG fájl betöltése... +PROGRESSBAR_LOADPNG;PNG fájl betöltése... +PROGRESSBAR_LOADTIFF;TIFF fájl betöltése... +PROGRESSBAR_PROCESSING;Kép feldolgozása... +PROGRESSBAR_READY;Kész. +PROGRESSBAR_SAVEJPEG;JPEG fájl mentése... +PROGRESSBAR_SAVEPNG;PNG fájl mentése... +PROGRESSBAR_SAVETIFF;TIFF fájl mentése... +PROGRESSDLG_LOADING;Fájl betöltése... +PROGRESSDLG_PROCESSING;Kép feldolgozása... +PROGRESSDLG_SAVING;Fájl mentése... +QINFO_FOCALLENGTH;Fokális távolság +QINFO_ISO;ISO +QINFO_LENS;Objektív +QINFO_NOEXIF;Exif adat nem áll rendelkezésre. +SAVEDLG_FILEFORMAT;Fájl formátum +SAVEDLG_JPEGQUAL;JPEG MinÅ‘ség +SAVEDLG_JPGFILTER;JPEG fájlok +SAVEDLG_PNGCOMPR;PNG Tömörítés +SAVEDLG_PNGFILTER;PNG fájlok +SAVEDLG_PUTTOQUEUE;Feldolgozási sorba helyezés +SAVEDLG_PUTTOQUEUEHEAD;Feldolgozási sorba helyezés az elsÅ‘ helyre +SAVEDLG_PUTTOQUEUETAIL;Feldolgozási sorba helyezés az utolsó helyre +SAVEDLG_SAVEIMMEDIATELY;Mentés azonnal +SAVEDLG_SAVESPP;Feldolgozási paraméterek mentése a kép mellé +SAVEDLG_TIFFFILTER;TIFF fájlok +TOOLBAR_TOOLTIP_CROP;Képkivágás (Gyorsbillentyű: C) +TOOLBAR_TOOLTIP_HAND;"Kéz" eszköz (Gyorsbillentyű: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Vizszintes/függÅ‘leges vonal kijelölése (Gyorsbillentyű: S) +TOOLBAR_TOOLTIP_WB;Fehéregyensúly kijelölés (Gyorsbillentyű: W) +TP_CACORRECTION_BLUE;Kék +TP_CACORRECTION_LABEL;Kromatikus aberráció +TP_CACORRECTION_RED;Piros +TP_CHMIXER_BLUE;Kék +TP_CHMIXER_GREEN;Zöld +TP_CHMIXER_LABEL;SzínkeverÅ‘ +TP_CHMIXER_RED;Piros +TP_COARSETRAF_DEGREE;fok: +TP_COARSETRAF_TOOLTIP_HFLIP;Vizszintes tükrözés +TP_COARSETRAF_TOOLTIP_ROTLEFT;Forgatás balra +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Forgatás jobbra +TP_COARSETRAF_TOOLTIP_VFLIP;FüggÅ‘leges tükrözés +TP_COLORBOOST_ACHANNEL;"a" csatorna +TP_COLORBOOST_AMOUNT;Mennyiség +TP_COLORBOOST_AVOIDCOLORCLIP;Szín telítÅ‘dés elkerülése +TP_COLORBOOST_BCHANNEL;"b" csatorna +TP_COLORBOOST_CHAB;a & b együtt +TP_COLORBOOST_CHANNEL;Csatorna +TP_COLORBOOST_CHSEPARATE;külön +TP_COLORBOOST_ENABLESATLIMITER;Telítettség korlátozás +TP_COLORBOOST_LABEL;Színtelítettség +TP_COLORBOOST_SATLIMIT;Telítettség korlát +TP_COLORDENOISE_EDGESENSITIVE;Élérzékeny +TP_COLORDENOISE_EDGETOLERANCE;Él tolerancia +TP_COLORDENOISE_LABEL;Színzaj-csökkentés +TP_COLORDENOISE_RADIUS;Sugár +TP_COLORSHIFT_BLUEYELLOW;Kék-Sárga +TP_COLORSHIFT_GREENMAGENTA;Zöld-Lila +TP_COLORSHIFT_LABEL;Színeltolás +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Rögzített oldalarány +TP_CROP_GTDIAGONALS;Diagonál módszer +TP_CROP_GTHARMMEANS1;Aranymetszés 1 +TP_CROP_GTHARMMEANS2;Aranymetszés 2 +TP_CROP_GTHARMMEANS3;Aranymetszés 3 +TP_CROP_GTHARMMEANS4;Aranymetszés 4 +TP_CROP_GTNONE;Nincs +TP_CROP_GTRULETHIRDS;Harmadolás +TP_CROP_GUIDETYPE;Segédvonal típusa: +TP_CROP_H;M +TP_CROP_LABEL;Kivágás +TP_CROP_SELECTCROP; Kijelölés egérrel +TP_CROP_W;Sz +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;ErÅ‘sség +TP_DISTORTION_LABEL;Torzítás +TP_EXPOSURE_AUTOLEVELS;Auto szint +TP_EXPOSURE_BLACKLEVEL;Fekete szint +TP_EXPOSURE_BRIGHTNESS;FényerÅ‘ +TP_EXPOSURE_CLIP;Vágás +TP_EXPOSURE_COMPRHIGHLIGHTS;Világos tónus tömörítés +TP_EXPOSURE_COMPRSHADOWS;Sötét tónus tömörítés +TP_EXPOSURE_CONTRAST;Kontraszt +TP_EXPOSURE_CURVEEDITOR;Tónusgörbe +TP_EXPOSURE_EXPCOMP;Exp. Kompenzáció +TP_EXPOSURE_LABEL;Expozíció +TP_HLREC_CIELAB;CIELab visszaállítás +TP_HLREC_COLOR;Szín terjesztés +TP_HLREC_LABEL;Beégett részletek megmentése +TP_HLREC_LUMINANCE;Luminancia +TP_HLREC_METHOD;Preferencia: +TP_ICM_FILEDLGFILTERANY;inden fájl +TP_ICM_FILEDLGFILTERICM;ICC színprofil fájl +TP_ICM_GAMMABEFOREINPUT;Gamma korrekció a bemeneti profil elÅ‘tt +TP_ICM_INPUTCAMERA;FényképezÅ‘gép alapértelmezése +TP_ICM_INPUTCUSTOM;Saját +TP_ICM_INPUTDLGLABEL;Bemeneti színprofil kiválasztása... +TP_ICM_INPUTEMBEDDED;Beágyazott profil, ha van +TP_ICM_INPUTPROFILE;Bemeneti színprofil +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Nincs színmenedzsment: sRGB kimenet +TP_ICM_OUTPUTDLGLABEL;Kimeneti színprofil kiválasztása... +TP_ICM_OUTPUTPROFILE;Kimeneti színprofil +TP_ICM_SAVEREFERENCE;Referencia kép mentése profil kalibráláshoz +TP_ICM_WORKINGPROFILE;Munka színprofil +TP_LUMACURVE_BLACKLEVEL;Fekete szint +TP_LUMACURVE_BRIGHTNESS;FényerÅ‘ +TP_LUMACURVE_COMPRHIGHLIGHTS;Világos tónus tömörítés +TP_LUMACURVE_COMPRSHADOWS;Sötét tónus tömörítés +TP_LUMACURVE_CONTRAST;Kontraszt +TP_LUMACURVE_CURVEEDITOR;Fényesség görbe +TP_LUMACURVE_LABEL;Luminancia +TP_LUMADENOISE_EDGETOLERANCE;Él tolerancia +TP_LUMADENOISE_LABEL;Luminanciazaj-csökkentés +TP_LUMADENOISE_RADIUS;Sugár +TP_RESIZE_BICUBIC;Bicubic +TP_RESIZE_BICUBICSF;Bicubic (lágyabb) +TP_RESIZE_BICUBICSH;Bicubic (keményebb) +TP_RESIZE_BILINEAR;Bilineáris +TP_RESIZE_FULLSIZE;Képméret: +TP_RESIZE_H;M: +TP_RESIZE_LABEL;Ãtméretezés +TP_RESIZE_METHOD;Algoritmus: +TP_RESIZE_NEAREST;Legközelebbi szomszéd +TP_RESIZE_SCALE;Szorzó +TP_RESIZE_W;Sz: +TP_ROTATE_AUTOCROP;Autómatikus kivágás +TP_ROTATE_DEGREE;Fok +TP_ROTATE_FILL;Kitöltés +TP_ROTATE_LABEL;Forgatás +TP_ROTATE_SELECTLINE; Vizszintes vonal kijelölése +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Fényes részek +TP_SHADOWSHLIGHTS_HLTONALW;Tonális szélesség +TP_SHADOWSHLIGHTS_LABEL;Ãrnyékos/Fényes részek +TP_SHADOWSHLIGHTS_LOCALCONTR;Lokális kontraszt +TP_SHADOWSHLIGHTS_RADIUS;Sugár +TP_SHADOWSHLIGHTS_SHADOWS;Sötét részek +TP_SHADOWSHLIGHTS_SHTONALW;Tonális szélesség +TP_SHARPENING_AMOUNT;ErÅ‘sség +TP_SHARPENING_EDRADIUS;Sugár +TP_SHARPENING_EDTOLERANCE;Él tolerancia +TP_SHARPENING_HALOCONTROL;Mellékhatás csökkentés +TP_SHARPENING_HCAMOUNT;Mértéke +TP_SHARPENING_LABEL;Élesítés +TP_SHARPENING_METHOD;Algoritmus +TP_SHARPENING_ONLYEDGES;Csak az élek élesítése +TP_SHARPENING_RADIUS;Sugár +TP_SHARPENING_RLD_AMOUNT;ErÅ‘sség +TP_SHARPENING_RLD_DAMPING;Zajelnyomás +TP_SHARPENING_RLD_ITERATIONS;Iterációszám +TP_SHARPENING_RLD;RL Dekonvolúció +TP_SHARPENING_THRESHOLD;Küszöb +TP_SHARPENING_USM;Unsharp Mask +TP_VIGNETTING_AMOUNT;ErÅ‘sség +TP_VIGNETTING_LABEL;Saroksötétedés +TP_VIGNETTING_RADIUS;Sugár +TP_WBALANCE_AUTO;Automatikus +TP_WBALANCE_CAMERA;Tárolt +TP_WBALANCE_CUSTOM;Egyedi +TP_WBALANCE_GREEN;Ãrnyalat +TP_WBALANCE_LABEL;Fehéregyensúly +TP_WBALANCE_METHOD;Beállítás +TP_WBALANCE_SIZE;Méret: +TP_WBALANCE_SPOTWB;Mintavétel +TP_WBALANCE_TEMPERATURE;SzínhÅ‘mérséklet +ZOOMBAR_DETAIL;Részlet nézet +ZOOMBAR_HUGE;Nagyobb +ZOOMBAR_LARGE;Nagy +ZOOMBAR_NORMAL;Normál +ZOOMBAR_PREVIEW;ElÅ‘nézet +ZOOMBAR_SCALE;Kicsinyítés +ZOOMBAR_SMALL;Kicsi + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands new file mode 100644 index 000000000..3665e6307 --- /dev/null +++ b/rtdata/languages/Nederlands @@ -0,0 +1,704 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# RT 2.3 Nederlands +# 26.12.2007: door Rens Duijsens en Brent Huisman +# 14.03.2008: updated by reggybe +# 01.02.2009: updated to RT2.4-RC by paul.matthijsse +ADJUSTER_RESET_TO_DEFAULT;Terug naar beginwaarde +CURVEEDITOR_FILEDLGFILTERANY;Alle bestanden +CURVEEDITOR_FILEDLGFILTERCURVE;Curvebestanden +CURVEEDITOR_LINEAR;Lineair +CURVEEDITOR_LOADDLGLABEL;Laad curve... +CURVEEDITOR_SAVEDLGLABEL;Bewaar curve... +CURVEEDITOR_TOOLTIPLINEAR;Maak curve lineair +CURVEEDITOR_TOOLTIPLOAD;Laad curve uit bestand +CURVEEDITOR_TOOLTIPSAVE;Bewaar huidige curve +EXIFFILTER_APERTURE;Diafragma +EXIFFILTER_CAMERA;Camera +EXIFFILTER_DIALOGLABEL;Exif-filter +EXIFFILTER_FOCALLEN;Brandpuntsafstand +EXIFFILTER_ISO;ISO-waarde +EXIFFILTER_LENS;Objectief +EXIFFILTER_SHUTTER;Sluitertijd +EXIFPANEL_ADDEDITHINT;Voeg nieuwe tag toe of bewerk tag +EXIFPANEL_ADDEDIT;Voeg toe/bewerk +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Geef waarde +EXIFPANEL_ADDTAGDLG_SELECTTAG;Selecteer tag +EXIFPANEL_ADDTAGDLG_TITLE;Voeg tag toe of bewerk +EXIFPANEL_KEEP;Bewaar +EXIFPANEL_KEEPHINT;Bewaar geselecteerde tags in doelbestand +EXIFPANEL_REMOVEHINT;Verwijder geselecteerde tags in doelbestand +EXIFPANEL_REMOVE;Verwijder +EXIFPANEL_RESETALL;Herstel alles +EXIFPANEL_RESETALLHINT;Zet alle tags terug naar oorspronkelijke waarden +EXIFPANEL_RESET;Herstel +EXIFPANEL_RESETHINT;Zet geselecteerde tags terug naar oorspronkelijke waarden +EXIFPANEL_SUBDIRECTORY;Submap +FILEBROWSER_APPLYPROFILE;Pas profiel toe +FILEBROWSER_ARRANGEMENTHINT;Verticale/horizontale uitlijning miniaturen +FILEBROWSER_CLEARPROFILE;Verwijder profiel +FILEBROWSER_COPYPROFILE;Kopieer profiel +FILEBROWSER_DELETEDLGLABEL;Bevestiging bestand verwijderen +FILEBROWSER_DELETEDLGMSG;Weet u zeker dat u de geselecteerde %1 bestanden wilt verwijderen? +FILEBROWSER_EMPTYTRASHHINT;Verwijder bestanden in prullenbak voorgoed +FILEBROWSER_EMPTYTRASH;Leeg prullenbak +FILEBROWSER_EXIFFILTERAPPLY;Activeer +FILEBROWSER_EXIFFILTERAPPLYHINT;Pas Exif-filter toe op bestandsnavigator +FILEBROWSER_EXIFFILTERLABEL;Exif-filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Stel Exif-filter in +FILEBROWSER_EXIFFILTERSETTINGS;Stel in +FILEBROWSER_PARTIALPASTEPROFILE;Gedeeltelijk plakken +FILEBROWSER_PASTEPROFILE;Plak profiel +FILEBROWSER_POPUPCANCELJOB;Verwijder uit verwerkingsrij +FILEBROWSER_POPUPMOVEEND;Naar eind van verwerkingsrij +FILEBROWSER_POPUPMOVEHEAD;Naar begin verwerkingsrij +FILEBROWSER_POPUPOPEN;Open +FILEBROWSER_POPUPPROCESS;Plaats in verwerkingsrij +FILEBROWSER_POPUPRANK1;Waardeer met 1 ster +FILEBROWSER_POPUPRANK2;Waardeer met 2 sterren +FILEBROWSER_POPUPRANK3;Waardeer met 3 sterren +FILEBROWSER_POPUPRANK4;Waardeer met 4 sterren +FILEBROWSER_POPUPRANK5;Waardeer met 5 sterren +FILEBROWSER_POPUPREMOVE;Verwijder van bestandssysteem +FILEBROWSER_POPUPRENAME;Hernoem +FILEBROWSER_POPUPSELECTALL;Alles selecteren +FILEBROWSER_POPUPTRASH;Verplaats naar prullenbak +FILEBROWSER_POPUPUNRANK;Verwijder sterwaardering +FILEBROWSER_POPUPUNTRASH;Haal terug uit prullenbak +FILEBROWSER_PROCESSINGSETTINGSHINT;Kies bestandsformaat en doelmap +FILEBROWSER_PROCESSINGSETTINGS;Instellingen +FILEBROWSER_RENAMEDLGLABEL;Hernoem bestand +FILEBROWSER_RENAMEDLGMSG;Hernoem bestand "%1" naar: +FILEBROWSER_SHOWDIRHINT;Toon alle foto's in map +FILEBROWSER_SHOWQUEUEHINT;Toon inhoud verwerkingsrij +FILEBROWSER_SHOWRANK1HINT;Toon foto's met 1 ster waardering +FILEBROWSER_SHOWRANK2HINT;Toon foto's met 2 sterren waardering +FILEBROWSER_SHOWRANK3HINT;Toon foto's met 3 sterren waardering +FILEBROWSER_SHOWRANK4HINT;Toon foto's met 4 sterren waardering +FILEBROWSER_SHOWRANK5HINT;Toon foto's met 5 sterren waardering +FILEBROWSER_SHOWTRASHHINT;Toon inhoud prullenbak +FILEBROWSER_SHOWUNRANKHINT;Toon foto's zonder sterwaardering +FILEBROWSER_STARTPROCESSINGHINT;Start verwerking/bewaren van bestanden in verwerkingsrij +FILEBROWSER_STARTPROCESSING;Start verwerking +FILEBROWSER_STOPPROCESSINGHINT;Stop verwerking van foto's in verwerkingsrij +FILEBROWSER_STOPPROCESSING;Stop verwerking +FILEBROWSER_THUMBSIZE;Miniaturen +FILEBROWSER_ZOOMINHINT;Groter +FILEBROWSER_ZOOMOUTHINT;Kleiner +GENERAL_ABOUT;Over +GENERAL_CANCEL;Annuleren +GENERAL_DISABLE;Deactiveren +GENERAL_DISABLED;Gedeactiveerd +GENERAL_ENABLE;Activeer +GENERAL_ENABLED;Geactiveerd +GENERAL_LANDSCAPE;Landschap +GENERAL_LOAD;Laden +GENERAL_NA;nvt. +GENERAL_NO;Nee +GENERAL_OK;OK +GENERAL_PORTRAIT;Portret +GENERAL_SAVE;Opslaan +GENERAL_YES;Ja +HISTOGRAM_LABEL;Histogram +HISTOGRAM_TOOLTIP_B;Toon/verberg blauw histogram +HISTOGRAM_TOOLTIP_G;Toon/verberg groen histogram +HISTOGRAM_TOOLTIP_L;Toon/verberg CIELAB luminantie histogram +HISTOGRAM_TOOLTIP_R;Toon/verberg rood histogram +HISTORY_CHANGED;Veranderd +HISTORY_CUSTOMCURVE;Handmatig +HISTORY_DELSNAPSHOT;Wis +HISTORY_FROMCLIPBOARD;Van klembord +HISTORY_LABEL;Geschiedenis +HISTORY_MSG_10;Schaduwcompressie +HISTORY_MSG_11;Tooncurve +HISTORY_MSG_12;Automatische belichting +HISTORY_MSG_13;Drempel +HISTORY_MSG_14;Lum: helderheid +HISTORY_MSG_15;Lum: contrast +HISTORY_MSG_16;Lum: schaduwen +HISTORY_MSG_17;Lum: compr. hoge lichten +HISTORY_MSG_18;Lum: schaduwcompressie +HISTORY_MSG_19;Luminantiecurve +HISTORY_MSG_1;Foto geladen +HISTORY_MSG_20;Verscherping +HISTORY_MSG_21;Straal verscherping +HISTORY_MSG_22;Hoeveelheid verscherping +HISTORY_MSG_23;Drempel verscherping +HISTORY_MSG_24;Alleen randen verscherpen +HISTORY_MSG_25;Straal randverscherping +HISTORY_MSG_26;Tolerantie randverscherping +HISTORY_MSG_27;Verscherpen halocontrole +HISTORY_MSG_28;Halocontrole hoeveelheid +HISTORY_MSG_29;Verscherpingsmethode +HISTORY_MSG_2;Profiel geladen +HISTORY_MSG_30;Straal RL-verscherping +HISTORY_MSG_31;Hoeveelheid RL-verscherping +HISTORY_MSG_32;Demping RL-verscherping +HISTORY_MSG_33;Herhaling RL-verscherping +HISTORY_MSG_34;Vermijd kleuroversturing +HISTORY_MSG_35;Verzadigingsbegrenzer +HISTORY_MSG_36;Verzadigingslimiet +HISTORY_MSG_37;Kleurversterking +HISTORY_MSG_38;Witbalansmethode +HISTORY_MSG_39;Kleurtemperatuur +HISTORY_MSG_3;Profiel aangepast +HISTORY_MSG_40;Groentint WB +HISTORY_MSG_41;Kleurverschuiving A +HISTORY_MSG_42;Kleurverschuiving B +HISTORY_MSG_43;Ruisreductie luminantie +HISTORY_MSG_44;Straal lum. ruisreductie +HISTORY_MSG_45;Randtolerantie lum. ruisreductie +HISTORY_MSG_46;Ruisreductie kleur +HISTORY_MSG_47;Straal kleurruisreductie +HISTORY_MSG_48;Randtolerantie kleurruisreductie +HISTORY_MSG_49;Randgevoeligheid kleurruisreductie +HISTORY_MSG_4;Door geschiedenis bladeren +HISTORY_MSG_50;Schaduwen/hoge lichten +HISTORY_MSG_51;Compressie hoge lichten +HISTORY_MSG_52;Schaduwen ophelderen +HISTORY_MSG_53;Toonomvang hoge lichten +HISTORY_MSG_54;Toonomvang schaduwen +HISTORY_MSG_55;Lokaal contrast +HISTORY_MSG_56;Straal schaduwen/hoge lichten +HISTORY_MSG_57;Grof roteren +HISTORY_MSG_58;Horizontaal spiegelen +HISTORY_MSG_59;Vertikaal spiegelen +HISTORY_MSG_5;Helderheid +HISTORY_MSG_60;Roteren +HISTORY_MSG_61;Rotatie +HISTORY_MSG_62;Corrigeer lensvervorming +HISTORY_MSG_63;Snapshot +HISTORY_MSG_64;Afbeelding bijsnijden +HISTORY_MSG_65;C/A-correctie +HISTORY_MSG_66;Repareer hoge lichten +HISTORY_MSG_67;Repareer hoge lichten, hoeveelheid +HISTORY_MSG_68;Repareer hoge lichten, methode +HISTORY_MSG_69;Kleurwerkruimte +HISTORY_MSG_6;Contrast +HISTORY_MSG_70;Uitvoerkleurruimte +HISTORY_MSG_71;Invoerkleurruimte +HISTORY_MSG_72;Vignetteringscorrectie +HISTORY_MSG_73;Kanaalmixer +HISTORY_MSG_74;Schalingsinstelling +HISTORY_MSG_75;Schalingsmethode +HISTORY_MSG_76;Exif-metadata +HISTORY_MSG_77;IPTC-metadata +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;Schaduwen versterken +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;Belichtingscompensatie +HISTORY_MSG_9;Compressie hoge lichten +HISTORY_NEWSNAPSHOTAS;Als... +HISTORY_NEWSNAPSHOT;Nieuw +HISTORY_NEWSSDIALOGLABEL;Naam snapshot: +HISTORY_NEWSSDIALOGTITLE;Voeg nieuw snapshot toe +HISTORY_SETTO;Instellen +HISTORY_SNAPSHOT;Nieuw +HISTORY_SNAPSHOTS;Snapshots +ICMPANEL_FILEDLGFILTERANY;Alle bestanden +ICMPANEL_FILEDLGFILTERICM;ICC-profielbestanden +ICMPANEL_GAMMABEFOREINPUT;Profiel past gamma toe +ICMPANEL_INPUTCAMERA;Camera +ICMPANEL_INPUTCUSTOM;Handmatig +ICMPANEL_INPUTDLGLABEL;Selecteer invoer-ICC-profiel... +ICMPANEL_INPUTEMBEDDED;Gebruik ingebed profiel indien mogelijk +ICMPANEL_INPUTPROFILE;Invoerprofiel +ICMPANEL_NOICM;Geen ICM: sRGB-uitvoer +ICMPANEL_OUTPUTDLGLABEL;Selecteer uitvoer-ICC-profiel... +ICMPANEL_OUTPUTPROFILE;Uitvoerprofiel +ICMPANEL_SAVEREFERENCE;Bewaar referentiefoto tbv. profiling +ICMPANEL_WORKINGPROFILE;Werkprofiel +IMAGEAREA_DETAILVIEW;Detailvenster +IPTCPANEL_AUTHOR;Auteur +IPTCPANEL_AUTHORHINT;Naam van de maker van het object, bijv. schrijver, fotograaf of ontwerper (By-line) +IPTCPANEL_AUTHORSPOSITIONHINT;Titel van de maker(s) van het object (By-line Title) +IPTCPANEL_AUTHORSPOSITION;Positie van de maker +IPTCPANEL_CAPTIONHINT;Tekstuele omschrijving van de data (Omschrijving - abstract) +IPTCPANEL_CAPTION;Omschrijving +IPTCPANEL_CAPTIONWRITERHINT;De naam van de persoon betrokken bij het schrijven, bewerken of corrigeren van de foto of omschrijving (Schrijver - Editor) +IPTCPANEL_CAPTIONWRITER;Maker van de omschrijving +IPTCPANEL_CATEGORY;Categorie +IPTCPANEL_CATEGORYHINT;Beschrijft het onderwerp van de foto volgens de mening van de maker (Categorie) +IPTCPANEL_CITYHINT;Plaats van de opname (Plaats) +IPTCPANEL_CITY;Plaats +IPTCPANEL_COPYHINT;Kopieer IPTC-instellingen naar klembord +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COPYRIGHTHINT;Eventuele vereiste copyright-meldingen (Copyright-melding) +IPTCPANEL_COUNTRYHINT;De naam van het land/primaire locatie waar de foto werd genomen (Land - Primaire locatienaam) +IPTCPANEL_COUNTRY;Land +IPTCPANEL_CREDIT;Credit +IPTCPANEL_CREDITHINT;Naam van de leverancier van de foto, niet noodzakelijkerwijs de eigenaar/maker (Credit) +IPTCPANEL_DATECREATEDHINT;Datum waarop de foto werd genomen; formaat: JJJJMMDD (Opnamedatum) +IPTCPANEL_DATECREATED;Opnamedatum +IPTCPANEL_EMBEDDEDHINT;Keer terug naar IPTC-data die in de foto zijn opgeslagen +IPTCPANEL_EMBEDDED;Ingebed +IPTCPANEL_HEADLINEHINT;Samenvatting van de inhoud van de foto (Titel) +IPTCPANEL_HEADLINE;Titel +IPTCPANEL_INSTRUCTIONSHINT;Andere instructies mbt. beeldgebruik (Speciale Instructies) +IPTCPANEL_INSTRUCTIONS;Instructies +IPTCPANEL_KEYWORDSHINT;Gebruikt om sleutelwoorden mee te geven tbv. zoekdoeleinden (Sleutelwoorden) +IPTCPANEL_KEYWORDS;Sleutelwoorden +IPTCPANEL_PASTEHINT;Plak IPTC-instellingen van klembord +IPTCPANEL_PROVINCEHINT;De provincie/staat/departement waar de foto werd genomen (Provincie-Staat) +IPTCPANEL_PROVINCE;Provincie +IPTCPANEL_RESETHINT;Terug naar standaardwaarden +IPTCPANEL_RESET;Standaardwaarden +IPTCPANEL_SOURCE;Bron +IPTCPANEL_SOURCEHINT;De oorspronkelijke eigenaar van de foto (Bron) +IPTCPANEL_SUPPCATEGORIES;Extra categorieën +IPTCPANEL_SUPPCATEGORIESHINT;Verdere verfijning van het onderwerp van de foto (Extra categorieën) +IPTCPANEL_TITLEHINT;Een korte referentienaam voor de foto (Objectnaam) +IPTCPANEL_TITLE;Titel +IPTCPANEL_TRANSREFERENCEHINT;Een code die de locatie van de oorspronkelijke transmissie representeert (Original Transmission Reference) +IPTCPANEL_TRANSREFERENCE;Trans. Reference +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Voorkeuren +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;Als... +MAIN_BUTTON_SAVE;Bewaar foto +MAIN_BUTTON_SENDTOEDITOR;Stuur naar fotoprogramma +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Bestand bestaat reeds. +MAIN_MSG_CANNOTLOAD;Fout bij laden +MAIN_MSG_CANNOTSAVE;Fout bij opslaan van de afbeelding +MAIN_MSG_CANNOTSTARTEDITOR;Kan fotoprogramma niet starten. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Geef juiste pad op in 'Voorkeuren'. +MAIN_MSG_EXITJOBSINQUEUEINFO;Foto's in de verwerkingsrij zullen niet verwerkt worden bij afsluiten. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Weet u zeker dat u wilt stoppen? De verwerkingsrij bevat onverwerkte foto's. +MAIN_MSG_JOBSINQUEUE;Bewerking(en) in de wachtrij +MAIN_MSG_QOVERWRITE;Wilt u het bestand overschrijven? +MAIN_TAB_BASIC;Grondwaarde +MAIN_TAB_COLOR;Kleur +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Belichting +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Transformeer +MAIN_TOOLTIP_HIDEFP;Toon/verberg onderpaneel (bestandsnavigator, sneltoets F) +MAIN_TOOLTIP_HIDEHP;Toon/verberg linkerpaneel (geschiedenis, sneltoets H) +MAIN_TOOLTIP_INDCLIPPEDH;Overbelichtingsindicatie +MAIN_TOOLTIP_INDCLIPPEDS;Onderbelichtingsindicatie +MAIN_TOOLTIP_PREFERENCES;Voorkeuren en instellingen +MAIN_TOOLTIP_QINFO;Beknopte fotogegevens +MAIN_TOOLTIP_SAVEAS;Bewaar foto in andere map/ander formaat +MAIN_TOOLTIP_SAVE;Bewaar foto in standaardmap +PARTIALPASTE_BASICGROUP;Basisinstellingen +PARTIALPASTE_CACORRECTION;C/A-correctie +PARTIALPASTE_COARSETRANS;90 graden roteren/spiegelen +PARTIALPASTE_COLORBOOST;Kleurversterking +PARTIALPASTE_COLORDENOISE;Ruisreductie kleur +PARTIALPASTE_COLORGROUP;Kleurgerelateerde instellingen +PARTIALPASTE_COLORMIXER;Kleurenmixer +PARTIALPASTE_COLORSHIFT;Kleurverschuiving +PARTIALPASTE_COMPOSITIONGROUP;Compositie-instellingen +PARTIALPASTE_CROP;Bijsnijden +PARTIALPASTE_DIALOGLABEL;Profiel gedeeltelijk plakken... +PARTIALPASTE_DISTORTION;Corrigeer lensvervorming +PARTIALPASTE_EXIFCHANGES;Wijzig Exif-gegevens +PARTIALPASTE_EXPOSURE;Belichting +PARTIALPASTE_HLRECOVERY;Repareer hoge lichten +PARTIALPASTE_ICMSETTINGS;ICM-instellingen +PARTIALPASTE_IPTCINFO;IPTC-informatie +PARTIALPASTE_LENSGROUP;Lensgerelateerde instellingen +PARTIALPASTE_LUMACURVE;Luminantiecurve +PARTIALPASTE_LUMADENOISE;Ruisreductie luminantie +PARTIALPASTE_LUMINANCEGROUP;Instellingen luminantie +PARTIALPASTE_METAICMGROUP;Metadata/ICM-instellingen +PARTIALPASTE_RESIZE;Wijzig grootte +PARTIALPASTE_ROTATION;Roteren +PARTIALPASTE_SHADOWSHIGHLIGHTS;Schaduwen/hoge lichten +PARTIALPASTE_SHARPENING;Verscherping +PARTIALPASTE_VIGNETTING;Vignetteringscorrectie +PARTIALPASTE_WHITEBALANCE;Witbalans +PREFERENCES_APPLNEXTSTARTUP;Opnieuw opstarten vereist +PREFERENCES_BLINKCLIPPED;Knipper bij over/onderbelichting +PREFERENCES_CACHECLEARALL;Wis alles +PREFERENCES_CACHECLEARPROFILES;Wis profielen +PREFERENCES_CACHECLEARTHUMBS;Wis miniaturen +PREFERENCES_CACHEFORMAT1;RawTherapee (sneller, beter) +PREFERENCES_CACHEFORMAT2;JPEG (minder schijfruimte) +PREFERENCES_CACHEMAXENTRIES;Maximaal aantal elementen in cache +PREFERENCES_CACHEOPTS;Cache-opties +PREFERENCES_CACHESTRAT1;Sneller, meer geheugenbeslag +PREFERENCES_CACHESTRAT2;Langzamer, minder geheugenbeslag +PREFERENCES_CACHESTRAT;Cache-strategie +PREFERENCES_CACHETHUMBFORM;Miniatuurformaat cache +PREFERENCES_CACHETHUMBHEIGHT;Maximale hoogte miniaturen +PREFERENCES_CLEARDLG_LINE1;Cache legen... +PREFERENCES_CLEARDLG_LINE2;Dit kan even duren. +PREFERENCES_CLEARDLG_TITLE;Momentje svp. +PREFERENCES_CLIPPINGIND;Indicatie over/onderbelichting +PREFERENCES_CMETRICINTENT;Bedoelde colorimetrie +PREFERENCES_DATEFORMAT;Datumformaat +PREFERENCES_DATEFORMATHINT;U kunt de volgende formaten gebruiken:\n%y : jaar\n%m : maand\n%d : dag\n\nHet Nederlandse datumformaat is bijvoorbeeld:\n%d/%m/%y +PREFERENCES_DEFAULTLANG;Standaardtaal +PREFERENCES_DEFAULTTHEME;Standaardthema +PREFERENCES_DEMOSAICINGALGO;Demozaïek-algoritme +PREFERENCES_DIRHOME;Standaardmap +PREFERENCES_DIRLAST;Laatst bezochte map +PREFERENCES_DIROTHER;Anders +PREFERENCES_DIRSELECTDLG;Selecteer standaardmap bij opstarten... +PREFERENCES_DIRSOFTWARE;Installatiemap +PREFERENCES_DMETHOD;Methode +PREFERENCES_EDITORCMDLINE;Andere editor, geef pad +PREFERENCES_EXTERNALEDITOR;Externe editor +PREFERENCES_FALSECOLOR;Stapgrootte kleurfoutonderdrukking +PREFERENCES_FBROWSEROPTS;Opties bestandsnavigator +PREFERENCES_FILEFORMAT;Bestandstype +PREFERENCES_FORIMAGE;Voor niet-RAW-bestanden +PREFERENCES_FORRAW;Voor RAW-bestanden +PREFERENCES_GIMPPATH;Installatiemap GIMP +PREFERENCES_GTKTHEME;GTK standaard +PREFERENCES_HINT;Voorbeeld +PREFERENCES_HLTHRESHOLD;Grenswaarde overbelichting +PREFERENCES_ICCDIR;Map met ICC-profielen +PREFERENCES_IMPROCPARAMS;Standaardprofiel +PREFERENCES_INTENT_ABSOLUTE;Absolute colorimetrie +PREFERENCES_INTENT_PERCEPTUAL;Waargenomen colorimetrie +PREFERENCES_INTENT_RELATIVE;Relatieve colorimetrie +PREFERENCES_INTENT_SATURATION;Verzadiging +PREFERENCES_LIVETHUMBNAILS;Live-miniaturen (langzamer) +PREFERENCES_MONITORICC;Monitorprofiel +PREFERENCES_OUTDIRFOLDERHINT;Sla foto's op in andere map +PREFERENCES_OUTDIRFOLDER;Sla op in map +PREFERENCES_OUTDIRHINT;U kunt de volgende formaten gebruiken:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nDeze formaten hebben betrekking op de mappen en submappen van het RAW-bestand.\n\nAls bijvoorbeeld /home/tom/image/02-09-2006/dsc0012.nef is geopend, hebben deze formaten de volgende betekenis:\n%f=dsc0012, %d1=02-09-2006, %d2=foto, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nWanneer de geconverteerde RAW-foto in dezelfde map moet komen als het origineel, schrijf dan:\n%p1/%f\n\nIndien u de geconverteerde RAW-foto in een map genaamd 'geconverteerd' wilt plaatsen die een submap is van de oorspronkelijke locatie, schrijft u:\n%p1/geconverteerd/%f\n\nWilt u het geconverteerde RAW-bestand bewaren in map '/home/tom/geconverteerd' met behoud van dezelfde submap met datums, schrijf dan:\n%p2/geconverteerd/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Gebruik sjabloon +PREFERENCES_OUTDIRTEMPLATEHINT;U kunt de volgende formaten gebruiken:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nDeze formaten hebben betrekking op de mappen en submappen van het RAW-bestand.\n\nAls bijvoorbeeld /home/tom/image/02-09-2006/dsc0012.nef is geopend, hebben deze formaten de volgende betekenis:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nWanneer de geconverteerde RAW-foto in dezelfde map moet komen als het origineel, schrijf dan:\n%p1/%f\n\nIndien u de geconverteerde RAW-foto in een map genaamd 'geconverteerd' wilt plaatsen die een submap is van de oorspronkelijke locatie, schrijft u:\n%p1/geconverteerd/%f\n\nWilt u het geconverteerde RAW-bestand bewaren in map '/home/tom/geconverteerd' met behoud van dezelfde submap met datums, schrijf dan:\n%p2/geconverteerd/%d1/%f +PREFERENCES_OUTDIR;Uitvoermap +PREFERENCES_PARSEDEXTADDHINT;Typ nieuwe extensie en druk op knop om aan lijst toe te voegen +PREFERENCES_PARSEDEXTADD;Voeg extensie toe +PREFERENCES_PARSEDEXTDELHINT;Verwijder geselecteerde extensie(s) uit lijst +PREFERENCES_PARSEDEXT;Toon extensies +PREFERENCES_PROFILEHANDLING;Verwerking profielen +PREFERENCES_PROFILELOADPR;Laadprioriteit profielen +PREFERENCES_PROFILEPRCACHE;Profiel in cache +PREFERENCES_PROFILEPRFILE;Profiel bij RAW-bestand +PREFERENCES_PROFILESAVECACHE;Bewaar profiel in cache +PREFERENCES_PROFILESAVEINPUT;Bewaar profiel bij RAW-bestand +PREFERENCES_PSPATH;Installatiemap Adobe Photoshop +PREFERENCES_SELECTICCDIRDLG;Selecteer ICC-profielmap... +PREFERENCES_SELECTLANG;Selecteer taal +PREFERENCES_SELECTMONITORPROFDLG;Selecteer ICC-profielmap van de monitor... +PREFERENCES_SELECTTHEME;Kies thema +PREFERENCES_SHOWBASICEXIF;Toon standaard Exif-info +PREFERENCES_SHOWDATETIME;Toon datum en tijd +PREFERENCES_SHOWONLYRAW;Toon alleen RAW-bestanden +PREFERENCES_SHTHRESHOLD;Grenswaarde onderbelichting +PREFERENCES_STARTUPIMDIR;Standaardmap bij opstarten +PREFERENCES_TAB_BROWSER;Bestandsnavigator +PREFERENCES_TAB_COLORMGR;Kleurbeheer +PREFERENCES_TAB_GENERAL;Algemeen +PREFERENCES_TAB_IMPROC;Beeldverwerking +PREFERENCES_TAB_OUTPUT;Uitvoeropties +PREFERENCES_THUMBSIZE;Miniatuurgrootte +PROFILEPANEL_FILEDLGFILTERANY;Alle bestanden +PROFILEPANEL_FILEDLGFILTERPP;Profielen +PROFILEPANEL_LABEL;Profielen +PROFILEPANEL_LOADDLGLABEL;Kies profiel... +PROFILEPANEL_PCUSTOM;Handmatig +PROFILEPANEL_PFILE;Uit bestand +PROFILEPANEL_PLASTPHOTO;Laatste afbeelding +PROFILEPANEL_PLASTSAVED;Laatst opgeslagen +PROFILEPANEL_PROFILE;Profiel +PROFILEPANEL_SAVEDLGLABEL;Bewaar profiel... +PROFILEPANEL_TOOLTIPCOPY;Kopieer huidig profiel naar klembord +PROFILEPANEL_TOOLTIPLOAD;Laad profiel uit bestand +PROFILEPANEL_TOOLTIPPASTE; Plak profiel van klembord +PROFILEPANEL_TOOLTIPSAVE;Bewaar huidig profiel +PROGRESSBAR_DECODING;Laden RAW-bestand... +PROGRESSBAR_DEMOSAICING;Demozaïek-algoritme... +PROGRESSBAR_LOADING;Afbeelding laden... +PROGRESSBAR_LOADJPEG;Laden JPEG-bestand... +PROGRESSBAR_LOADPNG;Laden PNG-bestand... +PROGRESSBAR_LOADTIFF;Laden TIFF-bestand... +PROGRESSBAR_PROCESSING;Foto verwerken... +PROGRESSBAR_READY;Gereed. +PROGRESSBAR_SAVEJPEG;Opslaan JPEG-bestand... +PROGRESSBAR_SAVEPNG;Opslaan PNG-bestand... +PROGRESSBAR_SAVETIFF;Opslaan TIFF-bestand... +PROGRESSDLG_LOADING;Foto laden... +PROGRESSDLG_PROCESSING;Foto verwerken... +PROGRESSDLG_SAVING;Foto opslaan... +QINFO_FOCALLENGTH;Brandpuntsafstand +QINFO_ISO;ISO +QINFO_LENS;Objectief +QINFO_NOEXIF;Exif-gegevens niet beschikbaar. +SAVEDLG_FILEFORMAT;Bestandstype +SAVEDLG_JPEGQUAL;JPEG-kwaliteit +SAVEDLG_JPGFILTER;JPEG-bestanden +SAVEDLG_PNGCOMPR;PNG-compressie +SAVEDLG_PNGFILTER;PNG-bestanden +SAVEDLG_PUTTOQUEUEHEAD;Plaats vooraan in verwerkingsrij +SAVEDLG_PUTTOQUEUE;Plaats in verwerkingsrij +SAVEDLG_PUTTOQUEUETAIL;Plaats achteraan in verwerkingsrij +SAVEDLG_SAVEIMMEDIATELY;Bewaar meteen +SAVEDLG_SAVESPP;Bewaar afbeelding met profiel +SAVEDLG_TIFFFILTER;TIFF-bestanden +TOOLBAR_TOOLTIP_CROP;Bijsnijden (sneltoets C) +TOOLBAR_TOOLTIP_HAND;Sleepgereedschap (sneltoets N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Rechte lijn bepalen (sneltoets S) +TOOLBAR_TOOLTIP_WB;Witbalans (sneltoets W) +TP_CACORRECTION_BLUE;Blauw +TP_CACORRECTION_LABEL;Corrigeer chrom. aberratie +TP_CACORRECTION_RED;Rood +TP_CHMIXER_BLUE;Blauw +TP_CHMIXER_GREEN;Groen +TP_CHMIXER_LABEL;Kanaalmixer +TP_CHMIXER_RED;Rood +TP_COARSETRAF_DEGREE;graden: +TP_COARSETRAF_TOOLTIP_HFLIP;Horizontaal spiegelen +TP_COARSETRAF_TOOLTIP_ROTLEFT;Linksom roteren +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rechtsom roteren +TP_COARSETRAF_TOOLTIP_VFLIP;Verticaal spiegelen +TP_COLORBOOST_ACHANNEL;Kanaal A +TP_COLORBOOST_AMOUNT;Hoeveelheid +TP_COLORBOOST_AVOIDCOLORCLIP;Vermijd kleuroversturing +TP_COLORBOOST_BCHANNEL;Kanaal B +TP_COLORBOOST_CHAB;a & b +TP_COLORBOOST_CHANNEL;Kanaal +TP_COLORBOOST_CHSEPARATE;Scheiden +TP_COLORBOOST_ENABLESATLIMITER;Activeer verzadigingsbegrenzer +TP_COLORBOOST_LABEL;Kleurversterking +TP_COLORBOOST_SATLIMIT;Verzadigingslimiet +TP_COLORDENOISE_EDGESENSITIVE;Randgevoeligheid +TP_COLORDENOISE_EDGETOLERANCE;Randtolerantie +TP_COLORDENOISE_LABEL;Ruisonderdrukking op kleur +TP_COLORDENOISE_RADIUS;Straal +TP_COLORSHIFT_BLUEYELLOW;Blauw-Geel +TP_COLORSHIFT_GREENMAGENTA;Groen-Magenta +TP_COLORSHIFT_LABEL;Kleurverschuiving +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Verhouding: +TP_CROP_GTDIAGONALS;Diagonaalmethode +TP_CROP_GTHARMMEANS1;Harmonische snede 1 +TP_CROP_GTHARMMEANS2;Harmonische snede 2 +TP_CROP_GTHARMMEANS3;Harmonische snede 3 +TP_CROP_GTHARMMEANS4;Harmonische snede 4 +TP_CROP_GTNONE;Geen +TP_CROP_GTRULETHIRDS;Regel van derden +TP_CROP_GUIDETYPE;Hulplijnen: +TP_CROP_H;H +TP_CROP_LABEL;Bijsnijden +TP_CROP_SELECTCROP;Selecteer gebied +TP_CROP_W;B +TP_CROP_X;X +TP_CROP_Y;Y +TP_DISTORTION_AMOUNT;Hoeveelheid +TP_DISTORTION_LABEL;Corrigeer lensvervorming +TP_EXPOSURE_AUTOLEVELS;Autom. niveaus +TP_EXPOSURE_BLACKLEVEL;Schaduwen +TP_EXPOSURE_BRIGHTNESS;Helderheid +TP_EXPOSURE_CLIP;Drempel +TP_EXPOSURE_COMPRHIGHLIGHTS;Hoge lichten comprimeren +TP_EXPOSURE_COMPRSHADOWS;Schaduwcompressie +TP_EXPOSURE_CONTRAST;Contrast +TP_EXPOSURE_CURVEEDITOR;Tooncurve +TP_EXPOSURE_EXPCOMP;Belichtingscompensatie +TP_EXPOSURE_LABEL;Belichting +TP_HLREC_CIELAB;CIELab-blending +TP_HLREC_COLOR;Kleurherstel +TP_HLREC_LABEL;Repareer hoge lichten +TP_HLREC_LUMINANCE;Lichtherstel +TP_HLREC_METHOD;Methode: +TP_ICM_FILEDLGFILTERANY;Alle bestanden +TP_ICM_FILEDLGFILTERICM;ICC-profielbestanden +TP_ICM_GAMMABEFOREINPUT;Profiel past gamma toe +TP_ICM_INPUTCAMERA;Camera +TP_ICM_INPUTCUSTOM;Handmatig +TP_ICM_INPUTDLGLABEL;Selecteer invoer-ICC-profiel... +TP_ICM_INPUTEMBEDDED;Gebruik ingebed profiel, indien mogelijk +TP_ICM_INPUTPROFILE;Invoerprofiel +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Geen ICM: sRGB-uitvoer +TP_ICM_OUTPUTDLGLABEL;Selecteer uitvoer-ICC-profiel... +TP_ICM_OUTPUTPROFILE;Uitvoerprofiel +TP_ICM_SAVEREFERENCE;Bewaar referentiefoto tbv. profiling +TP_ICM_WORKINGPROFILE;Werkprofiel +TP_LUMACURVE_BLACKLEVEL;Schaduwen +TP_LUMACURVE_BRIGHTNESS;Helderheid +TP_LUMACURVE_COMPRHIGHLIGHTS;Hoge lichten comprimeren +TP_LUMACURVE_COMPRSHADOWS;Schaduwen comprimeren +TP_LUMACURVE_CONTRAST;Contrast +TP_LUMACURVE_CURVEEDITOR;Luminantiecurve +TP_LUMACURVE_LABEL;Luminantiecurve +TP_LUMADENOISE_EDGETOLERANCE;Randtolerantie +TP_LUMADENOISE_LABEL;Ruisonderdrukking op luminantie +TP_LUMADENOISE_RADIUS;Straal +TP_RESIZE_BICUBIC;Bikubisch +TP_RESIZE_BICUBICSF;Bikubisch (zachter) +TP_RESIZE_BICUBICSH;Bikubisch (scherper) +TP_RESIZE_BILINEAR;Bilineair +TP_RESIZE_FULLSIZE;Volledige beeldgrootte: +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Grootte aanpassen +TP_RESIZE_METHOD;Methode: +TP_RESIZE_NEAREST;Dichtstbij +TP_RESIZE_SCALE;Verhouding +TP_RESIZE_W;B: +TP_ROTATE_AUTOCROP;Automatisch bijsnijden +TP_ROTATE_DEGREE;Graden +TP_ROTATE_FILL;Uitvullen +TP_ROTATE_LABEL;Roteren +TP_ROTATE_SELECTLINE;Bepaal rechte lijn +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Hoge lichten +TP_SHADOWSHLIGHTS_HLTONALW;Toonomvang +TP_SHADOWSHLIGHTS_LABEL;Schaduwen/hoge lichten +TP_SHADOWSHLIGHTS_LOCALCONTR;Lokaal contrast +TP_SHADOWSHLIGHTS_RADIUS;Straal +TP_SHADOWSHLIGHTS_SHADOWS;Schaduwen +TP_SHADOWSHLIGHTS_SHTONALW;Toonomvang +TP_SHARPENING_AMOUNT;Hoeveelheid +TP_SHARPENING_EDRADIUS;Straal +TP_SHARPENING_EDTOLERANCE;Randtolerantie +TP_SHARPENING_HALOCONTROL;Halocontrole +TP_SHARPENING_HCAMOUNT;Hoeveelheid +TP_SHARPENING_LABEL;Verscherpen +TP_SHARPENING_METHOD;Methode +TP_SHARPENING_ONLYEDGES;Alleen randen verscherpen +TP_SHARPENING_RADIUS;Straal +TP_SHARPENING_RLD_AMOUNT;Hoeveelheid +TP_SHARPENING_RLD_DAMPING;Demping +TP_SHARPENING_RLD_ITERATIONS;Herhaling +TP_SHARPENING_RLD;RL-verscherping +TP_SHARPENING_THRESHOLD;Drempel +TP_SHARPENING_USM;Onscherpmasker +TP_VIGNETTING_AMOUNT;Hoeveelheid +TP_VIGNETTING_LABEL;Corrigeer vignettering +TP_VIGNETTING_RADIUS;Straal +TP_WBALANCE_AUTO;Automatisch +TP_WBALANCE_CAMERA;Camera +TP_WBALANCE_CUSTOM;Handmatig +TP_WBALANCE_GREEN;Groentint +TP_WBALANCE_LABEL;Witbalans +TP_WBALANCE_METHOD;Methode +TP_WBALANCE_SIZE;Grootte: +TP_WBALANCE_SPOTWB;Wijs WB aan +TP_WBALANCE_TEMPERATURE;Kleurtemperatuur +ZOOMBAR_DETAIL;Detailvenster +ZOOMBAR_HUGE;Groter +ZOOMBAR_LARGE;Groot +ZOOMBAR_NORMAL;Normaal +ZOOMBAR_PREVIEW;Afbeelding +ZOOMBAR_SCALE;Schaal +ZOOMBAR_SMALL;Klein + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Norsk BM b/rtdata/languages/Norsk BM new file mode 100644 index 000000000..8d530747a --- /dev/null +++ b/rtdata/languages/Norsk BM @@ -0,0 +1,703 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# 2009-02-12 +# Translated by Esben L. Kristensen +# norwegian translation of RawTherapee +ADJUSTER_RESET_TO_DEFAULT;Tilbake til standard +CURVEEDITOR_FILEDLGFILTERANY;Hvilken som helst fil +CURVEEDITOR_FILEDLGFILTERCURVE;Kurvefiler +CURVEEDITOR_LINEAR;Linjær +CURVEEDITOR_LOADDLGLABEL;Ã…pne kurve... +CURVEEDITOR_SAVEDLGLABEL;Lagre kurve... +CURVEEDITOR_TOOLTIPLINEAR;Nullstil kurve til linjær +CURVEEDITOR_TOOLTIPLOAD;Lagre kurve fra fil +CURVEEDITOR_TOOLTIPSAVE;Lagre nÃ¥værende kurve +EXIFFILTER_APERTURE;Blender +EXIFFILTER_CAMERA;Kamera +EXIFFILTER_DIALOGLABEL;Exif Filter +EXIFFILTER_FOCALLEN;Fokallengde +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objektiv +EXIFFILTER_SHUTTER;Lukker +EXIFPANEL_ADDEDITHINT;Tilføy ny tag eller rediger tag +EXIFPANEL_ADDEDIT;Tilføy/Rediger +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Skriv verdi +EXIFPANEL_ADDTAGDLG_SELECTTAG;Velg tag +EXIFPANEL_ADDTAGDLG_TITLE;Tilføy/Rediger Tag +EXIFPANEL_KEEP;Behold +EXIFPANEL_KEEPHINT;Behold de utvalgte tags nÃ¥r det skrives output fil +EXIFPANEL_REMOVE;Fjern +EXIFPANEL_REMOVEHINT;Fjern de utvalgte tags nÃ¥r det skrives output fil +EXIFPANEL_RESETALLHINT;Nullstil alle tags til de opprinnelige verdier +EXIFPANEL_RESETALL;Nullstil alle +EXIFPANEL_RESETHINT;Nullstil de utvalgte tags til de opprinnelige verdier +EXIFPANEL_RESET;Nullstil +EXIFPANEL_SUBDIRECTORY;Undermappe +FILEBROWSER_APPLYPROFILE;Legg til profil +FILEBROWSER_ARRANGEMENTHINT;Bytt mellom vertikal/horisontal oppstilling av thumbnails +FILEBROWSER_CLEARPROFILE;Slett profil +FILEBROWSER_COPYPROFILE;Kopier profil +FILEBROWSER_DELETEDLGLABEL;Bekreft slett fil +FILEBROWSER_DELETEDLGMSG;Vil du slette valgte %1 filer? +FILEBROWSER_EMPTYTRASHHINT;Tøm søpla permanent +FILEBROWSER_EMPTYTRASH;Tøm søpla +FILEBROWSER_EXIFFILTERAPPLYHINT;Skru pÃ¥/av exif filter i filleseren +FILEBROWSER_EXIFFILTERAPPLY;Legg til +FILEBROWSER_EXIFFILTERLABEL;Exif Filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Forandre opsettet i exif filteret +FILEBROWSER_EXIFFILTERSETTINGS;Oppsett +FILEBROWSER_PARTIALPASTEPROFILE;Delvis lim inn +FILEBROWSER_PASTEPROFILE;Lim inn profil +FILEBROWSER_POPUPCANCELJOB;Avbryt jobben +FILEBROWSER_POPUPMOVEEND;Flytt til enden av køen +FILEBROWSER_POPUPMOVEHEAD;Flytt til begynnelsen av køen +FILEBROWSER_POPUPOPEN;Ã…pne +FILEBROWSER_POPUPPROCESS;Legg til i prosesseringskøen +FILEBROWSER_POPUPRANK1;Rang 1 +FILEBROWSER_POPUPRANK2;Rang 2 +FILEBROWSER_POPUPRANK3;Rang 3 +FILEBROWSER_POPUPRANK4;Rang 4 +FILEBROWSER_POPUPRANK5;Rang 5 +FILEBROWSER_POPUPREMOVE;Fjern fra filsystem +FILEBROWSER_POPUPRENAME;Skift navn +FILEBROWSER_POPUPSELECTALL;Velg alt +FILEBROWSER_POPUPTRASH;Flytt til søpla +FILEBROWSER_POPUPUNRANK;Fjern rangering +FILEBROWSER_POPUPUNTRASH;Fjern fra søpla +FILEBROWSER_PROCESSINGSETTINGSHINT;Sett filformat og folderbane +FILEBROWSER_PROCESSINGSETTINGS;Innstillinger +FILEBROWSER_RENAMEDLGLABEL;Bytt filnavn +FILEBROWSER_RENAMEDLGMSG;Bytt filnavn "%1" til: +FILEBROWSER_SHOWDIRHINT;Vis alle bildene i folderen +FILEBROWSER_SHOWQUEUEHINT;Vis innholdet i prosesseringskøen +FILEBROWSER_SHOWRANK1HINT;Vis bilder rangert med 1 stjerne +FILEBROWSER_SHOWRANK2HINT;Vis bilder rangert med 2 stjerne +FILEBROWSER_SHOWRANK3HINT;Vis bilder rangert med 3 stjerne +FILEBROWSER_SHOWRANK4HINT;Vis bilder rangert med 4 stjerne +FILEBROWSER_SHOWRANK5HINT;Vis bilder rangert med 5 stjerne +FILEBROWSER_SHOWTRASHHINT;Vis innholdet i søpla +FILEBROWSER_SHOWUNRANKHINT;Vis unrangerte bilder +FILEBROWSER_STARTPROCESSINGHINT;Begynn prosessering/lagring av bilder i køen +FILEBROWSER_STARTPROCESSING;Start Processing +FILEBROWSER_STOPPROCESSINGHINT;Stopp prosesseringen av bilder +FILEBROWSER_STOPPROCESSING;Stopp prosesseringen +FILEBROWSER_THUMBSIZE;Thumbnail størrelse +FILEBROWSER_ZOOMINHINT;Øk thumbnail størrelse +FILEBROWSER_ZOOMOUTHINT;Reduser thumbnail størrelse +GENERAL_ABOUT;Om +GENERAL_CANCEL;Annuller +GENERAL_DISABLED;Deaktivert +GENERAL_DISABLE;Deaktiver +GENERAL_ENABLE;Aktiver +GENERAL_ENABLED;Aktivert +GENERAL_LANDSCAPE;Landskap +GENERAL_LOAD;Ã…pne +GENERAL_NA;n/a +GENERAL_NO;Nei +GENERAL_OK;Ok +GENERAL_PORTRAIT;Portrett +GENERAL_SAVE;Lagre +GENERAL_YES;Ja +HISTOGRAM_LABEL;Histogram +HISTOGRAM_TOOLTIP_B;Vis/skjul blÃ¥tt histogram +HISTOGRAM_TOOLTIP_G;Vis/skjul grønt histogram +HISTOGRAM_TOOLTIP_L;Vis/skjul CIELAB Luminans histogram +HISTOGRAM_TOOLTIP_R;Vis/skjul rødt histogram +HISTORY_CHANGED;Forandret +HISTORY_CUSTOMCURVE;Egen kurve +HISTORY_DELSNAPSHOT;Fjern b.m +HISTORY_FROMCLIPBOARD;Fra utklippstavlen +HISTORY_LABEL;Historikk +HISTORY_MSG_10;Skyggekomprimering +HISTORY_MSG_11;Tonekurve +HISTORY_MSG_12;Autoeksponering +HISTORY_MSG_13;Eksponeringsmarkering +HISTORY_MSG_14;Luminanslysstyrke +HISTORY_MSG_15;Luminanskontrast +HISTORY_MSG_16;Sort luminans +HISTORY_MSG_17;Luminans høylys kompr. +HISTORY_MSG_18;Luminans skygge kompr. +HISTORY_MSG_19;Luminanskurve +HISTORY_MSG_1;Foto Ã¥pnet +HISTORY_MSG_20;Skarphet +HISTORY_MSG_21;Skarphetsradius +HISTORY_MSG_22;Skarphetsmengde +HISTORY_MSG_23;Skarphetsterskelverdi +HISTORY_MSG_24;Skarphet kun i kanter +HISTORY_MSG_25;Kanttegningsradie-skarphet +HISTORY_MSG_26;Kantskarphetstoleranse +HISTORY_MSG_27;Halo-skarphetsskontroll +HISTORY_MSG_28;Halo-kontrollstørrelse +HISTORY_MSG_29;Skarphetsmetode +HISTORY_MSG_2;Profil Ã¥pnet +HISTORY_MSG_30;Deconvolution-radius +HISTORY_MSG_31;Deconvolution-størrelse +HISTORY_MSG_32;Deconvolution-dempning +HISTORY_MSG_33;Deconvolution-gjentakelse +HISTORY_MSG_34;UnngÃ¥ fargemarkeringer +HISTORY_MSG_35;Metthetsbegrensning +HISTORY_MSG_36;Methetsgrense +HISTORY_MSG_37;Fargeforsterkning +HISTORY_MSG_38;Hvitbalansemetode +HISTORY_MSG_39;Fargetemperatur +HISTORY_MSG_3;Profil endret +HISTORY_MSG_40;Hvitbalansenyanse +HISTORY_MSG_41;Fargeskift "A" +HISTORY_MSG_42;Fargeskift "B" +HISTORY_MSG_43;Luminans støyreduksjon +HISTORY_MSG_44;Lum. støyreduksjon-radius +HISTORY_MSG_45;Lum. støyreduksjon kanttoleranse +HISTORY_MSG_46;Fargestøyreduksjon +HISTORY_MSG_47;Fargestøyreduksjon-radius +HISTORY_MSG_48;Fargestøjreduktion-kanttoleranse +HISTORY_MSG_49;Kantfølsom fargestøyreduksjon +HISTORY_MSG_4;Historikk-gjennomsyn +HISTORY_MSG_50;Skygge/høylys verktøy +HISTORY_MSG_51;Høylys-forsterkning +HISTORY_MSG_52;Skyggeforsterkning +HISTORY_MSG_53;Høylys-tonvidde +HISTORY_MSG_54;Skygge-tonevidde +HISTORY_MSG_55;Lokal kontrast +HISTORY_MSG_56;Skygge/høylys -radius +HISTORY_MSG_57;Enkel rotasjon +HISTORY_MSG_58;Vend horisontalt +HISTORY_MSG_59;Vend vertikalt +HISTORY_MSG_5;Lysstyrke +HISTORY_MSG_60;Rotasjon +HISTORY_MSG_61;Rotasjon +HISTORY_MSG_62;Objektivforvrengning-korrigering +HISTORY_MSG_63;Valgt bokmerke +HISTORY_MSG_64;Beskjær foto +HISTORY_MSG_65;C/A korrigering +HISTORY_MSG_66;Høylys-forbedring +HISTORY_MSG_67;Høylys-forbedringsstyrke +HISTORY_MSG_68;Høylys-forbedringsmetode +HISTORY_MSG_69;Arbeidsfargerom +HISTORY_MSG_6;Kontrast +HISTORY_MSG_70;Utgangssfargerom +HISTORY_MSG_71;Inngangsfargerom +HISTORY_MSG_72;Vignettering-korrigering +HISTORY_MSG_73;Kanalmikser +HISTORY_MSG_74;Endre størrelsesskala +HISTORY_MSG_75;Endre størrelses metode +HISTORY_MSG_76;Exif Metadata +HISTORY_MSG_77;IPTC Metadata +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;Sort +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;Eksponerings-komprimering +HISTORY_MSG_9;Høylys-komprimering +HISTORY_NEWSNAPSHOTAS;Som... +HISTORY_NEWSNAPSHOT;Nytt b.m +HISTORY_NEWSSDIALOGLABEL;Navn pÃ¥ bokmerket: +HISTORY_NEWSSDIALOGTITLE;Opprett nytt bogmerke +HISTORY_SETTO;Inntil +HISTORY_SNAPSHOT;Bokmerke +HISTORY_SNAPSHOTS;Bokmerker +ICMPANEL_FILEDLGFILTERANY;Alle filer +ICMPANEL_FILEDLGFILTERICM;ICC profilfiler +ICMPANEL_GAMMABEFOREINPUT;Profilen tilføyer Gamma +ICMPANEL_INPUTCAMERA;Kameravalg +ICMPANEL_INPUTCUSTOM;Egen +ICMPANEL_INPUTDLGLABEL;Velg inngangs ICC-profil... +ICMPANEL_INPUTEMBEDDED;Anvend intern, hvis mulig +ICMPANEL_INPUTPROFILE;Inngangprofil +ICMPANEL_NOICM;Ingen ICM: sRGB-profil +ICMPANEL_OUTPUTDLGLABEL;Velg utgangs ICC-profil... +ICMPANEL_OUTPUTPROFILE;Utgangsprofil +ICMPANEL_SAVEREFERENCE;Lagre referansebilde til profil +ICMPANEL_WORKINGPROFILE;Arbeidsprofil +IMAGEAREA_DETAILVIEW;Detaljert +IPTCPANEL_AUTHORHINT;Navnet pÃ¥ oppretteren, f.eks. forfatter, fotograf eller grafiker (By-line). +IPTCPANEL_AUTHOR;Oppretter +IPTCPANEL_AUTHORSPOSITIONHINT;Beskrivelse av oppretterens tittel (By-line Title). +IPTCPANEL_AUTHORSPOSITION;Oppretterens tittel +IPTCPANEL_CAPTION;Billdetekst +IPTCPANEL_CAPTIONHINT;Tekstbeskrivelse av bildets innhold (Caption - Abstract). +IPTCPANEL_CAPTIONWRITER;Bildetekst forfatter +IPTCPANEL_CAPTIONWRITERHINT;Navnet pÃ¥ personen som har opprettet, redigert eller korrigeret bildeteksten (Writer - Editor). +IPTCPANEL_CATEGORYHINT;Brukes til Ã¥ beskrive innholdet i bildet ifølge kategorien (Category). +IPTCPANEL_CATEGORY;Kategori +IPTCPANEL_CITY;By +IPTCPANEL_CITYHINT;Bildets opprinnelsesby (City). +IPTCPANEL_COPYHINT;Kopier IPTC innstillinger til utklippstavlen +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COPYRIGHTHINT;Eventuelle copyright tilføyelser (Copyright Notice). +IPTCPANEL_COUNTRYHINT;Navnet pÃ¥ landet/primære omrÃ¥de hvor bildet er tatt (Country - Primary Location Name). +IPTCPANEL_COUNTRY;Land +IPTCPANEL_CREDITHINT;Identifisere oppretteren av bildet, ikke nødvendivis den samme som eieren (Credit). +IPTCPANEL_CREDIT;Kreditering +IPTCPANEL_DATECREATEDHINT;Datoen bildet ble tatt; Format: JJJJMMTT (Date Created). +IPTCPANEL_DATECREATED;Opptakelsesdato +IPTCPANEL_EMBEDDEDHINT;Nullstil til de IPTC data som finnes internt i bildefilen +IPTCPANEL_EMBEDDED;Intern IPTC data +IPTCPANEL_HEADLINEHINT;En kort beskrivelse av innholdet av bildet (Headline). +IPTCPANEL_HEADLINE;Overskrift +IPTCPANEL_INSTRUCTIONSHINT;Andre instuksjoner som omhandler bruken av bildet (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Instruksjoner +IPTCPANEL_KEYWORDSHINT;Brukes til Ã¥ beskrive spesifikke nøkkelord (Keywords). +IPTCPANEL_KEYWORDS;Nøkkelord +IPTCPANEL_PASTEHINT;Innsett IPTC innstillinger fra utklipstavlen +IPTCPANEL_PROVINCEHINT;Billedets opprinnelsesprovins/-stat (Province-State). +IPTCPANEL_PROVINCE;Provins +IPTCPANEL_RESETHINT;Nullstil til standard profil +IPTCPANEL_RESET;Nullstil +IPTCPANEL_SOURCEHINT;Den originale eier af bildets innhold (Source). +IPTCPANEL_SOURCE;Kilde +IPTCPANEL_SUPPCATEGORIESHINT;Ytterlige beskrivelser av innholdet i bildet (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Suppl. kategorier +IPTCPANEL_TITLE;Bildetittel +IPTCPANEL_TITLEHINT;En kort beskrivelse av bildet (Object Name). +IPTCPANEL_TRANSREFERENCEHINT;En kode som representerer stedet for original transmisjon (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Trans. Reference +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Innstillinger +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;Som... +MAIN_BUTTON_SAVE;Lagre bilde +MAIN_BUTTON_SENDTOEDITOR;Send til editor +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Filen eksisterer allerede. +MAIN_MSG_CANNOTLOAD;Kan ikke Ã¥pne bildet +MAIN_MSG_CANNOTSAVE;Kan ikke lagre +MAIN_MSG_CANNOTSTARTEDITOR;Kan ikke starte editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Vennligst sett korrekt bane i "Innstillinger" dialogen. +MAIN_MSG_EXITJOBSINQUEUEINFO;Uprosesserte bilder i køen vil bli tapt ved avslutning. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Vil du avslutte? Det er uprosesserte bilder i køen. +MAIN_MSG_JOBSINQUEUE;Arbeidet settes i kø +MAIN_MSG_QOVERWRITE;Vil du overskrive? +MAIN_TAB_BASIC;Grunnleggende +MAIN_TAB_COLOR;Farge +MAIN_TAB_DETAIL;Detailj +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Eksponering +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Endre +MAIN_TOOLTIP_HIDEFP;Vis/skjul nederste panel (Mapper og Filgjennomsyn, shortcut key: F) +MAIN_TOOLTIP_HIDEHP;Vis/skjul venstre panel (Inneholder historikken shortcut key: H) +MAIN_TOOLTIP_INDCLIPPEDH;Marker høylys-indikering +MAIN_TOOLTIP_INDCLIPPEDS;Marker skygge-indikering +MAIN_TOOLTIP_PREFERENCES;Endre innstillinger +MAIN_TOOLTIP_QINFO;Hurtig informasjon om bildet +MAIN_TOOLTIP_SAVEAS;Lagre bildet i en annen mappe +MAIN_TOOLTIP_SAVE;Lagre bildet i standardmappen +PARTIALPASTE_BASICGROUP;Basisinnstillinger +PARTIALPASTE_CACORRECTION;C/A korreksjon +PARTIALPASTE_COARSETRANS;90° rotasjon/flipping +PARTIALPASTE_COLORBOOST;Fargeforsterkning +PARTIALPASTE_COLORDENOISE;Fargestøyreduksjon +PARTIALPASTE_COLORGROUP;Fargerelaterte innstillinger +PARTIALPASTE_COLORMIXER;Farge mikser +PARTIALPASTE_COLORSHIFT;Fargeskift +PARTIALPASTE_COMPOSITIONGROUP;Komposisjonsinnstillinger +PARTIALPASTE_CROP;Utsnitt +PARTIALPASTE_DIALOGLABEL;Delvis innliming av prosesseringsprofil +PARTIALPASTE_DISTORTION;Forvrengningskorreksjon +PARTIALPASTE_EXIFCHANGES;Forandringer i exif data +PARTIALPASTE_EXPOSURE;Exponering +PARTIALPASTE_HLRECOVERY;Highlight recovery +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Objektivrelaterte innstillinger +PARTIALPASTE_LUMACURVE;Luminanskurve +PARTIALPASTE_LUMADENOISE;Luminansstøyreduksjon +PARTIALPASTE_LUMINANCEGROUP;Luminansrelaterte innstillinger +PARTIALPASTE_METAICMGROUP;Metadata/ICM innstillinger +PARTIALPASTE_RESIZE;Forandre størrelse +PARTIALPASTE_ROTATION;Rotasjon +PARTIALPASTE_SHADOWSHIGHLIGHTS;Skygger/Høylys +PARTIALPASTE_SHARPENING;Oppskarping +PARTIALPASTE_VIGNETTING;Vignetteringskorreksjon +PARTIALPASTE_WHITEBALANCE;Hvitbalanse +PREFERENCES_APPLNEXTSTARTUP;Endres ved neste oppstart +PREFERENCES_BLINKCLIPPED;Vis merkede omrÃ¥der +PREFERENCES_CACHECLEARALL;Slett alle +PREFERENCES_CACHECLEARPROFILES;Slett profiler +PREFERENCES_CACHECLEARTHUMBS;Slett thumbnails +PREFERENCES_CACHEFORMAT1;Proprietært (Raskere og bedre kvalitet) +PREFERENCES_CACHEFORMAT2;JPEG (Mindre filstørrelse) +PREFERENCES_CACHEMAXENTRIES;Maksimalt antall cache oppføringer +PREFERENCES_CACHEOPTS;Cache innstillinger +PREFERENCES_CACHESTRAT1;Prioriter hastighet fremfor lavt minneforbruk +PREFERENCES_CACHESTRAT2;Prioriter lavt minneforbruk fremfor hastighet +PREFERENCES_CACHESTRAT;Cache strategi +PREFERENCES_CACHETHUMBFORM;Cache thumbnail format +PREFERENCES_CACHETHUMBHEIGHT;Maksimal Thumbnail Høyde +PREFERENCES_CLEARDLG_LINE1;Sletter cache +PREFERENCES_CLEARDLG_LINE2;Dette kan ta sin tid.. +PREFERENCES_CLEARDLG_TITLE;Vennligst vent +PREFERENCES_CLIPPINGIND;Markerings-indikasjon +PREFERENCES_CMETRICINTENT;Kolorimetrisk Inntrykk +PREFERENCES_DATEFORMAT;Datoformat +PREFERENCES_DATEFORMATHINT;Du kan bruke følgende formattering:\n%y : Ã¥r\n%m : mÃ¥ned\n%d : dag\n\nF. eks. er ungarsk datoformat:\n%y/%m/%d +PREFERENCES_DEFAULTLANG;ProgramsprÃ¥k +PREFERENCES_DEFAULTTHEME;Standard tema +PREFERENCES_DEMOSAICINGALGO;Demosaikking Algoritme +PREFERENCES_DIRHOME;Hjemmemappe +PREFERENCES_DIRLAST;Sidste besøkte mappe +PREFERENCES_DIROTHER;Annen +PREFERENCES_DIRSELECTDLG;Velg bildemappe ved oppstart... +PREFERENCES_DIRSOFTWARE;Installasjons-mappe +PREFERENCES_DMETHOD;Metode +PREFERENCES_EDITORCMDLINE;Annen kommandolinje +PREFERENCES_EXTERNALEDITOR;Ekstern editor +PREFERENCES_FALSECOLOR;Falsk fargefortrengningsverdi +PREFERENCES_FBROWSEROPTS;Filfremviser-innstillinger +PREFERENCES_FILEFORMAT;Filformat +PREFERENCES_FORIMAGE;For bildefiler +PREFERENCES_FORRAW;For RAW-filer +PREFERENCES_GIMPPATH;GIMP installasjonsmappe +PREFERENCES_GTKTHEME;GTK standard +PREFERENCES_HINT;Tips +PREFERENCES_HLTHRESHOLD;Terskelverdi for markerte høylys +PREFERENCES_ICCDIR;Mappe til ICC-profiler +PREFERENCES_IMPROCPARAMS;Standard-bildebehandlingsparametre +PREFERENCES_INTENT_ABSOLUTE;Total kolorimetri +PREFERENCES_INTENT_PERCEPTUAL;Oppfattet kolorimetri +PREFERENCES_INTENT_RELATIVE;Relativ kolorimetri +PREFERENCES_INTENT_SATURATION;Metning +PREFERENCES_LIVETHUMBNAILS;Live Thumbnails (tregere) +PREFERENCES_MONITORICC;Skjermprofil +PREFERENCES_OUTDIRFOLDERHINT;Send lagrede bilder til valgt folder +PREFERENCES_OUTDIRFOLDER;Lagre til folder +PREFERENCES_OUTDIRHINT;Du kan bruke følgende formattering:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nFormateringsstrengene refererer til folderne og understier av stien til RAW-filen.\n\nF. eks., hvis /home/tom/image/02-09-2006/dsc0012.nefhar vært Ã¥pnet, vil det bety at formateringsstrengen er:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nHvis du vil lagre det prosesserte bildet der originalen er, skriv:\n%p1/%f\n\nHvis du vil lagre det prosesserte bildet i folderen 'converted' under inni originalfolderen, skriv:\n%p1/converted/%f\n\nHvis du vil lagre det prosesserte bildet i '/home/tom/converted' men beholde underfolderens datomerking, skriv:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Bruk mal +PREFERENCES_OUTDIRTEMPLATEHINT;Du kan bruke følgende formattering:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nFormateringsstrengene refererer til folderne og understier av stien til RAW-filen.\n\nF. eks., hvis /home/tom/image/02-09-2006/dsc0012.nefhar vært Ã¥pnet, vil det bety at formateringsstrengen er:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nvis du vil lagre det prosesserte bildet der originalen er, skriv:\n%p1/%f\n\nHvis du vil lagre det prosesserte bildet i folderen 'converted' under inni originalfolderen, skriv:\n%p1/converted/%f\n\nHvis du vil lagre det prosesserte bildet i '/home/tom/converted' men beholde underfolderens datomerking, skriv:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIR;Utmappe +PREFERENCES_PARSEDEXTADDHINT;Skriv inn en utvidelse og trykk pÃ¥ kanppen for Ã¥ legge til listen +PREFERENCES_PARSEDEXTADD;Legg til utvidelse +PREFERENCES_PARSEDEXT;Analyserte utvidelser +PREFERENCES_PARSEDEXTDELHINT;Fjern valgte utvidelse fra listen +PREFERENCES_PROFILEHANDLING;Prosesserer filbehandling +PREFERENCES_PROFILELOADPR;Profillastingsprioritet +PREFERENCES_PROFILEPRCACHE;Profil i Cache +PREFERENCES_PROFILEPRFILE;Profil i innfilen +PREFERENCES_PROFILESAVECACHE;Lagre prosesseringsparametre til cachen +PREFERENCES_PROFILESAVEINPUT;Lagre prosesseringsparametre i innfilen +PREFERENCES_PSPATH;Adobe Photoshop installasjonsfolder +PREFERENCES_SELECTICCDIRDLG;Velg ICC-profil mappe... +PREFERENCES_SELECTLANG;Velg sprÃ¥k +PREFERENCES_SELECTMONITORPROFDLG;Velg ICC-profil til skjermen... +PREFERENCES_SELECTTHEME;Velg tema +PREFERENCES_SHOWBASICEXIF;Vis utvidet Exif-informasjon +PREFERENCES_SHOWDATETIME;Vis dato og tid +PREFERENCES_SHOWONLYRAW;Vis kun RAW-filer +PREFERENCES_SHTHRESHOLD;Terskelverdi for markerte skygger +PREFERENCES_STARTUPIMDIR;Bildemappe som vises ved oppstart +PREFERENCES_TAB_BROWSER;Filfremviser +PREFERENCES_TAB_COLORMGR;FargehÃ¥ndtering +PREFERENCES_TAB_GENERAL;Generelt +PREFERENCES_TAB_IMPROC;Bildebehandling +PREFERENCES_TAB_OUTPUT;Utfilindtillinger +PREFERENCES_THUMBSIZE;Miniatyrebildestørrelse +PROFILEPANEL_FILEDLGFILTERANY;Alle filer +PROFILEPANEL_FILEDLGFILTERPP;Bildebehandlingsprofiler +PROFILEPANEL_LABEL;Bildebehandlingsprofiler +PROFILEPANEL_LOADDLGLABEL;Ã…pne bildebehandlingsparametre... +PROFILEPANEL_PCUSTOM;Egen +PROFILEPANEL_PFILE;Fra fil +PROFILEPANEL_PLASTPHOTO;Seneste foto +PROFILEPANEL_PLASTSAVED;Seneste lagret +PROFILEPANEL_PROFILE;Profil +PROFILEPANEL_SAVEDLGLABEL;Lagre bildebehandlingsparametre... +PROFILEPANEL_TOOLTIPCOPY;Kopier gjeldende profil til utklippstavlen +PROFILEPANEL_TOOLTIPLOAD;Ã…pne profil fra fil +PROFILEPANEL_TOOLTIPPASTE; Lim inn profil fra utklippstavlen +PROFILEPANEL_TOOLTIPSAVE;Lagre nÃ¥værende profil +PROGRESSBAR_DECODING;Dekod Raw-fil... +PROGRESSBAR_DEMOSAICING;Demosaikker... +PROGRESSBAR_LOADING;Ã…pner bilde... +PROGRESSBAR_LOADJPEG;Ã…pner JPEG-fil... +PROGRESSBAR_LOADPNG;Ã…pner PNG-fil... +PROGRESSBAR_LOADTIFF;Ã…pner TIFF-fil... +PROGRESSBAR_PROCESSING;Bearbeider Bilde... +PROGRESSBAR_READY;Klar. +PROGRESSBAR_SAVEJPEG;Lagre JPEG-fil... +PROGRESSBAR_SAVEPNG;Lagre PNG-fil... +PROGRESSBAR_SAVETIFF;Lagre TIFF-fil... +PROGRESSDLG_LOADING;Laster fil... +PROGRESSDLG_PROCESSING;Prosesserer bilde... +PROGRESSDLG_SAVING;Lagrer fil... +QINFO_FOCALLENGTH;Brennvidde +QINFO_ISO;ISO +QINFO_LENS;Objektiv +QINFO_NOEXIF;Exifdata utilgjengelig. +SAVEDLG_FILEFORMAT;Filformat +SAVEDLG_JPEGQUAL;JPEG-kvalitet +SAVEDLG_JPGFILTER;JPEG-filter +SAVEDLG_PNGCOMPR;PNG-komprimering +SAVEDLG_PNGFILTER;PNG-filter +SAVEDLG_PUTTOQUEUEHEAD;Sett øverst i prosesseringskøen +SAVEDLG_PUTTOQUEUE;Sett i prosesseringskø +SAVEDLG_PUTTOQUEUETAIL;Sett nederst i prosesseringskøen +SAVEDLG_SAVEIMMEDIATELY;Lagre med en gang +SAVEDLG_SAVESPP;Lagre bildebehandlingsparametre med bildene +SAVEDLG_TIFFFILTER;TIFF-filter +TOOLBAR_TOOLTIP_CROP;Velg beskjæringsomrÃ¥de (shortcut key: C) +TOOLBAR_TOOLTIP_HAND;HÃ¥ndverktøy (shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Rett opp (shortcut key: S) +TOOLBAR_TOOLTIP_WB;Punkt-hvitbalanse (shortcut key: W) +TP_CACORRECTION_BLUE;BlÃ¥ +TP_CACORRECTION_LABEL;C/A justering +TP_CACORRECTION_RED;Rød +TP_CHMIXER_BLUE;BlÃ¥ +TP_CHMIXER_GREEN;Grønn +TP_CHMIXER_LABEL;Kanalmikser +TP_CHMIXER_RED;Rød +TP_COARSETRAF_DEGREE;grad: +TP_COARSETRAF_TOOLTIP_HFLIP;Vend horisontalt +TP_COARSETRAF_TOOLTIP_ROTLEFT;Roter mot venstre +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Roter mot høyre +TP_COARSETRAF_TOOLTIP_VFLIP;Vend vertikalt +TP_COLORBOOST_ACHANNEL;kanal "a" +TP_COLORBOOST_AMOUNT;Mengde +TP_COLORBOOST_AVOIDCOLORCLIP;UnngÃ¥ fargeklipping +TP_COLORBOOST_BCHANNEL;kanal "b" +TP_COLORBOOST_CHAB;a & b +TP_COLORBOOST_CHANNEL;Kanal +TP_COLORBOOST_CHSEPARATE;separat +TP_COLORBOOST_ENABLESATLIMITER;Metningsgrense +TP_COLORBOOST_LABEL;Fargeforsterkning +TP_COLORBOOST_SATLIMIT;Metningsgrense +TP_COLORDENOISE_EDGESENSITIVE;Kantfølsomhet +TP_COLORDENOISE_EDGETOLERANCE;Kanttoleranse +TP_COLORDENOISE_LABEL;Farvestøyreduksjon +TP_COLORDENOISE_RADIUS;Radius +TP_COLORSHIFT_BLUEYELLOW;BlÃ¥-Gul +TP_COLORSHIFT_GREENMAGENTA;Grønn-Magenta +TP_COLORSHIFT_LABEL;Fargeskift +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Fast proporsjon +TP_CROP_GTDIAGONALS;Diagonalreglen +TP_CROP_GTHARMMEANS1;Harmonisk metode 1 +TP_CROP_GTHARMMEANS2;Harmonisk metode 2 +TP_CROP_GTHARMMEANS3;Harmonisk metode 3 +TP_CROP_GTHARMMEANS4;Harmonisk metode 4 +TP_CROP_GTNONE;Ingen +TP_CROP_GTRULETHIRDS;Tredjedelsreglen +TP_CROP_GUIDETYPE;Guidetype: +TP_CROP_H;H +TP_CROP_LABEL;Beskjæring +TP_CROP_SELECTCROP;Velg beskjæringsomrÃ¥de +TP_CROP_W;B +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Mengde +TP_DISTORTION_LABEL;Forvrengning +TP_EXPOSURE_AUTOLEVELS;Auto nivÃ¥ +TP_EXPOSURE_BLACKLEVEL;Sort +TP_EXPOSURE_BRIGHTNESS;Lysstyrke +TP_EXPOSURE_CLIP;Klipp +TP_EXPOSURE_COMPRHIGHLIGHTS;Høylyskomprimering +TP_EXPOSURE_COMPRSHADOWS;Skyggekomprimering +TP_EXPOSURE_CONTRAST;Kontrast +TP_EXPOSURE_CURVEEDITOR;Tonekurve +TP_EXPOSURE_EXPCOMP;Eks. Komp. +TP_EXPOSURE_LABEL;Eksponering +TP_HLREC_CIELAB;CIELab Blending +TP_HLREC_COLOR;Fargespedning +TP_HLREC_LABEL;Høylys-forbedring +TP_HLREC_LUMINANCE;Forbedring av luminans +TP_HLREC_METHOD;Metode: +TP_ICM_FILEDLGFILTERANY;Alle filer +TP_ICM_FILEDLGFILTERICM;ICC profilfiler +TP_ICM_GAMMABEFOREINPUT;Profilen tilføyer Gamma +TP_ICM_INPUTCAMERA;Kameravalg +TP_ICM_INPUTCUSTOM;Egen +TP_ICM_INPUTDLGLABEL;Velg indgangs ICC-profil... +TP_ICM_INPUTEMBEDDED;Anvend intern, hvis mulig +TP_ICM_INPUTPROFILE;Inngangprofil +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Ingen ICM: sRGB-profil +TP_ICM_OUTPUTDLGLABEL;Select Velg utgangs ICC-profil... +TP_ICM_OUTPUTPROFILE;Utgangsprofil +TP_ICM_SAVEREFERENCE;Lagre referansebilde til profil +TP_ICM_WORKINGPROFILE;Arbeidsprofil +TP_LUMACURVE_BLACKLEVEL;Sort +TP_LUMACURVE_BRIGHTNESS;Lysstyrke +TP_LUMACURVE_COMPRHIGHLIGHTS;Høylyskomprimering +TP_LUMACURVE_COMPRSHADOWS;Skyggekomprimering +TP_LUMACURVE_CONTRAST;Kontrast +TP_LUMACURVE_CURVEEDITOR;Luminanskurve +TP_LUMACURVE_LABEL;Luminanskurve +TP_LUMADENOISE_EDGETOLERANCE;Kanttoleranse +TP_LUMADENOISE_LABEL;Luminans-støyredusering +TP_LUMADENOISE_RADIUS;Radius +TP_RESIZE_BICUBIC;Bikubisk +TP_RESIZE_BICUBICSF;Bikubisk (Bløtere) +TP_RESIZE_BICUBICSH;Bikubisk (Skarpere) +TP_RESIZE_BILINEAR;Bilinjær +TP_RESIZE_FULLSIZE;Bildestørrelse: +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Endre størrelse +TP_RESIZE_METHOD;Metode: +TP_RESIZE_NEAREST;Nærmeste +TP_RESIZE_SCALE;Skala +TP_RESIZE_W;B: +TP_ROTATE_AUTOCROP;Autobeskjæring +TP_ROTATE_DEGREE;Antall grader +TP_ROTATE_FILL;Fyll +TP_ROTATE_LABEL;Rett opp +TP_ROTATE_SELECTLINE;Velg rett linje +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Høylys +TP_SHADOWSHLIGHTS_HLTONALW;Toneomfang +TP_SHADOWSHLIGHTS_LABEL;Skygger/høylys +TP_SHADOWSHLIGHTS_LOCALCONTR;Lokal kontrast +TP_SHADOWSHLIGHTS_RADIUS;Radius +TP_SHADOWSHLIGHTS_SHADOWS;Skygger +TP_SHADOWSHLIGHTS_SHTONALW;Toneomfang +TP_SHARPENING_AMOUNT;Mengde +TP_SHARPENING_EDRADIUS;Radius +TP_SHARPENING_EDTOLERANCE;Kanttoleranse +TP_SHARPENING_HALOCONTROL;Halo-kontroll +TP_SHARPENING_HCAMOUNT;Mengde +TP_SHARPENING_LABEL;Skarphet +TP_SHARPENING_METHOD;Metode +TP_SHARPENING_ONLYEDGES;Skarphet kun i kanter +TP_SHARPENING_RADIUS;Radius +TP_SHARPENING_RLD_AMOUNT;Mengde +TP_SHARPENING_RLD_DAMPING;Demping +TP_SHARPENING_RLD_ITERATIONS;Gjentakelse +TP_SHARPENING_RLD;RL Dekonvolusjon +TP_SHARPENING_THRESHOLD;Terskelverdi +TP_SHARPENING_USM;Uskarp maske +TP_VIGNETTING_AMOUNT;Mengde +TP_VIGNETTING_LABEL;Vignetterings-korrigering +TP_VIGNETTING_RADIUS;Radius +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Kamera +TP_WBALANCE_CUSTOM;Egen +TP_WBALANCE_GREEN;Nyanse +TP_WBALANCE_LABEL;Hvitbalanse +TP_WBALANCE_METHOD;Metode +TP_WBALANCE_SIZE;Størrelse: +TP_WBALANCE_SPOTWB;Punkt HB +TP_WBALANCE_TEMPERATURE;Temperatur +ZOOMBAR_DETAIL;Lupe +ZOOMBAR_HUGE;Ekstra stor +ZOOMBAR_LARGE;Stor +ZOOMBAR_NORMAL;Normal +ZOOMBAR_PREVIEW;Filgjennomsyn +ZOOMBAR_SCALE;Skala +ZOOMBAR_SMALL;Liten + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish new file mode 100644 index 000000000..086a3356e --- /dev/null +++ b/rtdata/languages/Polish @@ -0,0 +1,708 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# polish version +# 24.12.2007 +# Mateusz Ludwin +# ----------------------------- +# 08.01.2010 +# Initial update for 3.0 release +# Bartosz "Simek" Kaszubowski +# +ADJUSTER_RESET_TO_DEFAULT;Przywróć domyÅ›lne +CURVEEDITOR_FILEDLGFILTERANY;Wszystkie pliki +CURVEEDITOR_FILEDLGFILTERCURVE;Pliki z krzywymi +CURVEEDITOR_LINEAR;Liniowa +CURVEEDITOR_LOADDLGLABEL;Wczytaj krzywÄ…... +CURVEEDITOR_SAVEDLGLABEL;Zapisz krzywÄ…... +CURVEEDITOR_TOOLTIPLINEAR;Zresetuj krzywÄ… do liniowej +CURVEEDITOR_TOOLTIPLOAD;Wczytaj krzywÄ… z pliku +CURVEEDITOR_TOOLTIPSAVE;Zapisz aktualnÄ… krzywÄ… +EXIFFILTER_APERTURE;PrzesÅ‚ona +EXIFFILTER_CAMERA;Aparat +EXIFFILTER_DIALOGLABEL;Filrt Exif +EXIFFILTER_FOCALLEN;Wartość ogniskowej +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Obiektyw +EXIFFILTER_SHUTTER;Migawka +EXIFPANEL_ADDEDIT;Dodaj/Edytuj +EXIFPANEL_ADDEDITHINT;Dodaj nowÄ… etykietÄ™ lub edytuj etykietÄ™ +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Wpisz wartość +EXIFPANEL_ADDTAGDLG_SELECTTAG;Wybierz etykietÄ™ +EXIFPANEL_ADDTAGDLG_TITLE;Dodaj/Edytuj etykietÄ™ +EXIFPANEL_KEEPHINT;ZapamiÄ™taj wybrane etykiety podczas zapisywania pliku wyjÅ›ciowego +EXIFPANEL_KEEP;ZapamiÄ™taj +EXIFPANEL_REMOVEHINT;UsuÅ„ wybrane etykiety podczas zapisywania pliku wyjÅ›ciowego +EXIFPANEL_REMOVE;UsuÅ„ +EXIFPANEL_RESETALLHINT;Przywróć wszystkie etykiety do ich oryginalnych wartoÅ›ci +EXIFPANEL_RESETALL;Przywróć wszystkie +EXIFPANEL_RESETHINT;Przywróć wybrane etykiety do ich oryginalnych wartoÅ›ci +EXIFPANEL_RESET;Przywróć +EXIFPANEL_SUBDIRECTORY;Podkatalog +FILEBROWSER_APPLYPROFILE;Zastosuj profil +FILEBROWSER_ARRANGEMENTHINT;Przełącz pomiÄ™dzy poziomym/pionowym wyrównaniem miniaturek +FILEBROWSER_CLEARPROFILE;Wyczyść profil +FILEBROWSER_COPYPROFILE;Kopiuj profil +FILEBROWSER_DELETEDLGLABEL;Potwierdzenie usuniÄ™cia pliku +FILEBROWSER_DELETEDLGMSG;JesteÅ› pewieÅ„, że chcesz usunąć zaznaczone %1 pliki? +FILEBROWSER_EMPTYTRASHHINT;Permanentnie usuÅ„ pliki z kosza +FILEBROWSER_EMPTYTRASH;Wyczyść kosz +FILEBROWSER_EXIFFILTERAPPLYHINT;Włącz/wyłącz filtr Exif w przeglÄ…darce plików +FILEBROWSER_EXIFFILTERAPPLY;Zastosuj +FILEBROWSER_EXIFFILTERLABEL;Filrt Exif +FILEBROWSER_EXIFFILTERSETTINGSHINT;ZmieÅ„ ustawienia filtru Exif +FILEBROWSER_EXIFFILTERSETTINGS;Ustawienia +FILEBROWSER_PARTIALPASTEPROFILE;Wklej częściowo +FILEBROWSER_PASTEPROFILE;Wklej profil +FILEBROWSER_POPUPCANCELJOB;Anuluj zadanie +FILEBROWSER_POPUPMOVEEND;PrzenieÅ› na koniec kolejki +FILEBROWSER_POPUPMOVEHEAD;PrzenieÅ› na poczÄ…tek kolejki +FILEBROWSER_POPUPOPEN;Otrórz +FILEBROWSER_POPUPPROCESS;Umieść w kolejce do przetwarzania +FILEBROWSER_POPUPRANK1;Ocena 1 +FILEBROWSER_POPUPRANK2;Ocena 2 +FILEBROWSER_POPUPRANK3;Ocena 3 +FILEBROWSER_POPUPRANK4;Ocena 4 +FILEBROWSER_POPUPRANK5;Ocena 5 +FILEBROWSER_POPUPREMOVE;UsuÅ„ z systemu plików +FILEBROWSER_POPUPRENAME;ZmieÅ„ nazwÄ™ +FILEBROWSER_POPUPSELECTALL;Zaznacz wszystkie +FILEBROWSER_POPUPTRASH;PrzenieÅ› do kosza +FILEBROWSER_POPUPUNRANK;UsuÅ„ ocenÄ™ +FILEBROWSER_POPUPUNTRASH;UsuÅ„ z kosza +FILEBROWSER_PROCESSINGSETTINGSHINT;Ustaw format pliku i katalog wyjÅ›ciowy +FILEBROWSER_PROCESSINGSETTINGS;Ustawienia +FILEBROWSER_RENAMEDLGLABEL;ZmieÅ„ nazwÄ™ pliku +FILEBROWSER_RENAMEDLGMSG;ZmieÅ„ nazwÄ™ plki "%1" na: +FILEBROWSER_SHOWDIRHINT;Pokaż wszystkie zdjÄ™cia w katalogu +FILEBROWSER_SHOWQUEUEHINT;Pokaz zawartość kolejki przetwarzania +FILEBROWSER_SHOWRANK1HINT;Pokaż zdjÄ™cia ocenione na 1 gwiazdkÄ™ +FILEBROWSER_SHOWRANK2HINT;Pokaż zdjÄ™cia ocenione na 2 gwiazdki +FILEBROWSER_SHOWRANK3HINT;Pokaż zdjÄ™cia ocenione na 3 gwiazdki +FILEBROWSER_SHOWRANK4HINT;Pokaż zdjÄ™cia ocenione na 4 gwiazdki +FILEBROWSER_SHOWRANK5HINT;Pokaż zdjÄ™cia ocenione na 5 gwiazdek +FILEBROWSER_SHOWTRASHHINT;Pokaż zawartość kosza +FILEBROWSER_SHOWUNRANKHINT;Pokaz nieocenione zdjÄ™cia +FILEBROWSER_STARTPROCESSINGHINT;Rozpocznij przetwarzanie/zapisywanie plików w kolejce +FILEBROWSER_STARTPROCESSING;Rozpocznij przetwarzanie +FILEBROWSER_STOPPROCESSINGHINT;Zatrzymaj przetwarzanie zdjęć +FILEBROWSER_STOPPROCESSING;Zatrzymaj przetwarzanie +FILEBROWSER_THUMBSIZE;Rozmiar minaturek +FILEBROWSER_ZOOMINHINT;ZwiÄ™ksz rozmiar miniaturek +FILEBROWSER_ZOOMOUTHINT;Zmniejsz rozmiar miniaturek +GENERAL_ABOUT;O programie +GENERAL_CANCEL;Anuluj +GENERAL_DISABLED;Wyłączone +GENERAL_DISABLE;Wyłącz +GENERAL_ENABLED;Włączone +GENERAL_ENABLE;Włącz +GENERAL_LANDSCAPE;Poziomo +GENERAL_LOAD;Åaduj +GENERAL_NA;nd. +GENERAL_NO;Nie +GENERAL_OK;OK +GENERAL_PORTRAIT;Pionowo +GENERAL_SAVE;Zapisz +GENERAL_YES;Tak +HISTOGRAM_LABEL;Histogram +HISTOGRAM_TOOLTIP_B;Pokaż/Ukryj histogram błękitów +HISTOGRAM_TOOLTIP_G;Pokaż/Ukryj histogram zieleni +HISTOGRAM_TOOLTIP_L;Pokaż/Ukryj histogram luminancji CIELAB +HISTOGRAM_TOOLTIP_R;Pokaż/Ukryj histogram czerwieni +HISTORY_CHANGED;Zmieniono +HISTORY_CUSTOMCURVE;Dowolna krzywa +HISTORY_DELSNAPSHOT;UsuÅ„ migawkÄ™ +HISTORY_FROMCLIPBOARD;Ze schowka +HISTORY_LABEL;Historia +HISTORY_MSG_10;Kompresja cieni +HISTORY_MSG_11;Krzywa tonalna +HISTORY_MSG_12;Automatyczna ekspozycja +HISTORY_MSG_13;Przycinanie ekspozycji +HISTORY_MSG_14;Jasność luminancji +HISTORY_MSG_15;Kontrast luminancji +HISTORY_MSG_16;CzerÅ„ luminancji +HISTORY_MSG_17;Kompr. Å›wiateÅ‚ luminancji +HISTORY_MSG_18;Kompr. cieni luminancji +HISTORY_MSG_19;Krzywa luminancji +HISTORY_MSG_1;ZdjÄ™cie zaÅ‚adowane +HISTORY_MSG_20;Wyostrzanie +HISTORY_MSG_21;PromieÅ„ wyostrzania +HISTORY_MSG_22;SiÅ‚a wyostrzania +HISTORY_MSG_23;Próg wyostrzania +HISTORY_MSG_24;Wyostrz tylko krawÄ™dzie +HISTORY_MSG_25;PromieÅ„ detekcji krawÄ™dzi wyostrzania +HISTORY_MSG_26;Tolerancja wyostrzania krawÄ™dzi +HISTORY_MSG_27;Kontrola poÅ›wiaty wyostrzania +HISTORY_MSG_28;StopieÅ„ kontroli poÅ›wiaty +HISTORY_MSG_29;Metoda wyostrzania +HISTORY_MSG_2;Profil zaÅ‚adowany +HISTORY_MSG_30;PromieÅ„ dekonwolucji +HISTORY_MSG_31;SiÅ‚a dekonwolucji +HISTORY_MSG_32;TÅ‚umienie dekonwolucji +HISTORY_MSG_33;Iteracje dekonwolucji +HISTORY_MSG_34;Zapobiegaj przycinaniu kolorów +HISTORY_MSG_35;Limit saturacji +HISTORY_MSG_36;Limit saturacji +HISTORY_MSG_37;Wzmocnienie koloru +HISTORY_MSG_38;Metoda balansu bieli +HISTORY_MSG_39;Temperatura koloru +HISTORY_MSG_3;Profil zmieniony +HISTORY_MSG_40;OdcieÅ„ balansu bieli +HISTORY_MSG_41;PrzesuniÄ™cie koloru "A" +HISTORY_MSG_42;PrzesuniÄ™cie koloru "B" +HISTORY_MSG_43;Odszumianie luminancji +HISTORY_MSG_44;PromieÅ„ odszumiania lum. +HISTORY_MSG_45;Tol. krawÄ™dzi odszumiania lum. +HISTORY_MSG_46;Odszumianie koloru +HISTORY_MSG_47;PromieÅ„ odszumiania kolorowego +HISTORY_MSG_48;Tol. krawÄ™dzi odszumiania kol. +HISTORY_MSG_49;Odszumianie koloru z czuÅ‚. kraw. +HISTORY_MSG_4;PrzeglÄ…danie historii +HISTORY_MSG_50;NarzÄ™dzie Å›wiatÅ‚a/cienie +HISTORY_MSG_51;Wzmocnienie Å›wiateÅ‚ +HISTORY_MSG_52;Wzmocnienie cieni +HISTORY_MSG_53;Szerokość tonalna Å›wiateÅ‚ +HISTORY_MSG_54;Szerokość tonalna cieni +HISTORY_MSG_55;Kontrast lokalny +HISTORY_MSG_56;PromieÅ„ Å›wiateÅ‚/cieni +HISTORY_MSG_57;Surowy obrót +HISTORY_MSG_58;Odbicie w poziomie +HISTORY_MSG_59;Odbicie w pionie +HISTORY_MSG_5;Jasność +HISTORY_MSG_60;Obrót +HISTORY_MSG_61;Obrót +HISTORY_MSG_62;Korekcja dystorsji obiektywu +HISTORY_MSG_63;ZapamiÄ™taj wybrany +HISTORY_MSG_64;Kadrowanie zdjÄ™cia +HISTORY_MSG_65;Korekcja AC +HISTORY_MSG_66;Odzyskiwanie przeÅ›wietleÅ„ +HISTORY_MSG_67;SiÅ‚a odzyskiwania przeÅ›wietleÅ„ +HISTORY_MSG_68;Metoda odzyskiwania PrzeÅ›wietleÅ„ +HISTORY_MSG_69;Robocza przestrzeÅ„ kolorów +HISTORY_MSG_6;Kontrast +HISTORY_MSG_70;WyjÅ›ciowa przestrzeÅ„ kolorów +HISTORY_MSG_71;WejÅ›ciowa przestrzeÅ„ kolorów +HISTORY_MSG_72;Korekcja winietowania +HISTORY_MSG_73;Mikser kanałów +HISTORY_MSG_74;Skala zmiany rozmiaru +HISTORY_MSG_75;Metoda zmiany rozmiaru +HISTORY_MSG_76;Metadane Exif +HISTORY_MSG_77;Metadane IPTC +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;CzerÅ„ +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;Kompensacja ekspozycji +HISTORY_MSG_9;Kompresja Å›wiateÅ‚ +HISTORY_NEWSNAPSHOTAS;Jako... +HISTORY_NEWSNAPSHOT;Nowa migawka +HISTORY_NEWSSDIALOGLABEL;Nazwa migawki: +HISTORY_NEWSSDIALOGTITLE;Dodaj nowÄ… migawkÄ™ +HISTORY_SETTO;Wybrano +HISTORY_SNAPSHOT;Migawka +HISTORY_SNAPSHOTS;Migawki +ICMPANEL_FILEDLGFILTERANY;Wszystkie pliki +ICMPANEL_FILEDLGFILTERICM;Pliki z profilami ICC +ICMPANEL_GAMMABEFOREINPUT;Profile applies Gamma +ICMPANEL_INPUTCAMERA;DomyÅ›lny aparatu +ICMPANEL_INPUTCUSTOM;RÄ™czny +ICMPANEL_INPUTDLGLABEL;Wybierz wejÅ›ciowy profil ICC... +ICMPANEL_INPUTEMBEDDED;JeÅ›li to możliwe, użyj osadzonego +ICMPANEL_INPUTPROFILE;Profil wejÅ›ciowy +ICMPANEL_NOICM;No ICM: WyjÅ›cie sRGB +ICMPANEL_OUTPUTDLGLABEL;Wybierz wyjÅ›ciowy profil ICC... +ICMPANEL_OUTPUTPROFILE;Profil wyjÅ›ciowy +ICMPANEL_SAVEREFERENCE;Save reference image for profiling +ICMPANEL_WORKINGPROFILE;Profil roboczy +IMAGEAREA_DETAILVIEW;Lupa +IPTCPANEL_AUTHOR;Autor +IPTCPANEL_AUTHORHINT;ImiÄ™ lub nazwa twórcy obiektu np. pisarza, fotografa lub grafika (w linii). +IPTCPANEL_AUTHORSPOSITION;Author's position +IPTCPANEL_AUTHORSPOSITIONHINT;Title of the creator or creators of the object (By-line Title). +IPTCPANEL_CAPTIONHINT;A textual description of the data (Caption - Abstract). +IPTCPANEL_CAPTION;TytuÅ‚ +IPTCPANEL_CAPTIONWRITER;Caption Writer +IPTCPANEL_CAPTIONWRITERHINT;The name of the person involved in the writing, editing or correcting the image or caption/abstract (Writer - Editor). +IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider (Category). +IPTCPANEL_CATEGORY;Kategoria +IPTCPANEL_CITYHINT;City of image origin (City). +IPTCPANEL_CITY;Miasto +IPTCPANEL_COPYHINT;Copy IPTC settings to clipboard +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COPYRIGHTHINT;Any necessary copyright notice (Copyright Notice). +IPTCPANEL_COUNTRYHINT;The name of the country/primary location where the image was created (Country - Primary Location Name). +IPTCPANEL_COUNTRY;Kraj +IPTCPANEL_CREDIT;Credit +IPTCPANEL_CREDITHINT;Identifies the provider of the image, not necessarily the owner/creator (Credit). +IPTCPANEL_DATECREATED;Data utworzenia +IPTCPANEL_DATECREATEDHINT;The date the intellectual content of the image was created; Format: JJJJMMTT (Date Created). +IPTCPANEL_EMBEDDED;Embedded +IPTCPANEL_EMBEDDEDHINT;Reset to IPTC data embedded in the image file +IPTCPANEL_HEADLINEHINT;A publishable entry providing a synopsis of the contents of the image (Headline). +IPTCPANEL_HEADLINE;Nagłówek +IPTCPANEL_INSTRUCTIONSHINT;Other editorial instructions concerning the use of the image (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Instrukcje +IPTCPANEL_KEYWORDSHINT;Used to indicate specific information retrieval words (Keywords). +IPTCPANEL_KEYWORDS;SÅ‚owa kluczowe +IPTCPANEL_PASTEHINT;Paste IPTC settings from clipboard +IPTCPANEL_PROVINCEHINT;The Province/State where the image originates (Province-State). +IPTCPANEL_PROVINCE;Stan, województwo, dystrykt itd. +IPTCPANEL_RESETHINT;Reset to profile default +IPTCPANEL_RESET;Reset +IPTCPANEL_SOURCEHINT;The original owner of the intellectual content of the image (Source). +IPTCPANEL_SOURCE;ŹródÅ‚o +IPTCPANEL_SUPPCATEGORIESHINT;Further refines the subject of the image (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Suppl. Categories +IPTCPANEL_TITLEHINT;A shorthand reference for the image (Object Name). +IPTCPANEL_TITLE;TytuÅ‚ +IPTCPANEL_TRANSREFERENCEHINT;A code representing the location of original transmission (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Trans. Reference +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Preferencje +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;Jako... +MAIN_BUTTON_SAVE;Zapisz obraz +MAIN_BUTTON_SENDTOEDITOR;WyÅ›lij do edytora +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Plik już istnieje. +MAIN_MSG_CANNOTLOAD;Nie można wczytać obrazu +MAIN_MSG_CANNOTSAVE;Błąd zapisu pliku +MAIN_MSG_CANNOTSTARTEDITOR;Nie mozna uruchomic edytora. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Musisz wspisać prawidÅ‚owÄ… Å›cieżkÄ™ w oknie "Preferencji". +MAIN_MSG_EXITJOBSINQUEUEINFO;Nieprzetworzone zdjÄ™cia w kolejce bÄ™dÄ… utracone po zamkniÄ™ciu. +MAIN_MSG_EXITJOBSINQUEUEQUEST;JesteÅ› pewien, że chcesz zamknąć alpikacjÄ™? W kolejce znajdujÄ… siÄ™ nieprzetworzone zdjÄ™cia. +MAIN_MSG_JOBSINQUEUE;zadaÅ„ w kolejce +MAIN_MSG_QOVERWRITE;Czy chcesz go zastÄ…pić? +MAIN_TAB_BASIC;Podstawowe +MAIN_TAB_COLOR;Kolor +MAIN_TAB_DETAIL;Szczegóły +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Ekspozycja +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadane +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Transformacje +MAIN_TOOLTIP_HIDEFP;Pokaż/ukryj dolny panel (przeglÄ…darka plików i katalogów, shortcut key: F) +MAIN_TOOLTIP_HIDEHP;Pokaż/ukryj lewy panel (razem z historiÄ…, shortcut key: H) +MAIN_TOOLTIP_INDCLIPPEDH;Pokaż przeÅ›wietlenia +MAIN_TOOLTIP_INDCLIPPEDS;Pokaż niedoÅ›wietlenia +MAIN_TOOLTIP_PREFERENCES;Ustaw preferencje +MAIN_TOOLTIP_QINFO;Informacje o pliku +MAIN_TOOLTIP_SAVEAS;Zapisz obraz we wskazanym katalogu +MAIN_TOOLTIP_SAVE;Zapisz obraz w katalogu domyÅ›lnym +PARTIALPASTE_BASICGROUP;Podstawowe ustawienia +PARTIALPASTE_CACORRECTION;Korekcja C/A +PARTIALPASTE_COARSETRANS;Rotacja/odwrócenie o 90 stopni +PARTIALPASTE_COLORBOOST;Uwydatnienie koloru +PARTIALPASTE_COLORDENOISE;Odszumienie koloru +PARTIALPASTE_COLORGROUP;Ustawienia zwiÄ…zane z kolorem +PARTIALPASTE_COLORMIXER;Mikser koloru +PARTIALPASTE_COLORSHIFT;PrzesuniÄ™cie koloru +PARTIALPASTE_COMPOSITIONGROUP;Ustawienia kompozycji +PARTIALPASTE_CROP;Przytnij +PARTIALPASTE_DIALOGLABEL;Partial paste processing profile +PARTIALPASTE_DISTORTION;Korekcja znieksztaÅ‚cenia +PARTIALPASTE_EXIFCHANGES;ZmieÅ„ dane Exif +PARTIALPASTE_EXPOSURE;Ekspozycja +PARTIALPASTE_HLRECOVERY;Highlight recovery +PARTIALPASTE_ICMSETTINGS;Ustawienia ICM +PARTIALPASTE_IPTCINFO;Informacje IPTC +PARTIALPASTE_LENSGROUP;Ustawienia zwiÄ…zane z obiektywem +PARTIALPASTE_LUMACURVE;Krzywa obiektywu +PARTIALPASTE_LUMADENOISE;Redukcja zaszumienia jaskrawoÅ›ci +PARTIALPASTE_LUMINANCEGROUP;Ustawienia zwiÄ…zane z jaskrawoÅ›ciÄ… +PARTIALPASTE_METAICMGROUP;Metadanea/Ustawienia ICM +PARTIALPASTE_RESIZE;ZmieÅ„ rozmiar +PARTIALPASTE_ROTATION;Rotacja +PARTIALPASTE_SHADOWSHIGHLIGHTS;Cienie/PodÅ›wietlenia +PARTIALPASTE_SHARPENING;Wyostrzanie +PARTIALPASTE_VIGNETTING;Korekcja winiety +PARTIALPASTE_WHITEBALANCE;Balans bieli +PREFERENCES_APPLNEXTSTARTUP;wymaga ponownego uruchomienia +PREFERENCES_BLINKCLIPPED;MrugajÄ…ce przeÅ›wietlenia +PREFERENCES_CACHECLEARALL;Wyczyść wszystko +PREFERENCES_CACHECLEARPROFILES;Wyczyść profile +PREFERENCES_CACHECLEARTHUMBS;Wyczyść miniaturki +PREFERENCES_CACHEFORMAT1;Proprietary (faster and better quality) +PREFERENCES_CACHEFORMAT2;JPEG (smaller disk footprint) +PREFERENCES_CACHEMAXENTRIES;Maksymalna liczba wpisów w pamiÄ™ci podrÄ™cznej +PREFERENCES_CACHEOPTS;Opcje pamiÄ™ci podrÄ™cznej +PREFERENCES_CACHESTRAT1;Prefer Speed to Low Memory Consumption +PREFERENCES_CACHESTRAT2;Prefer Low Memory Consumption to Speed +PREFERENCES_CACHESTRAT;Cache Strategy +PREFERENCES_CACHETHUMBFORM;Cache Thumbnail Format +PREFERENCES_CACHETHUMBHEIGHT;Maximal Thumbnail Height +PREFERENCES_CLEARDLG_LINE1;Czyszczenie pamiÄ™ci podrÄ™cznej +PREFERENCES_CLEARDLG_LINE2;Może to potrwać kilka sekund. +PREFERENCES_CLEARDLG_TITLE;Prosze czekać +PREFERENCES_CLIPPINGIND;Pokazywanie przeÅ›wietleÅ„ +PREFERENCES_CMETRICINTENT;Sposób odwzorowania barw +PREFERENCES_DATEFORMAT;Format daty +PREFERENCES_DATEFORMATHINT;You can use the following formatting strings:\n%y : year\n%m : month\n%d : day\n\nFor example, the hungarian date format is:\n%y/%m/%d +PREFERENCES_DEFAULTLANG;JÄ™zyk domyÅ›lny +PREFERENCES_DEFAULTTHEME;Default theme +PREFERENCES_DEMOSAICINGALGO;Algorytm demozaikowania +PREFERENCES_DIRHOME;Katalog domowy +PREFERENCES_DIRLAST;Ostatnio odwiedzony katalog +PREFERENCES_DIROTHER;Inny +PREFERENCES_DIRSELECTDLG;Wybierz katalog z obrazami po uruchomieniu... +PREFERENCES_DIRSOFTWARE;Katalog instalacyjny +PREFERENCES_DMETHOD;Metoda +PREFERENCES_EDITORCMDLINE;Other command line +PREFERENCES_EXTERNALEDITOR;ZewnÄ™trzny edytor +PREFERENCES_FALSECOLOR;Kroki zapobiegania zafaÅ‚szowaniom kolorów +PREFERENCES_FBROWSEROPTS;Opcje przeglÄ…darki plików +PREFERENCES_FILEFORMAT;Format pliku +PREFERENCES_FORIMAGE;Dla plików z obrazami +PREFERENCES_FORRAW;Dla plików RAW +PREFERENCES_GIMPPATH;Katalog, w którym zainstalowany jest GIMP +PREFERENCES_GTKTHEME;GTK default +PREFERENCES_HINT;Porada +PREFERENCES_HLTHRESHOLD;Próg dla przeÅ›wietleñ +PREFERENCES_ICCDIR;Katalog z profilami ICC +PREFERENCES_IMPROCPARAMS;DomyÅ›lne parametry przetwarzania obrazu +PREFERENCES_INTENT_ABSOLUTE;Absolutnie kolorymetryczny +PREFERENCES_INTENT_PERCEPTUAL;Percepcyjny +PREFERENCES_INTENT_RELATIVE;WzglÄ™dnie kolorymetryczny +PREFERENCES_INTENT_SATURATION;Nasyceniowy +PREFERENCES_LIVETHUMBNAILS;Miniaturki na żywo (wojniej) +PREFERENCES_MONITORICC;Profil monitora +PREFERENCES_OUTDIRFOLDERHINT;Umieść zapisane zdjÄ™cia w wybranym katalogu +PREFERENCES_OUTDIRFOLDER;Zapisz do katalogu +PREFERENCES_OUTDIRHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIR;Katalog wyjÅ›ciowy +PREFERENCES_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Użyj schemat +PREFERENCES_PARSEDEXTADD;Dodaj rozszerzenie +PREFERENCES_PARSEDEXTADDHINT;Type an extension and press this button to append list +PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list +PREFERENCES_PARSEDEXT;Parsed Extensions +PREFERENCES_PROFILEHANDLING;Processing Profile Handling +PREFERENCES_PROFILELOADPR;Profile Loading Priority +PREFERENCES_PROFILEPRCACHE;Profile in Cache +PREFERENCES_PROFILEPRFILE;Profile Next to the Input File +PREFERENCES_PROFILESAVECACHE;Save Processing Parameters to the Cache +PREFERENCES_PROFILESAVEINPUT;Save Processing Parameters Next to the Input File +PREFERENCES_PSPATH;Katalog w którym zainstalowany jest Adobe Photoshop +PREFERENCES_SELECTICCDIRDLG;Wybierz katalog z profilami ICC... +PREFERENCES_SELECTLANG;Wybierz jÄ™zyk +PREFERENCES_SELECTMONITORPROFDLG;Wybierz profil ICC do wyÅ›wietlenia... +PREFERENCES_SELECTTHEME;Select theme +PREFERENCES_SHOWBASICEXIF;Pokaż podstawowe dane Exif +PREFERENCES_SHOWDATETIME;Pokaż datÄ™ i czas +PREFERENCES_SHOWONLYRAW;Pokaż tylko pliki RAW +PREFERENCES_SHTHRESHOLD;Próg dla niedoÅ›wietleñ +PREFERENCES_STARTUPIMDIR;Katalog startowy +PREFERENCES_TAB_BROWSER;PrzeglÄ…darka plików +PREFERENCES_TAB_COLORMGR;ZarzÄ…dzanie kolorami +PREFERENCES_TAB_GENERAL;Ogólne +PREFERENCES_TAB_IMPROC;Przetwarzanie obrazu +PREFERENCES_TAB_OUTPUT;Opcje wyjÅ›ciowe +PREFERENCES_THUMBSIZE;Wielkość miniaturki +PROFILEPANEL_FILEDLGFILTERANY;Wszystkie pliki +PROFILEPANEL_FILEDLGFILTERPP;Profile postprocessingu +PROFILEPANEL_LABEL;Profil postprocessingu +PROFILEPANEL_LOADDLGLABEL;Åaduj parametry postprocessingu... +PROFILEPANEL_PCUSTOM;RÄ™czny +PROFILEPANEL_PFILE;Z pliku +PROFILEPANEL_PLASTPHOTO;Ostatnie ZdjÄ™cie +PROFILEPANEL_PLASTSAVED;Ostatnio zapisany +PROFILEPANEL_PROFILE;Profil +PROFILEPANEL_SAVEDLGLABEL;Zapisz parametry postprocessingu... +PROFILEPANEL_TOOLTIPCOPY;Skopiuj aktualny profil do schowka +PROFILEPANEL_TOOLTIPLOAD;Åaduj profil z pliku +PROFILEPANEL_TOOLTIPPASTE;Wklej profil ze schowka +PROFILEPANEL_TOOLTIPSAVE;Zapisz aktualny profil +PROGRESSBAR_DECODING;Dekodowanie pliku raw... +PROGRESSBAR_DEMOSAICING;Demozaikowanie... +PROGRESSBAR_LOADING;Wczytywanie obrazu... +PROGRESSBAR_LOADJPEG;Åadowanie pliku JPEG... +PROGRESSBAR_LOADPNG;Åadowanie pliku PNG... +PROGRESSBAR_LOADTIFF;Åadowanie pliku TIFF... +PROGRESSBAR_PROCESSING;Przetwarzanie obrazu... +PROGRESSBAR_READY;Gotowe. +PROGRESSBAR_SAVEJPEG;Zapisywanie pliku JPEG... +PROGRESSBAR_SAVEPNG;Zapisywanie pliku PNG... +PROGRESSBAR_SAVETIFF;Zapisywanie pliku TIFF... +PROGRESSDLG_LOADING;Wczytywanie pliku... +PROGRESSDLG_PROCESSING;Przetwarzanie zdjÄ™cia... +PROGRESSDLG_SAVING;Zapisywanie pliku... +QINFO_FOCALLENGTH;Ogniskowa +QINFO_ISO;ISO +QINFO_LENS;Obiektyw +QINFO_NOEXIF;Dane exif niedostÄ™pne. +SAVEDLG_FILEFORMAT;Format pliku +SAVEDLG_JPEGQUAL;Jakość JPEG +SAVEDLG_JPGFILTER;Pliki JPEG +SAVEDLG_PNGCOMPR;Kompresja PNG +SAVEDLG_PNGFILTER;Pliki PNG +SAVEDLG_PUTTOQUEUEHEAD;Put to the head of the processing queue +SAVEDLG_PUTTOQUEUE;Put into processing queue +SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue +SAVEDLG_SAVEIMMEDIATELY;Save immediately +SAVEDLG_SAVESPP;Zapisz parametry przetwarzania wraz z obrazem +SAVEDLG_TIFFFILTER;Pliki TIFF +TOOLBAR_TOOLTIP_CROP;Kadruj (shortcut key: C) +TOOLBAR_TOOLTIP_HAND;PrzesuÅ„ (shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Wyprostuj obraz (shortcut key: S) +TOOLBAR_TOOLTIP_WB;Wskaż balans bieli (shortcut key: W) +TP_CACORRECTION_BLUE;Niebieski +TP_CACORRECTION_LABEL;Korekcja AC +TP_CACORRECTION_RED;Czerwony +TP_CHMIXER_BLUE;Niebieski +TP_CHMIXER_GREEN;Zielony +TP_CHMIXER_LABEL;Mikser kanałów +TP_CHMIXER_RED;Czerwony +TP_COARSETRAF_DEGREE;stopnie: +TP_COARSETRAF_TOOLTIP_HFLIP;Odbij w poziomie +TP_COARSETRAF_TOOLTIP_ROTLEFT;Obróć w lewo +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Obróć w prawo +TP_COARSETRAF_TOOLTIP_VFLIP;Odbij w pionie +TP_COLORBOOST_ACHANNEL;kanaÅ‚ "a" +TP_COLORBOOST_AMOUNT;StopieÅ„ +TP_COLORBOOST_AVOIDCOLORCLIP;Unikaj przycinania kolorów +TP_COLORBOOST_BCHANNEL;kanaÅ‚ "b" +TP_COLORBOOST_CHAB;a i b +TP_COLORBOOST_CHANNEL;KanaÅ‚ +TP_COLORBOOST_CHSEPARATE;oddzielnie +TP_COLORBOOST_ENABLESATLIMITER;Włącz limit saturacji +TP_COLORBOOST_LABEL;Wzmocnienie koloru +TP_COLORBOOST_SATLIMIT;Limit saturacji +TP_COLORDENOISE_EDGESENSITIVE;CzuÅ‚ość krawÄ™dzi +TP_COLORDENOISE_EDGETOLERANCE;Tolerancja krawÄ™dzi +TP_COLORDENOISE_LABEL;Odszumianie koloru +TP_COLORDENOISE_RADIUS;PromieÅ„ +TP_COLORSHIFT_BLUEYELLOW;Błękit-żółty +TP_COLORSHIFT_GREENMAGENTA;ZieleÅ„-magenta +TP_COLORSHIFT_LABEL;PrzesuniÄ™cie koloru +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Zablokuj proporcje: +TP_CROP_GTDIAGONALS;PrzekÄ…tna +TP_CROP_GTHARMMEANS1;ZÅ‚oty podziaÅ‚ 1 +TP_CROP_GTHARMMEANS2;ZÅ‚oty podziaÅ‚ 2 +TP_CROP_GTHARMMEANS3;ZÅ‚oty podziaÅ‚ 3 +TP_CROP_GTHARMMEANS4;ZÅ‚oty podziaÅ‚ 4 +TP_CROP_GTNONE;Nic +TP_CROP_GTRULETHIRDS;TrójpodziaÅ‚ +TP_CROP_GUIDETYPE;Typ pomocy: +TP_CROP_H;W +TP_CROP_LABEL;Kadrowanie +TP_CROP_SELECTCROP;Wybierz kadr +TP_CROP_W;S +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;SiÅ‚a +TP_DISTORTION_LABEL;Dystorsja +TP_EXPOSURE_AUTOLEVELS;Wyrównaj poziomy +TP_EXPOSURE_BLACKLEVEL;CzerÅ„ +TP_EXPOSURE_BRIGHTNESS;Jasność +TP_EXPOSURE_CLIP;Przytnij +TP_EXPOSURE_COMPRHIGHLIGHTS;Kompresja Å›wiateÅ‚ +TP_EXPOSURE_COMPRSHADOWS;Kompresja cieni +TP_EXPOSURE_CONTRAST;Kontrast +TP_EXPOSURE_CURVEEDITOR;Krzywa tonalna +TP_EXPOSURE_EXPCOMP;EV +TP_EXPOSURE_LABEL;Ekspozycja +TP_HLREC_CIELAB;Mieszanie koloru CIELab +TP_HLREC_COLOR;Propagacja koloru +TP_HLREC_LABEL;Odzyskiwanie przeÅ›wietleÅ„ +TP_HLREC_LUMINANCE;Odzyskiwanie luminancji +TP_HLREC_METHOD;Metoda: +TP_ICM_FILEDLGFILTERANY;Wszystkie pliki +TP_ICM_FILEDLGFILTERICM;Pliki z profilami ICC +TP_ICM_GAMMABEFOREINPUT;Profile applies Gamma +TP_ICM_INPUTCAMERA;DomyÅ›lny aparatu +TP_ICM_INPUTCUSTOM;RÄ™czny +TP_ICM_INPUTDLGLABEL;Wybierz wejÅ›ciowy profil ICC... +TP_ICM_INPUTEMBEDDED;JeÅ›li to możliwe, użyj osadzonego +TP_ICM_INPUTPROFILE;Profil wejÅ›ciowy +TP_ICM_LABEL;ICM +TP_ICM_NOICM;No ICM: WyjÅ›cie sRGB +TP_ICM_OUTPUTDLGLABEL;Wybierz wyjÅ›ciowy profil ICC... +TP_ICM_OUTPUTPROFILE;Profil wyjÅ›ciowy +TP_ICM_SAVEREFERENCE;Save reference image for profiling +TP_ICM_WORKINGPROFILE;Profil roboczy +TP_LUMACURVE_BLACKLEVEL;CzerÅ„ +TP_LUMACURVE_BRIGHTNESS;Jasność +TP_LUMACURVE_COMPRHIGHLIGHTS;Kompresja Å›wiateÅ‚ +TP_LUMACURVE_COMPRSHADOWS;Kompresja cieni +TP_LUMACURVE_CONTRAST;Kontrast +TP_LUMACURVE_CURVEEDITOR;Krzywa luminancji +TP_LUMACURVE_LABEL;Krzywa luminancji +TP_LUMADENOISE_EDGETOLERANCE;Tolerancja krawÄ™dzi +TP_LUMADENOISE_LABEL;Odszumianie luminancji +TP_LUMADENOISE_RADIUS;PromieÅ„ +TP_RESIZE_BICUBIC;Bicubic +TP_RESIZE_BICUBICSF;Bicubic (MiÄ™kko) +TP_RESIZE_BICUBICSH;Bicubic (Ostro) +TP_RESIZE_BILINEAR;Bilinear +TP_RESIZE_FULLSIZE;PeÅ‚ny rozmiar obrazu: +TP_RESIZE_H;W: +TP_RESIZE_LABEL;Skalowanie +TP_RESIZE_METHOD;Metoda: +TP_RESIZE_NEAREST;Najbliższa +TP_RESIZE_SCALE;Skala +TP_RESIZE_W;S: +TP_ROTATE_AUTOCROP;Auto przycinanie +TP_ROTATE_DEGREE;Stopnie +TP_ROTATE_FILL;WypeÅ‚nij +TP_ROTATE_LABEL;Obrót +TP_ROTATE_SELECTLINE;Wyprostuj obraz +TP_SHADOWSHLIGHTS_HIGHLIGHTS;ÅšwiatÅ‚a +TP_SHADOWSHLIGHTS_HLTONALW;Szerokość tonalna +TP_SHADOWSHLIGHTS_LABEL;Cienie/ÅšwiatÅ‚a +TP_SHADOWSHLIGHTS_LOCALCONTR;Kontrast lokalny +TP_SHADOWSHLIGHTS_RADIUS;PromieÅ„ +TP_SHADOWSHLIGHTS_SHADOWS;Cienie +TP_SHADOWSHLIGHTS_SHTONALW;Szerokość tonalna +TP_SHARPENING_AMOUNT;SiÅ‚a +TP_SHARPENING_EDRADIUS;PromieÅ„ +TP_SHARPENING_EDTOLERANCE;Tolerancja +TP_SHARPENING_HALOCONTROL;Kontrola poÅ›wiaty +TP_SHARPENING_HCAMOUNT;SiÅ‚a +TP_SHARPENING_LABEL;Wyostrzanie +TP_SHARPENING_METHOD;Metoda +TP_SHARPENING_ONLYEDGES;Wyostrz tylko krawÄ™dzie +TP_SHARPENING_RADIUS;PromieÅ„ +TP_SHARPENING_RLD_AMOUNT;SiÅ‚a +TP_SHARPENING_RLD_DAMPING;TÅ‚umienie +TP_SHARPENING_RLD;Dekonwolucja RL +TP_SHARPENING_RLD_ITERATIONS;Iteracje +TP_SHARPENING_THRESHOLD;Próg +TP_SHARPENING_USM;Maska wyostrzajÄ…ca +TP_VIGNETTING_AMOUNT;SiÅ‚a +TP_VIGNETTING_LABEL;Korekcja winietowania +TP_VIGNETTING_RADIUS;PromieÅ„ +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Z aparatu +TP_WBALANCE_CUSTOM;RÄ™czny +TP_WBALANCE_GREEN;OdcieÅ„ +TP_WBALANCE_LABEL;Balans bieli +TP_WBALANCE_METHOD;Metoda +TP_WBALANCE_SIZE;Wielkość: +TP_WBALANCE_SPOTWB;Punktowy +TP_WBALANCE_TEMPERATURE;Temperatura +ZOOMBAR_DETAIL;Lupa +ZOOMBAR_HUGE;Olbrzymia +ZOOMBAR_LARGE;Duża +ZOOMBAR_NORMAL;Normalna +ZOOMBAR_PREVIEW;Widok +ZOOMBAR_SCALE;Skala +ZOOMBAR_SMALL;MaÅ‚a + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Polish (Latin Characters) b/rtdata/languages/Polish (Latin Characters) new file mode 100644 index 000000000..c604b6988 --- /dev/null +++ b/rtdata/languages/Polish (Latin Characters) @@ -0,0 +1,708 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# polish version +# 24.12.2007 +# Mateusz Ludwin +# ----------------------------- +# 08.01.2010 +# Initial update for 3.0 release +# Bartosz "Simek" Kaszubowski +# +ADJUSTER_RESET_TO_DEFAULT;Przywroc domyslne +CURVEEDITOR_FILEDLGFILTERANY;Wszystkie pliki +CURVEEDITOR_FILEDLGFILTERCURVE;Pliki z krzywymi +CURVEEDITOR_LINEAR;Liniowa +CURVEEDITOR_LOADDLGLABEL;Wczytaj krzywa... +CURVEEDITOR_SAVEDLGLABEL;Zapisz krzywa... +CURVEEDITOR_TOOLTIPLINEAR;Zresetuj krzywa do liniowej +CURVEEDITOR_TOOLTIPLOAD;Wczytaj krzywa z pliku +CURVEEDITOR_TOOLTIPSAVE;Zapisz aktualna krzywa +EXIFFILTER_APERTURE;Przeslona +EXIFFILTER_CAMERA;Aparat +EXIFFILTER_DIALOGLABEL;Filrt Exif +EXIFFILTER_FOCALLEN;Wartosc ogniskowej +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Obiektyw +EXIFFILTER_SHUTTER;Migawka +EXIFPANEL_ADDEDIT;Dodaj/Edytuj +EXIFPANEL_ADDEDITHINT;Dodaj nowa etykiete lub edytuj etykiete +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Wpisz wartosc +EXIFPANEL_ADDTAGDLG_SELECTTAG;Wybierz etykiete +EXIFPANEL_ADDTAGDLG_TITLE;Dodaj/Edytuj etykiete +EXIFPANEL_KEEPHINT;Zapamietaj wybrane etykiety podczas zapisywania pliku wyjsciowego +EXIFPANEL_KEEP;Zapamietaj +EXIFPANEL_REMOVEHINT;Usun wybrane etykiety podczas zapisywania pliku wyjsciowego +EXIFPANEL_REMOVE;Usun +EXIFPANEL_RESETALLHINT;Przywroc wszystkie etykiety do ich oryginalnych wartosci +EXIFPANEL_RESETALL;Przywroc wszystkie +EXIFPANEL_RESETHINT;Przywroc wybrane etykiety do ich oryginalnych wartosci +EXIFPANEL_RESET;Przywroc +EXIFPANEL_SUBDIRECTORY;Podkatalog +FILEBROWSER_APPLYPROFILE;Zastosuj profil +FILEBROWSER_ARRANGEMENTHINT;Przelacz pomiedzy poziomym/pionowym wyrownaniem miniaturek +FILEBROWSER_CLEARPROFILE;Wyczysc profil +FILEBROWSER_COPYPROFILE;Kopiuj profil +FILEBROWSER_DELETEDLGLABEL;Potwierdzenie usuniecia pliku +FILEBROWSER_DELETEDLGMSG;Jestes pewien, ze chcesz usunac zaznaczone %1 pliki? +FILEBROWSER_EMPTYTRASHHINT;Permanentnie usun pliki z kosza +FILEBROWSER_EMPTYTRASH;Wyczysc kosz +FILEBROWSER_EXIFFILTERAPPLYHINT;Wlacz/wylacz filtr Exif w przegladarce plikow +FILEBROWSER_EXIFFILTERAPPLY;Zastosuj +FILEBROWSER_EXIFFILTERLABEL;Filrt Exif +FILEBROWSER_EXIFFILTERSETTINGSHINT;Zmien ustawienia filtru Exif +FILEBROWSER_EXIFFILTERSETTINGS;Ustawienia +FILEBROWSER_PARTIALPASTEPROFILE;Wklej czesciowo +FILEBROWSER_PASTEPROFILE;Wklej profil +FILEBROWSER_POPUPCANCELJOB;Anuluj zadanie +FILEBROWSER_POPUPMOVEEND;Przenies na koniec kolejki +FILEBROWSER_POPUPMOVEHEAD;Przenies na poczatek kolejki +FILEBROWSER_POPUPOPEN;Otrorz +FILEBROWSER_POPUPPROCESS;Umiesc w kolejce do przetwarzania +FILEBROWSER_POPUPRANK1;Ocena 1 +FILEBROWSER_POPUPRANK2;Ocena 2 +FILEBROWSER_POPUPRANK3;Ocena 3 +FILEBROWSER_POPUPRANK4;Ocena 4 +FILEBROWSER_POPUPRANK5;Ocena 5 +FILEBROWSER_POPUPREMOVE;Usun z systemu plikow +FILEBROWSER_POPUPRENAME;Zmien nazwe +FILEBROWSER_POPUPSELECTALL;Zaznacz wszystkie +FILEBROWSER_POPUPTRASH;Przenies do kosza +FILEBROWSER_POPUPUNRANK;Usun ocene +FILEBROWSER_POPUPUNTRASH;Usun z kosza +FILEBROWSER_PROCESSINGSETTINGSHINT;Ustaw format pliku i katalog wyjsciowy +FILEBROWSER_PROCESSINGSETTINGS;Ustawienia +FILEBROWSER_RENAMEDLGLABEL;Zmien nazwe pliku +FILEBROWSER_RENAMEDLGMSG;Zmien nazwe plki "%1" na: +FILEBROWSER_SHOWDIRHINT;Pokaz wszystkie zdjecia w katalogu +FILEBROWSER_SHOWQUEUEHINT;Pokaz zawartosc kolejki przetwarzania +FILEBROWSER_SHOWRANK1HINT;Pokaz zdjecia ocenione na 1 gwiazdke +FILEBROWSER_SHOWRANK2HINT;Pokaz zdjecia ocenione na 2 gwiazdki +FILEBROWSER_SHOWRANK3HINT;Pokaz zdjecia ocenione na 3 gwiazdki +FILEBROWSER_SHOWRANK4HINT;Pokaz zdjecia ocenione na 4 gwiazdki +FILEBROWSER_SHOWRANK5HINT;Pokaz zdjecia ocenione na 5 gwiazdek +FILEBROWSER_SHOWTRASHHINT;Pokaz zawartosc kosza +FILEBROWSER_SHOWUNRANKHINT;Pokaz nieocenione zdjecia +FILEBROWSER_STARTPROCESSINGHINT;Rozpocznij przetwarzanie/zapisywanie plikow w kolejce +FILEBROWSER_STARTPROCESSING;Rozpocznij przetwarzanie +FILEBROWSER_STOPPROCESSINGHINT;Zatrzymaj przetwarzanie zdjec +FILEBROWSER_STOPPROCESSING;Zatrzymaj przetwarzanie +FILEBROWSER_THUMBSIZE;Rozmiar minaturek +FILEBROWSER_ZOOMINHINT;Zwieksz rozmiar miniaturek +FILEBROWSER_ZOOMOUTHINT;Zmniejsz rozmiar miniaturek +GENERAL_ABOUT;O programie +GENERAL_CANCEL;Anuluj +GENERAL_DISABLED;Wylaczone +GENERAL_DISABLE;Wylacz +GENERAL_ENABLED;Wlaczone +GENERAL_ENABLE;Wlacz +GENERAL_LANDSCAPE;Poziomo +GENERAL_LOAD;laduj +GENERAL_NA;nd. +GENERAL_NO;Nie +GENERAL_OK;OK +GENERAL_PORTRAIT;Pionowo +GENERAL_SAVE;Zapisz +GENERAL_YES;Tak +HISTOGRAM_LABEL;Histogram +HISTOGRAM_TOOLTIP_B;Pokaz/Ukryj histogram blekitow +HISTOGRAM_TOOLTIP_G;Pokaz/Ukryj histogram zieleni +HISTOGRAM_TOOLTIP_L;Pokaz/Ukryj histogram luminancji CIELAB +HISTOGRAM_TOOLTIP_R;Pokaz/Ukryj histogram czerwieni +HISTORY_CHANGED;Zmieniono +HISTORY_CUSTOMCURVE;Dowolna krzywa +HISTORY_DELSNAPSHOT;Usun migawke +HISTORY_FROMCLIPBOARD;Ze schowka +HISTORY_LABEL;Historia +HISTORY_MSG_10;Kompresja cieni +HISTORY_MSG_11;Krzywa tonalna +HISTORY_MSG_12;Automatyczna ekspozycja +HISTORY_MSG_13;Przycinanie ekspozycji +HISTORY_MSG_14;Jasnosc luminancji +HISTORY_MSG_15;Kontrast luminancji +HISTORY_MSG_16;Czern luminancji +HISTORY_MSG_17;Kompr. swiatel luminancji +HISTORY_MSG_18;Kompr. cieni luminancji +HISTORY_MSG_19;Krzywa luminancji +HISTORY_MSG_1;Zdjecie zaladowane +HISTORY_MSG_20;Wyostrzanie +HISTORY_MSG_21;Promien wyostrzania +HISTORY_MSG_22;Sila wyostrzania +HISTORY_MSG_23;Prog wyostrzania +HISTORY_MSG_24;Wyostrz tylko krawedzie +HISTORY_MSG_25;Promien detekcji krawedzi wyostrzania +HISTORY_MSG_26;Tolerancja wyostrzania krawedzi +HISTORY_MSG_27;Kontrola poswiaty wyostrzania +HISTORY_MSG_28;Stopien kontroli poswiaty +HISTORY_MSG_29;Metoda wyostrzania +HISTORY_MSG_2;Profil zaladowany +HISTORY_MSG_30;Promien dekonwolucji +HISTORY_MSG_31;Sila dekonwolucji +HISTORY_MSG_32;Tlumienie dekonwolucji +HISTORY_MSG_33;Iteracje dekonwolucji +HISTORY_MSG_34;Zapobiegaj przycinaniu kolorow +HISTORY_MSG_35;Limit saturacji +HISTORY_MSG_36;Limit saturacji +HISTORY_MSG_37;Wzmocnienie koloru +HISTORY_MSG_38;Metoda balansu bieli +HISTORY_MSG_39;Temperatura koloru +HISTORY_MSG_3;Profil zmieniony +HISTORY_MSG_40;Odcien balansu bieli +HISTORY_MSG_41;Przesuniecie koloru "A" +HISTORY_MSG_42;Przesuniecie koloru "B" +HISTORY_MSG_43;Odszumianie luminancji +HISTORY_MSG_44;Promien odszumiania lum. +HISTORY_MSG_45;Tol. krawedzi odszumiania lum. +HISTORY_MSG_46;Odszumianie koloru +HISTORY_MSG_47;Promien odszumiania kolorowego +HISTORY_MSG_48;Tol. krawedzi odszumiania kol. +HISTORY_MSG_49;Odszumianie koloru z czul. kraw. +HISTORY_MSG_4;Przegladanie historii +HISTORY_MSG_50;Narzedzie swiatla/cienie +HISTORY_MSG_51;Wzmocnienie swiatel +HISTORY_MSG_52;Wzmocnienie cieni +HISTORY_MSG_53;Szerokosc tonalna swiatel +HISTORY_MSG_54;Szerokosc tonalna cieni +HISTORY_MSG_55;Kontrast lokalny +HISTORY_MSG_56;Promien swiatel/cieni +HISTORY_MSG_57;Surowy obrot +HISTORY_MSG_58;Odbicie w poziomie +HISTORY_MSG_59;Odbicie w pionie +HISTORY_MSG_5;Jasnosc +HISTORY_MSG_60;Obrot +HISTORY_MSG_61;Obrot +HISTORY_MSG_62;Korekcja dystorsji obiektywu +HISTORY_MSG_63;Zapamietaj wybrany +HISTORY_MSG_64;Kadrowanie zdjecia +HISTORY_MSG_65;Korekcja AC +HISTORY_MSG_66;Odzyskiwanie przeswietlen +HISTORY_MSG_67;Sila odzyskiwania przeswietlen +HISTORY_MSG_68;Metoda odzyskiwania Przeswietlen +HISTORY_MSG_69;Robocza przestrzen kolorow +HISTORY_MSG_6;Kontrast +HISTORY_MSG_70;Wyjsciowa przestrzen kolorow +HISTORY_MSG_71;Wejsciowa przestrzen kolorow +HISTORY_MSG_72;Korekcja winietowania +HISTORY_MSG_73;Mikser kanalow +HISTORY_MSG_74;Skala zmiany rozmiaru +HISTORY_MSG_75;Metoda zmiany rozmiaru +HISTORY_MSG_76;Metadane Exif +HISTORY_MSG_77;Metadane IPTC +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;Czern +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;Kompensacja ekspozycji +HISTORY_MSG_9;Kompresja swiatel +HISTORY_NEWSNAPSHOTAS;Jako... +HISTORY_NEWSNAPSHOT;Nowa migawka +HISTORY_NEWSSDIALOGLABEL;Nazwa migawki: +HISTORY_NEWSSDIALOGTITLE;Dodaj nowa migawke +HISTORY_SETTO;Wybrano +HISTORY_SNAPSHOT;Migawka +HISTORY_SNAPSHOTS;Migawki +ICMPANEL_FILEDLGFILTERANY;Wszystkie pliki +ICMPANEL_FILEDLGFILTERICM;Pliki z profilami ICC +ICMPANEL_GAMMABEFOREINPUT;Profile applies Gamma +ICMPANEL_INPUTCAMERA;Domyslny aparatu +ICMPANEL_INPUTCUSTOM;Reczny +ICMPANEL_INPUTDLGLABEL;Wybierz wejsciowy profil ICC... +ICMPANEL_INPUTEMBEDDED;Jesli to mozliwe, uzyj osadzonego +ICMPANEL_INPUTPROFILE;Profil wejsciowy +ICMPANEL_NOICM;No ICM: Wyjscie sRGB +ICMPANEL_OUTPUTDLGLABEL;Wybierz wyjsciowy profil ICC... +ICMPANEL_OUTPUTPROFILE;Profil wyjsciowy +ICMPANEL_SAVEREFERENCE;Save reference image for profiling +ICMPANEL_WORKINGPROFILE;Profil roboczy +IMAGEAREA_DETAILVIEW;Lupa +IPTCPANEL_AUTHOR;Autor +IPTCPANEL_AUTHORHINT;Imie lub nazwa tworcy obiektu np. pisarza, fotografa lub grafika (w linii). +IPTCPANEL_AUTHORSPOSITION;Author's position +IPTCPANEL_AUTHORSPOSITIONHINT;Title of the creator or creators of the object (By-line Title). +IPTCPANEL_CAPTIONHINT;A textual description of the data (Caption - Abstract). +IPTCPANEL_CAPTION;Tytul +IPTCPANEL_CAPTIONWRITER;Caption Writer +IPTCPANEL_CAPTIONWRITERHINT;The name of the person involved in the writing, editing or correcting the image or caption/abstract (Writer - Editor). +IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider (Category). +IPTCPANEL_CATEGORY;Kategoria +IPTCPANEL_CITYHINT;City of image origin (City). +IPTCPANEL_CITY;Miasto +IPTCPANEL_COPYHINT;Copy IPTC settings to clipboard +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COPYRIGHTHINT;Any necessary copyright notice (Copyright Notice). +IPTCPANEL_COUNTRYHINT;The name of the country/primary location where the image was created (Country - Primary Location Name). +IPTCPANEL_COUNTRY;Kraj +IPTCPANEL_CREDIT;Credit +IPTCPANEL_CREDITHINT;Identifies the provider of the image, not necessarily the owner/creator (Credit). +IPTCPANEL_DATECREATED;Data utworzenia +IPTCPANEL_DATECREATEDHINT;The date the intellectual content of the image was created; Format: JJJJMMTT (Date Created). +IPTCPANEL_EMBEDDED;Embedded +IPTCPANEL_EMBEDDEDHINT;Reset to IPTC data embedded in the image file +IPTCPANEL_HEADLINEHINT;A publishable entry providing a synopsis of the contents of the image (Headline). +IPTCPANEL_HEADLINE;Naglowek +IPTCPANEL_INSTRUCTIONSHINT;Other editorial instructions concerning the use of the image (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Instrukcje +IPTCPANEL_KEYWORDSHINT;Used to indicate specific information retrieval words (Keywords). +IPTCPANEL_KEYWORDS;Slowa kluczowe +IPTCPANEL_PASTEHINT;Paste IPTC settings from clipboard +IPTCPANEL_PROVINCEHINT;The Province/State where the image originates (Province-State). +IPTCPANEL_PROVINCE;Stan, wojewodztwo, dystrykt itd. +IPTCPANEL_RESETHINT;Reset to profile default +IPTCPANEL_RESET;Reset +IPTCPANEL_SOURCEHINT;The original owner of the intellectual content of the image (Source). +IPTCPANEL_SOURCE;zrodlo +IPTCPANEL_SUPPCATEGORIESHINT;Further refines the subject of the image (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Suppl. Categories +IPTCPANEL_TITLEHINT;A shorthand reference for the image (Object Name). +IPTCPANEL_TITLE;Tytul +IPTCPANEL_TRANSREFERENCEHINT;A code representing the location of original transmission (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Trans. Reference +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Preferencje +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;Jako... +MAIN_BUTTON_SAVE;Zapisz obraz +MAIN_BUTTON_SENDTOEDITOR;Wyslij do edytora +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Plik juz istnieje. +MAIN_MSG_CANNOTLOAD;Nie mozna wczytac obrazu +MAIN_MSG_CANNOTSAVE;Blad zapisu pliku +MAIN_MSG_CANNOTSTARTEDITOR;Nie mozna uruchomic edytora. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Musisz wspisac prawidlowa sciezke w oknie "Preferencji". +MAIN_MSG_EXITJOBSINQUEUEINFO;Nieprzetworzone zdjecia w kolejce beda utracone po zamknieciu. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Jestes pewien, ze chcesz zamknac alpikacje? W kolejce znajduja sie nieprzetworzone zdjecia. +MAIN_MSG_JOBSINQUEUE;zadan w kolejce +MAIN_MSG_QOVERWRITE;Czy chcesz go zastapic? +MAIN_TAB_BASIC;Podstawowe +MAIN_TAB_COLOR;Kolor +MAIN_TAB_DETAIL;Szczegoly +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Ekspozycja +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadane +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Transformacje +MAIN_TOOLTIP_HIDEFP;Pokaz/ukryj dolny panel (przegladarka plikow i katalogow, shortcut key: F) +MAIN_TOOLTIP_HIDEHP;Pokaz/ukryj lewy panel (razem z historia, shortcut key: H) +MAIN_TOOLTIP_INDCLIPPEDH;Pokaz przeswietlenia +MAIN_TOOLTIP_INDCLIPPEDS;Pokaz niedoswietlenia +MAIN_TOOLTIP_PREFERENCES;Ustaw preferencje +MAIN_TOOLTIP_QINFO;Informacje o pliku +MAIN_TOOLTIP_SAVEAS;Zapisz obraz we wskazanym katalogu +MAIN_TOOLTIP_SAVE;Zapisz obraz w katalogu domyslnym +PARTIALPASTE_BASICGROUP;Podstawowe ustawienia +PARTIALPASTE_CACORRECTION;Korekcja C/A +PARTIALPASTE_COARSETRANS;Rotacja/odwrocenie o 90 stopni +PARTIALPASTE_COLORBOOST;Uwydatnienie koloru +PARTIALPASTE_COLORDENOISE;Odszumienie koloru +PARTIALPASTE_COLORGROUP;Ustawienia zwiazane z kolorem +PARTIALPASTE_COLORMIXER;Mikser koloru +PARTIALPASTE_COLORSHIFT;Przesuniecie koloru +PARTIALPASTE_COMPOSITIONGROUP;Ustawienia kompozycji +PARTIALPASTE_CROP;Przytnij +PARTIALPASTE_DIALOGLABEL;Partial paste processing profile +PARTIALPASTE_DISTORTION;Korekcja znieksztalcenia +PARTIALPASTE_EXIFCHANGES;Zmien dane Exif +PARTIALPASTE_EXPOSURE;Ekspozycja +PARTIALPASTE_HLRECOVERY;Highlight recovery +PARTIALPASTE_ICMSETTINGS;Ustawienia ICM +PARTIALPASTE_IPTCINFO;Informacje IPTC +PARTIALPASTE_LENSGROUP;Ustawienia zwiazane z obiektywem +PARTIALPASTE_LUMACURVE;Krzywa obiektywu +PARTIALPASTE_LUMADENOISE;Redukcja zaszumienia jaskrawosci +PARTIALPASTE_LUMINANCEGROUP;Ustawienia zwiazane z jaskrawoscia +PARTIALPASTE_METAICMGROUP;Metadanea/Ustawienia ICM +PARTIALPASTE_RESIZE;Zmien rozmiar +PARTIALPASTE_ROTATION;Rotacja +PARTIALPASTE_SHADOWSHIGHLIGHTS;Cienie/Podswietlenia +PARTIALPASTE_SHARPENING;Wyostrzanie +PARTIALPASTE_VIGNETTING;Korekcja winiety +PARTIALPASTE_WHITEBALANCE;Balans bieli +PREFERENCES_APPLNEXTSTARTUP;wymaga ponownego uruchomienia +PREFERENCES_BLINKCLIPPED;Mrugajace przeswietlenia +PREFERENCES_CACHECLEARALL;Wyczysc wszystko +PREFERENCES_CACHECLEARPROFILES;Wyczysc profile +PREFERENCES_CACHECLEARTHUMBS;Wyczysc miniaturki +PREFERENCES_CACHEFORMAT1;Proprietary (faster and better quality) +PREFERENCES_CACHEFORMAT2;JPEG (smaller disk footprint) +PREFERENCES_CACHEMAXENTRIES;Maksymalna liczba wpisow w pamieci podrecznej +PREFERENCES_CACHEOPTS;Opcje pamieci podrecznej +PREFERENCES_CACHESTRAT1;Prefer Speed to Low Memory Consumption +PREFERENCES_CACHESTRAT2;Prefer Low Memory Consumption to Speed +PREFERENCES_CACHESTRAT;Cache Strategy +PREFERENCES_CACHETHUMBFORM;Cache Thumbnail Format +PREFERENCES_CACHETHUMBHEIGHT;Maximal Thumbnail Height +PREFERENCES_CLEARDLG_LINE1;Czyszczenie pamieci podrecznej +PREFERENCES_CLEARDLG_LINE2;Moze to potrwac kilka sekund. +PREFERENCES_CLEARDLG_TITLE;Prosze czekac +PREFERENCES_CLIPPINGIND;Pokazywanie przeswietlen +PREFERENCES_CMETRICINTENT;Sposob odwzorowania barw +PREFERENCES_DATEFORMAT;Format daty +PREFERENCES_DATEFORMATHINT;You can use the following formatting strings:\n%y : year\n%m : month\n%d : day\n\nFor example, the hungarian date format is:\n%y/%m/%d +PREFERENCES_DEFAULTLANG;Jezyk domyslny +PREFERENCES_DEFAULTTHEME;Default theme +PREFERENCES_DEMOSAICINGALGO;Algorytm demozaikowania +PREFERENCES_DIRHOME;Katalog domowy +PREFERENCES_DIRLAST;Ostatnio odwiedzony katalog +PREFERENCES_DIROTHER;Inny +PREFERENCES_DIRSELECTDLG;Wybierz katalog z obrazami po uruchomieniu... +PREFERENCES_DIRSOFTWARE;Katalog instalacyjny +PREFERENCES_DMETHOD;Metoda +PREFERENCES_EDITORCMDLINE;Other command line +PREFERENCES_EXTERNALEDITOR;Zewnetrzny edytor +PREFERENCES_FALSECOLOR;Kroki zapobiegania zafalszowaniom kolorow +PREFERENCES_FBROWSEROPTS;Opcje przegladarki plikow +PREFERENCES_FILEFORMAT;Format pliku +PREFERENCES_FORIMAGE;Dla plikow z obrazami +PREFERENCES_FORRAW;Dla plikow RAW +PREFERENCES_GIMPPATH;Katalog, w ktorym zainstalowany jest GIMP +PREFERENCES_GTKTHEME;GTK default +PREFERENCES_HINT;Porada +PREFERENCES_HLTHRESHOLD;Prog dla przeswietleñ +PREFERENCES_ICCDIR;Katalog z profilami ICC +PREFERENCES_IMPROCPARAMS;Domyslne parametry przetwarzania obrazu +PREFERENCES_INTENT_ABSOLUTE;Absolutnie kolorymetryczny +PREFERENCES_INTENT_PERCEPTUAL;Percepcyjny +PREFERENCES_INTENT_RELATIVE;Wzglednie kolorymetryczny +PREFERENCES_INTENT_SATURATION;Nasyceniowy +PREFERENCES_LIVETHUMBNAILS;Miniaturki na zywo (wojniej) +PREFERENCES_MONITORICC;Profil monitora +PREFERENCES_OUTDIRFOLDERHINT;Umiesc zapisane zdjecia w wybranym katalogu +PREFERENCES_OUTDIRFOLDER;Zapisz do katalogu +PREFERENCES_OUTDIRHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIR;Katalog wyjsciowy +PREFERENCES_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Uzyj schemat +PREFERENCES_PARSEDEXTADD;Dodaj rozszerzenie +PREFERENCES_PARSEDEXTADDHINT;Type an extension and press this button to append list +PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list +PREFERENCES_PARSEDEXT;Parsed Extensions +PREFERENCES_PROFILEHANDLING;Processing Profile Handling +PREFERENCES_PROFILELOADPR;Profile Loading Priority +PREFERENCES_PROFILEPRCACHE;Profile in Cache +PREFERENCES_PROFILEPRFILE;Profile Next to the Input File +PREFERENCES_PROFILESAVECACHE;Save Processing Parameters to the Cache +PREFERENCES_PROFILESAVEINPUT;Save Processing Parameters Next to the Input File +PREFERENCES_PSPATH;Katalog w ktorym zainstalowany jest Adobe Photoshop +PREFERENCES_SELECTICCDIRDLG;Wybierz katalog z profilami ICC... +PREFERENCES_SELECTLANG;Wybierz jezyk +PREFERENCES_SELECTMONITORPROFDLG;Wybierz profil ICC do wyswietlenia... +PREFERENCES_SELECTTHEME;Select theme +PREFERENCES_SHOWBASICEXIF;Pokaz podstawowe dane Exif +PREFERENCES_SHOWDATETIME;Pokaz date i czas +PREFERENCES_SHOWONLYRAW;Pokaz tylko pliki RAW +PREFERENCES_SHTHRESHOLD;Prog dla niedoswietleñ +PREFERENCES_STARTUPIMDIR;Katalog startowy +PREFERENCES_TAB_BROWSER;Przegladarka plikow +PREFERENCES_TAB_COLORMGR;Zarzadzanie kolorami +PREFERENCES_TAB_GENERAL;Ogolne +PREFERENCES_TAB_IMPROC;Przetwarzanie obrazu +PREFERENCES_TAB_OUTPUT;Opcje wyjsciowe +PREFERENCES_THUMBSIZE;Wielkosc miniaturki +PROFILEPANEL_FILEDLGFILTERANY;Wszystkie pliki +PROFILEPANEL_FILEDLGFILTERPP;Profile postprocessingu +PROFILEPANEL_LABEL;Profil postprocessingu +PROFILEPANEL_LOADDLGLABEL;laduj parametry postprocessingu... +PROFILEPANEL_PCUSTOM;Reczny +PROFILEPANEL_PFILE;Z pliku +PROFILEPANEL_PLASTPHOTO;Ostatnie Zdjecie +PROFILEPANEL_PLASTSAVED;Ostatnio zapisany +PROFILEPANEL_PROFILE;Profil +PROFILEPANEL_SAVEDLGLABEL;Zapisz parametry postprocessingu... +PROFILEPANEL_TOOLTIPCOPY;Skopiuj aktualny profil do schowka +PROFILEPANEL_TOOLTIPLOAD;laduj profil z pliku +PROFILEPANEL_TOOLTIPPASTE;Wklej profil ze schowka +PROFILEPANEL_TOOLTIPSAVE;Zapisz aktualny profil +PROGRESSBAR_DECODING;Dekodowanie pliku raw... +PROGRESSBAR_DEMOSAICING;Demozaikowanie... +PROGRESSBAR_LOADING;Wczytywanie obrazu... +PROGRESSBAR_LOADJPEG;ladowanie pliku JPEG... +PROGRESSBAR_LOADPNG;ladowanie pliku PNG... +PROGRESSBAR_LOADTIFF;ladowanie pliku TIFF... +PROGRESSBAR_PROCESSING;Przetwarzanie obrazu... +PROGRESSBAR_READY;Gotowe. +PROGRESSBAR_SAVEJPEG;Zapisywanie pliku JPEG... +PROGRESSBAR_SAVEPNG;Zapisywanie pliku PNG... +PROGRESSBAR_SAVETIFF;Zapisywanie pliku TIFF... +PROGRESSDLG_LOADING;Wczytywanie pliku... +PROGRESSDLG_PROCESSING;Przetwarzanie zdjecia... +PROGRESSDLG_SAVING;Zapisywanie pliku... +QINFO_FOCALLENGTH;Ogniskowa +QINFO_ISO;ISO +QINFO_LENS;Obiektyw +QINFO_NOEXIF;Dane exif niedostepne. +SAVEDLG_FILEFORMAT;Format pliku +SAVEDLG_JPEGQUAL;Jakosc JPEG +SAVEDLG_JPGFILTER;Pliki JPEG +SAVEDLG_PNGCOMPR;Kompresja PNG +SAVEDLG_PNGFILTER;Pliki PNG +SAVEDLG_PUTTOQUEUEHEAD;Put to the head of the processing queue +SAVEDLG_PUTTOQUEUE;Put into processing queue +SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue +SAVEDLG_SAVEIMMEDIATELY;Save immediately +SAVEDLG_SAVESPP;Zapisz parametry przetwarzania wraz z obrazem +SAVEDLG_TIFFFILTER;Pliki TIFF +TOOLBAR_TOOLTIP_CROP;Kadruj (shortcut key: C) +TOOLBAR_TOOLTIP_HAND;Przesun (shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Wyprostuj obraz (shortcut key: S) +TOOLBAR_TOOLTIP_WB;Wskaz balans bieli (shortcut key: W) +TP_CACORRECTION_BLUE;Niebieski +TP_CACORRECTION_LABEL;Korekcja AC +TP_CACORRECTION_RED;Czerwony +TP_CHMIXER_BLUE;Niebieski +TP_CHMIXER_GREEN;Zielony +TP_CHMIXER_LABEL;Mikser kanalow +TP_CHMIXER_RED;Czerwony +TP_COARSETRAF_DEGREE;stopnie: +TP_COARSETRAF_TOOLTIP_HFLIP;Odbij w poziomie +TP_COARSETRAF_TOOLTIP_ROTLEFT;Obroc w lewo +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Obroc w prawo +TP_COARSETRAF_TOOLTIP_VFLIP;Odbij w pionie +TP_COLORBOOST_ACHANNEL;kanal "a" +TP_COLORBOOST_AMOUNT;Stopien +TP_COLORBOOST_AVOIDCOLORCLIP;Unikaj przycinania kolorow +TP_COLORBOOST_BCHANNEL;kanal "b" +TP_COLORBOOST_CHAB;a i b +TP_COLORBOOST_CHANNEL;Kanal +TP_COLORBOOST_CHSEPARATE;oddzielnie +TP_COLORBOOST_ENABLESATLIMITER;Wlacz limit saturacji +TP_COLORBOOST_LABEL;Wzmocnienie koloru +TP_COLORBOOST_SATLIMIT;Limit saturacji +TP_COLORDENOISE_EDGESENSITIVE;Czulosc krawedzi +TP_COLORDENOISE_EDGETOLERANCE;Tolerancja krawedzi +TP_COLORDENOISE_LABEL;Odszumianie koloru +TP_COLORDENOISE_RADIUS;Promien +TP_COLORSHIFT_BLUEYELLOW;Blekit-zolty +TP_COLORSHIFT_GREENMAGENTA;Zielen-magenta +TP_COLORSHIFT_LABEL;Przesuniecie koloru +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Zablokuj proporcje: +TP_CROP_GTDIAGONALS;Przekatna +TP_CROP_GTHARMMEANS1;Zloty podzial 1 +TP_CROP_GTHARMMEANS2;Zloty podzial 2 +TP_CROP_GTHARMMEANS3;Zloty podzial 3 +TP_CROP_GTHARMMEANS4;Zloty podzial 4 +TP_CROP_GTNONE;Nic +TP_CROP_GTRULETHIRDS;Trojpodzial +TP_CROP_GUIDETYPE;Typ pomocy: +TP_CROP_H;W +TP_CROP_LABEL;Kadrowanie +TP_CROP_SELECTCROP;Wybierz kadr +TP_CROP_W;S +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Sila +TP_DISTORTION_LABEL;Dystorsja +TP_EXPOSURE_AUTOLEVELS;Wyrownaj poziomy +TP_EXPOSURE_BLACKLEVEL;Czern +TP_EXPOSURE_BRIGHTNESS;Jasnosc +TP_EXPOSURE_CLIP;Przytnij +TP_EXPOSURE_COMPRHIGHLIGHTS;Kompresja swiatel +TP_EXPOSURE_COMPRSHADOWS;Kompresja cieni +TP_EXPOSURE_CONTRAST;Kontrast +TP_EXPOSURE_CURVEEDITOR;Krzywa tonalna +TP_EXPOSURE_EXPCOMP;EV +TP_EXPOSURE_LABEL;Ekspozycja +TP_HLREC_CIELAB;Mieszanie koloru CIELab +TP_HLREC_COLOR;Propagacja koloru +TP_HLREC_LABEL;Odzyskiwanie przeswietlen +TP_HLREC_LUMINANCE;Odzyskiwanie luminancji +TP_HLREC_METHOD;Metoda: +TP_ICM_FILEDLGFILTERANY;Wszystkie pliki +TP_ICM_FILEDLGFILTERICM;Pliki z profilami ICC +TP_ICM_GAMMABEFOREINPUT;Profile applies Gamma +TP_ICM_INPUTCAMERA;Domyslny aparatu +TP_ICM_INPUTCUSTOM;Reczny +TP_ICM_INPUTDLGLABEL;Wybierz wejsciowy profil ICC... +TP_ICM_INPUTEMBEDDED;Jesli to mozliwe, uzyj osadzonego +TP_ICM_INPUTPROFILE;Profil wejsciowy +TP_ICM_LABEL;ICM +TP_ICM_NOICM;No ICM: Wyjscie sRGB +TP_ICM_OUTPUTDLGLABEL;Wybierz wyjsciowy profil ICC... +TP_ICM_OUTPUTPROFILE;Profil wyjsciowy +TP_ICM_SAVEREFERENCE;Save reference image for profiling +TP_ICM_WORKINGPROFILE;Profil roboczy +TP_LUMACURVE_BLACKLEVEL;Czern +TP_LUMACURVE_BRIGHTNESS;Jasnosc +TP_LUMACURVE_COMPRHIGHLIGHTS;Kompresja swiatel +TP_LUMACURVE_COMPRSHADOWS;Kompresja cieni +TP_LUMACURVE_CONTRAST;Kontrast +TP_LUMACURVE_CURVEEDITOR;Krzywa luminancji +TP_LUMACURVE_LABEL;Krzywa luminancji +TP_LUMADENOISE_EDGETOLERANCE;Tolerancja krawedzi +TP_LUMADENOISE_LABEL;Odszumianie luminancji +TP_LUMADENOISE_RADIUS;Promien +TP_RESIZE_BICUBIC;Bicubic +TP_RESIZE_BICUBICSF;Bicubic (Miekko) +TP_RESIZE_BICUBICSH;Bicubic (Ostro) +TP_RESIZE_BILINEAR;Bilinear +TP_RESIZE_FULLSIZE;Pelny rozmiar obrazu: +TP_RESIZE_H;W: +TP_RESIZE_LABEL;Skalowanie +TP_RESIZE_METHOD;Metoda: +TP_RESIZE_NEAREST;Najblizsza +TP_RESIZE_SCALE;Skala +TP_RESIZE_W;S: +TP_ROTATE_AUTOCROP;Auto przycinanie +TP_ROTATE_DEGREE;Stopnie +TP_ROTATE_FILL;Wypelnij +TP_ROTATE_LABEL;Obrot +TP_ROTATE_SELECTLINE;Wyprostuj obraz +TP_SHADOWSHLIGHTS_HIGHLIGHTS;swiatla +TP_SHADOWSHLIGHTS_HLTONALW;Szerokosc tonalna +TP_SHADOWSHLIGHTS_LABEL;Cienie/swiatla +TP_SHADOWSHLIGHTS_LOCALCONTR;Kontrast lokalny +TP_SHADOWSHLIGHTS_RADIUS;Promien +TP_SHADOWSHLIGHTS_SHADOWS;Cienie +TP_SHADOWSHLIGHTS_SHTONALW;Szerokosc tonalna +TP_SHARPENING_AMOUNT;Sila +TP_SHARPENING_EDRADIUS;Promien +TP_SHARPENING_EDTOLERANCE;Tolerancja +TP_SHARPENING_HALOCONTROL;Kontrola poswiaty +TP_SHARPENING_HCAMOUNT;Sila +TP_SHARPENING_LABEL;Wyostrzanie +TP_SHARPENING_METHOD;Metoda +TP_SHARPENING_ONLYEDGES;Wyostrz tylko krawedzie +TP_SHARPENING_RADIUS;Promien +TP_SHARPENING_RLD_AMOUNT;Sila +TP_SHARPENING_RLD_DAMPING;Tlumienie +TP_SHARPENING_RLD;Dekonwolucja RL +TP_SHARPENING_RLD_ITERATIONS;Iteracje +TP_SHARPENING_THRESHOLD;Prog +TP_SHARPENING_USM;Maska wyostrzajaca +TP_VIGNETTING_AMOUNT;Sila +TP_VIGNETTING_LABEL;Korekcja winietowania +TP_VIGNETTING_RADIUS;Promien +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Z aparatu +TP_WBALANCE_CUSTOM;Reczny +TP_WBALANCE_GREEN;Odcien +TP_WBALANCE_LABEL;Balans bieli +TP_WBALANCE_METHOD;Metoda +TP_WBALANCE_SIZE;Wielkosc: +TP_WBALANCE_SPOTWB;Punktowy +TP_WBALANCE_TEMPERATURE;Temperatura +ZOOMBAR_DETAIL;Lupa +ZOOMBAR_HUGE;Olbrzymia +ZOOMBAR_LARGE;Duza +ZOOMBAR_NORMAL;Normalna +ZOOMBAR_PREVIEW;Widok +ZOOMBAR_SCALE;Skala +ZOOMBAR_SMALL;Mala + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Portugues (Brasil) b/rtdata/languages/Portugues (Brasil) new file mode 100644 index 000000000..d260471a6 --- /dev/null +++ b/rtdata/languages/Portugues (Brasil) @@ -0,0 +1,703 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# Português Brasileiro +# 01.02.2010: Vitor da Silva Gonçalves +# +ADJUSTER_RESET_TO_DEFAULT;Restaurar para o padrão +CURVEEDITOR_FILEDLGFILTERANY;Quaisquer Arquivos +CURVEEDITOR_FILEDLGFILTERCURVE;Arquivos de curva +CURVEEDITOR_LINEAR;Linear +CURVEEDITOR_LOADDLGLABEL;Carregar Curva... +CURVEEDITOR_SAVEDLGLABEL;Salvar Curva... +CURVEEDITOR_TOOLTIPLINEAR;Restaurar curva para linha +CURVEEDITOR_TOOLTIPLOAD;Carregar uma Curva a Partir de Arquivo +CURVEEDITOR_TOOLTIPSAVE;Salvar Arquivo Atual +EXIFFILTER_APERTURE;Abertura +EXIFFILTER_CAMERA;Câmera +EXIFFILTER_DIALOGLABEL;Filtro Exif +EXIFFILTER_FOCALLEN;Distância Focal +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Lente +EXIFFILTER_SHUTTER;Obturador +EXIFPANEL_ADDEDIT;Adicionar/Editar +EXIFPANEL_ADDEDITHINT;Adicionar nova etiqueta ou editá-la +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Entre um valor +EXIFPANEL_ADDTAGDLG_SELECTTAG;Selecione uma etiqueta +EXIFPANEL_ADDTAGDLG_TITLE;Adicionar/Editar etiqueta +EXIFPANEL_KEEPHINT;Manter as etiquetas selecionadas ao escrever arquivo de saída +EXIFPANEL_KEEP;Manter +EXIFPANEL_REMOVEHINT;Remover as etiquetas selecionadas ao escrever arquivo de saída +EXIFPANEL_REMOVE;Remover +EXIFPANEL_RESETALLHINT;Restaurar todas as etiquetas a seus valores originais +EXIFPANEL_RESETALL;Restaurar Tudo +EXIFPANEL_RESETHINT;Restaurar todas as etiquetas selecionadas a seus valores originais +EXIFPANEL_RESET;Restaurar +EXIFPANEL_SUBDIRECTORY;Subdiretório +FILEBROWSER_APPLYPROFILE;Aplicar Perfil +FILEBROWSER_ARRANGEMENTHINT;Alternar entre alinhamento vertical/horizontal das miniaturas +FILEBROWSER_CLEARPROFILE;Limpar Perfil +FILEBROWSER_COPYPROFILE;Copiar Perfil +FILEBROWSER_DELETEDLGLABEL;Confirmação para Apagar Arquivo +FILEBROWSER_DELETEDLGMSG;Tem certeza de que deseja apagar os %1 arquivos selecionados? +FILEBROWSER_EMPTYTRASH;Esvaziar Lixeira +FILEBROWSER_EMPTYTRASHHINT;Remove permanentemente os arquivos da lixeira +FILEBROWSER_EXIFFILTERAPPLY;Aplicar +FILEBROWSER_EXIFFILTERAPPLYHINT; Habilitar/Desabilitar Filtro exif do navegador de arquivos +FILEBROWSER_EXIFFILTERLABEL;Filtro Exif +FILEBROWSER_EXIFFILTERSETTINGS;Configuração +FILEBROWSER_EXIFFILTERSETTINGSHINT;Alterar configurações do filtro exif +FILEBROWSER_PARTIALPASTEPROFILE;Colar parcialmente +FILEBROWSER_PASTEPROFILE;Colar Perfil +FILEBROWSER_POPUPCANCELJOB;Cancelar trabalho +FILEBROWSER_POPUPMOVEEND;Mover para o fim da fila +FILEBROWSER_POPUPMOVEHEAD;Mover para o início da fila +FILEBROWSER_POPUPOPEN;Abrir +FILEBROWSER_POPUPPROCESS;Colocar na fila de processamento +FILEBROWSER_POPUPRANK1;Classificação 1 +FILEBROWSER_POPUPRANK2;Classificação 2 +FILEBROWSER_POPUPRANK3;Classificação 3 +FILEBROWSER_POPUPRANK4;Classificação 4 +FILEBROWSER_POPUPRANK5;Classificação 5 +FILEBROWSER_POPUPREMOVE;Remover do sistema de arquivos +FILEBROWSER_POPUPRENAME;Renomear +FILEBROWSER_POPUPSELECTALL;Selecionar tudo +FILEBROWSER_POPUPTRASH;Mover para a lixeira +FILEBROWSER_POPUPUNRANK;Desclassificar +FILEBROWSER_POPUPUNTRASH;Remover da lixeira +FILEBROWSER_PROCESSINGSETTINGS;Configurações +FILEBROWSER_PROCESSINGSETTINGSHINT;Ajustar o formato de arquivo e diretório de saída +FILEBROWSER_RENAMEDLGLABEL;Renomear arquivo +FILEBROWSER_RENAMEDLGMSG;Renomear arquivo "%1" como: +FILEBROWSER_SHOWDIRHINT;Exibir todas as imagens do diretório +FILEBROWSER_SHOWQUEUEHINT;Exibir conteúdo da fila de processamento +FILEBROWSER_SHOWRANK1HINT;Exibir imagens classificadas como 1 estrela +FILEBROWSER_SHOWRANK2HINT;Exibir imagens classificadas como 2 estrelas +FILEBROWSER_SHOWRANK3HINT;Exibir imagens classificadas como 3 estrelas +FILEBROWSER_SHOWRANK4HINT;Exibir imagens classificadas como 4 estrelas +FILEBROWSER_SHOWRANK5HINT;Exibir imagens classificadas como 5 estrelas +FILEBROWSER_SHOWTRASHHINT;Exibir conteúdo da lixeira +FILEBROWSER_SHOWUNRANKHINT;Exibir imagens não classificadas +FILEBROWSER_STARTPROCESSINGHINT;Iniciar processamento/salvar imagens da lista +FILEBROWSER_STARTPROCESSING;Iniciar Processamento +FILEBROWSER_STOPPROCESSINGHINT;Para o processamento das imagens +FILEBROWSER_STOPPROCESSING;Parar processamento +FILEBROWSER_THUMBSIZE;Tamanho das Miniaturas +FILEBROWSER_ZOOMINHINT;Aumentar Tamanho das Miniaturas +FILEBROWSER_ZOOMOUTHINT;Diminuir Tamanho das Miniaturas +GENERAL_ABOUT;Sobre +GENERAL_CANCEL;Cancelar +GENERAL_DISABLED;Desabilitado +GENERAL_DISABLE;Desabilitar +GENERAL_ENABLED;Habilitado +GENERAL_ENABLE;Habilitar +GENERAL_LANDSCAPE;Paisagem +GENERAL_LOAD;Carregar +GENERAL_NA;n/a +GENERAL_NO;Não +GENERAL_OK;OK +GENERAL_PORTRAIT;Retrato +GENERAL_SAVE;Salvar +GENERAL_YES;Sim +HISTOGRAM_LABEL;Histograma +HISTOGRAM_TOOLTIP_B;Mostrar/Esconder histograma AZUL +HISTOGRAM_TOOLTIP_G;Mostrar/Esconder histograma VERDE +HISTOGRAM_TOOLTIP_L;Mostrar/Esconder histograma CIELAB +HISTOGRAM_TOOLTIP_R;Mostrar/Esconder histograma VERMELHO +HISTORY_CHANGED;Alterado +HISTORY_CUSTOMCURVE;Curva personalizada +HISTORY_DELSNAPSHOT;Apagar +HISTORY_FROMCLIPBOARD;Da área de transferência +HISTORY_LABEL;Histórico +HISTORY_MSG_10;Compressão de Sombras +HISTORY_MSG_11;Curva de Tons +HISTORY_MSG_12;Exposição Automática +HISTORY_MSG_13;Clipping de Exposição +HISTORY_MSG_14;Brilho de Luminância +HISTORY_MSG_15;Contraste de Luminância +HISTORY_MSG_16;Luminância do Preto +HISTORY_MSG_17;Compressão do Foco de Luminância +HISTORY_MSG_18;Compressão das sombras de Luminância +HISTORY_MSG_19;Curva de Luminância +HISTORY_MSG_1;Foto carregada +HISTORY_MSG_20;Tornar Nítido +HISTORY_MSG_21;Raio de Nitidez +HISTORY_MSG_22;Quantidade de Nitidez +HISTORY_MSG_23;Limiar de Nitidez +HISTORY_MSG_24;Tornar nítido apenas as bordas +HISTORY_MSG_25;Raio de Detecção de Bordas de Nitidez +HISTORY_MSG_26;Tolerância da nitidez das bordas +HISTORY_MSG_27;Controle de luz na nitidez +HISTORY_MSG_28;Quantidade do Controle de Luz +HISTORY_MSG_29;Método de Nitidez +HISTORY_MSG_2;Perfil Carregado +HISTORY_MSG_30;Raio de Desconvolução +HISTORY_MSG_31;Quantidade de Desconvolução +HISTORY_MSG_32;Umedecimento de Desconvolução +HISTORY_MSG_33;Interações de Desconvolução +HISTORY_MSG_34;Evitar Clipping de Cor +HISTORY_MSG_35;Limitador de Saturação +HISTORY_MSG_36;limite de Saturação +HISTORY_MSG_37;Melhoria de Cor +HISTORY_MSG_38;Método do Balanço do Branco +HISTORY_MSG_39;Temperatura de Cor +HISTORY_MSG_3;Perfil Alterado +HISTORY_MSG_40;Tonalidade do Balanço de Branco +HISTORY_MSG_41;Deslocamento da Cor "A" +HISTORY_MSG_42;Deslocamento da Cor "B" +HISTORY_MSG_43;Remoção de ruídos da luminância +HISTORY_MSG_44;Raio da remoção de ruídos da lum. +HISTORY_MSG_45;Tolerância de bordas da remoção de ruídos da lum. +HISTORY_MSG_46;Remoção de ruídos da cor +HISTORY_MSG_47;Raio da remoção de ruídos da cor +HISTORY_MSG_48;Tolerância de bordas da remoção de ruídos da cor +HISTORY_MSG_49;Remoção de ruidos da cor sensível a bordas +HISTORY_MSG_4;Navegador do histórico +HISTORY_MSG_50;Ferramenta Sombra/Luz +HISTORY_MSG_51;Melhora de luz +HISTORY_MSG_52;Melhora de Sombras +HISTORY_MSG_53;Largura de Tons da Luz +HISTORY_MSG_54;Largura de Tons das Sombras +HISTORY_MSG_55;Contraste Local +HISTORY_MSG_56;Raio de Luz/Sombra +HISTORY_MSG_57;Coarse Rotation +HISTORY_MSG_58;Inversão Horizontal +HISTORY_MSG_59;Inversão Vertical +HISTORY_MSG_5;Brilho +HISTORY_MSG_60;Rotação +HISTORY_MSG_61;Rotação +HISTORY_MSG_62;Correção de Distorção de Lente +HISTORY_MSG_63;Snapshot Selecionado +HISTORY_MSG_64;Cortar Foto +HISTORY_MSG_65;Correção de C/A +HISTORY_MSG_66;Recuperação de Luz +HISTORY_MSG_67;Quantidade de Recuperação +HISTORY_MSG_68;Método de Recuperação +HISTORY_MSG_69;Espaço de atuação da cor +HISTORY_MSG_6;Contraste +HISTORY_MSG_70;Espaço de Cor de Saída +HISTORY_MSG_71;Espaço de Cor de Entrada +HISTORY_MSG_72;Correção de Vinheta +HISTORY_MSG_73;Misturador de Canais +HISTORY_MSG_74;Escala de Redimensionamento +HISTORY_MSG_75;Método de Redimensionamento +HISTORY_MSG_76;Metadados Exif +HISTORY_MSG_77;Metadados IPTC +HISTORY_MSG_78;Dados especificados para redimensionamento +HISTORY_MSG_79;Largura do redimensionamento +HISTORY_MSG_7;Preto +HISTORY_MSG_80;Altura do redimensionamento +HISTORY_MSG_81;Redimensionamento habilitado +HISTORY_MSG_8;Compensação de Exposição +HISTORY_MSG_9;Compressão da Luz +HISTORY_NEWSNAPSHOT;Adicionar +HISTORY_NEWSNAPSHOTAS;Como... +HISTORY_NEWSSDIALOGLABEL;Etiqueta do snapshot: +HISTORY_NEWSSDIALOGTITLE;Adicionar novo snapshot +HISTORY_SETTO;Ajustar para +HISTORY_SNAPSHOT;Snapshot +HISTORY_SNAPSHOTS;Snapshots +ICMPANEL_FILEDLGFILTERANY;Quaisquer arquivos +ICMPANEL_FILEDLGFILTERICM;ICC Profile Files +ICMPANEL_GAMMABEFOREINPUT;Profile applies Gamma +ICMPANEL_INPUTCAMERA;Padrão de câmera +ICMPANEL_INPUTCUSTOM;Personalizado +ICMPANEL_INPUTDLGLABEL;selecionar perfil de entrada ICC.. +ICMPANEL_INPUTEMBEDDED;Utilizar encaixe, se possível +ICMPANEL_INPUTPROFILE;Perfil de entrada +ICMPANEL_NOICM;No ICM: Saída sRGB +ICMPANEL_OUTPUTDLGLABEL;Selecionar perfil de saída ICC... +ICMPANEL_OUTPUTPROFILE;Perfil de saída +ICMPANEL_SAVEREFERENCE;Salvar imagem de referência para perfis +ICMPANEL_WORKINGPROFILE;Prefil de atuação +IMAGEAREA_DETAILVIEW;visualisação de detalhes +IPTCPANEL_AUTHOR;Autor +IPTCPANEL_AUTHORHINT;Nome do criador do objeto, escritor, fotógrafo o artista gráfico. +IPTCPANEL_AUTHORSPOSITIONHINT;Título do criador ou criadores do objeto. +IPTCPANEL_AUTHORSPOSITION;Posição do autor +IPTCPANEL_CAPTIONHINT;Uma descrição dos dados em forma de texto. +IPTCPANEL_CAPTION;Legenda +IPTCPANEL_CAPTIONWRITER;Autor da Legenda +IPTCPANEL_CAPTIONWRITERHINT;o nome da pessoa envolvida na escrita, edição ou correção da imagem ou legenda/resumo. +IPTCPANEL_CATEGORY;Categoria +IPTCPANEL_CATEGORYHINT;Identifica o assunto da imagem (Categoria). +IPTCPANEL_CITY;Cidade +IPTCPANEL_CITYHINT;Cidade de origem da imagem. +IPTCPANEL_COPYHINT;Copiar configurações IPTC da área de transferência +IPTCPANEL_COPYRIGHT;Direios autorais (Copyright). +IPTCPANEL_COPYRIGHTHINT;qualquer informação necessário sobre os direitos autorais. +IPTCPANEL_COUNTRYHINT;O nome do país onde a imagem foi criada. +IPTCPANEL_COUNTRY;País +IPTCPANEL_CREDIT;Créditos +IPTCPANEL_CREDITHINT;Identifica o provedor da imagem, nçao necessariamente o proprietário/criador. +IPTCPANEL_DATECREATED;Data de criação +IPTCPANEL_DATECREATEDHINT;A data em que o conteúdo intelectual da imagem foi criado; Formato: AAAAMMDD. +IPTCPANEL_EMBEDDED;Embedded +IPTCPANEL_EMBEDDEDHINT;Restaura para IPTC os dados encaixados na imagem +IPTCPANEL_HEADLINEHINT;Uma entrada publicável que com uma sinopse dos conteúdos da imagem. +IPTCPANEL_HEADLINE;Título +IPTCPANEL_INSTRUCTIONSHINT;Outras instruções editorias sobre o uso da imagem. +IPTCPANEL_INSTRUCTIONS;Instruções +IPTCPANEL_KEYWORDSHINT;Utilizado para indicar informações especificas. +IPTCPANEL_KEYWORDS;Palavras-chave +IPTCPANEL_PASTEHINT;colar configurações IPTC da área de transferência +IPTCPANEL_PROVINCEHINT;o Estado/província de origem da imagem. +IPTCPANEL_PROVINCE;Província +IPTCPANEL_RESETHINT;Restaurar paara o padrão do perfil +IPTCPANEL_RESET;Restaurar +IPTCPANEL_SOURCE;Fonte +IPTCPANEL_SOURCEHINT;o proprietário original do contepudo intelectual da imagem. +IPTCPANEL_SUPPCATEGORIES; Categorias Adicionais +IPTCPANEL_SUPPCATEGORIESHINT;Mais informações sobre o assunto da imagem. +IPTCPANEL_TITLEHINT;Uma referência rápida da imagem. +IPTCPANEL_TITLE;Título +IPTCPANEL_TRANSREFERENCEHINT;Um código representando a localização da transmissão original. +IPTCPANEL_TRANSREFERENCE;Trans. Referência +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Preferências +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;Como... +MAIN_BUTTON_SAVE;Salvar Imagem +MAIN_BUTTON_SENDTOEDITOR;Enviar ao Editor +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Arquivo Já Existe. +MAIN_MSG_CANNOTLOAD;Não foi possível carregar a imagem +MAIN_MSG_CANNOTSAVE;Erro ao salvar arquivo +MAIN_MSG_CANNOTSTARTEDITOR;Não foi possível iniciar o editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;por favor ajuste corretamente o caminho no diálogo "Preferências". +MAIN_MSG_EXITJOBSINQUEUEINFO;As imagens da lista que não foram processadas serão perdidas. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Tem certeza de que deseja sair? Há imagens na lista que ainda não foram processadas. +MAIN_MSG_JOBSINQUEUE;trabalho(s) na fila +MAIN_MSG_QOVERWRITE;Deseja sobreescrever? +MAIN_TAB_BASIC;Básico +MAIN_TAB_COLOR;Cor +MAIN_TAB_DETAIL;Detalhes +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Exposição +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadados +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Transformar +MAIN_TOOLTIP_HIDEFP;Mostrar/esconder o painel inferior (diretórios and navegador de arquivos, tecla de atalho: F) +MAIN_TOOLTIP_HIDEHP;Mostrar/esconder o painel à esquerda (incluindo o histórico, tecla de atallho: H) +MAIN_TOOLTIP_INDCLIPPEDH;Indicação de luz recortada +MAIN_TOOLTIP_INDCLIPPEDS;Indicação de sombra recortada +MAIN_TOOLTIP_PREFERENCES;Ajustar preferências +MAIN_TOOLTIP_QINFO;Informações rápidas da imagem +MAIN_TOOLTIP_SAVEAS;Salvar imagem em uma pasta selecionada +MAIN_TOOLTIP_SAVE;Salvar imagem na pasta padrão +PARTIALPASTE_BASICGROUP;Configurações básicas +PARTIALPASTE_CACORRECTION;Correção C/A +PARTIALPASTE_COARSETRANS;Rotação de 90 graus +PARTIALPASTE_COLORBOOST;Melhoria de Cor +PARTIALPASTE_COLORDENOISE;Redução de ruídos da cor +PARTIALPASTE_COLORGROUP;Configurações relacionadas à cor +PARTIALPASTE_COLORMIXER;Misturador de Cores +PARTIALPASTE_COLORSHIFT;Mudança de Cor +PARTIALPASTE_COMPOSITIONGROUP;Configurações de composição +PARTIALPASTE_CROP;Cortar +PARTIALPASTE_DIALOGLABEL;Perfil de processamento de colagem parcial +PARTIALPASTE_DISTORTION;Correção de Distorção +PARTIALPASTE_EXIFCHANGES;alterações dos dados exif +PARTIALPASTE_EXPOSURE;Exposição +PARTIALPASTE_HLRECOVERY;Recuperação de Luz +PARTIALPASTE_ICMSETTINGS;Configurações ICM +PARTIALPASTE_IPTCINFO;informações IPTC +PARTIALPASTE_LENSGROUP;Configurações relacionadas à Lente +PARTIALPASTE_LUMACURVE;Curva de luminância +PARTIALPASTE_LUMADENOISE;Redução de ruídos da luminância +PARTIALPASTE_LUMINANCEGROUP;Configurações relacionadas à luminância +PARTIALPASTE_METAICMGROUP;Metadados/configurações ICM +PARTIALPASTE_RESIZE;Redimensionar +PARTIALPASTE_ROTATION;Rotação +PARTIALPASTE_SHADOWSHIGHLIGHTS;Sombra/Luz +PARTIALPASTE_SHARPENING;Nitidez +PARTIALPASTE_VIGNETTING;Correção de vinheta +PARTIALPASTE_WHITEBALANCE;Balanço do branco +PREFERENCES_APPLNEXTSTARTUP;Aplicadas na próxima inicialização +PREFERENCES_BLINKCLIPPED;Piscar áreas recortadas +PREFERENCES_CACHECLEARALL;Limpar Tudo +PREFERENCES_CACHECLEARPROFILES;Limpar perfis +PREFERENCES_CACHECLEARTHUMBS;Limpar Miniaturas +PREFERENCES_CACHEFORMAT1;Proprietário (mais rápido e melhor qualidade) +PREFERENCES_CACHEFORMAT2;JPEG (Menor espaço em disco) +PREFERENCES_CACHEMAXENTRIES;Número máximo de entradas no cache +PREFERENCES_CACHEOPTS;Opções de Cache +PREFERENCES_CACHESTRAT1;Preferir velocidade a baixo consumo de memória +PREFERENCES_CACHESTRAT2;Preferir baixo consumo de memória a velocidade +PREFERENCES_CACHESTRAT;Estratégia de Cache +PREFERENCES_CACHETHUMBFORM;Formato das miniaturas no cache +PREFERENCES_CACHETHUMBHEIGHT;Tamanho máximo das miniaturas +PREFERENCES_CLEARDLG_LINE1;Limpando cache +PREFERENCES_CLEARDLG_LINE2;Isto pode levar alguns segundos. +PREFERENCES_CLEARDLG_TITLE;Por favor aguarde +PREFERENCES_CLIPPINGIND;Recortando indicação +PREFERENCES_CMETRICINTENT;Intenção colorimétrica +PREFERENCES_DATEFORMAT;Formato de data +PREFERENCES_DATEFORMATHINT;Você pode usar as seguintes formatações:\n%a : ano\n%m : mês\n%d : dia\n\nPor exemplo, o formato de data húngaro é:\n%a/%m/%d +PREFERENCES_DEFAULTLANG;Idioma padrão +PREFERENCES_DEFAULTTHEME;Tema padrão +PREFERENCES_DEMOSAICINGALGO;Algorítmo de remoção de mosaico +PREFERENCES_DIRHOME;Directory inicial +PREFERENCES_DIRLAST;Último directory visitado +PREFERENCES_DIROTHER;Outro +PREFERENCES_DIRSELECTDLG;selecionar diretório de imagem na inicialização... +PREFERENCES_DIRSOFTWARE;Diretório de instalação +PREFERENCES_DMETHOD;Método +PREFERENCES_EDITORCMDLINE;Outra Linha de Comando +PREFERENCES_EXTERNALEDITOR;Editor externo +PREFERENCES_FALSECOLOR;Supressão de cor falsa +PREFERENCES_FBROWSEROPTS;Opções do navegador de arquivos +PREFERENCES_FILEFORMAT;Formato de arquivo +PREFERENCES_FORIMAGE;Para arquivos de imagem +PREFERENCES_FORRAW;Para arquivos RAW +PREFERENCES_GIMPPATH;Diretório de Instalação do GIMP +PREFERENCES_GTKTHEME;Padrão do GTK +PREFERENCES_HINT;Dica +PREFERENCES_HLTHRESHOLD;ponto inicial para luzes recortadas +PREFERENCES_ICCDIR;Diretório de perfis ICC +PREFERENCES_IMPROCPARAMS;Parâmetros padrões de processamento de imagem +PREFERENCES_INTENT_ABSOLUTE;Colorimétrico Absoluto +PREFERENCES_INTENT_PERCEPTUAL;Perceptual +PREFERENCES_INTENT_RELATIVE;Colorimétrico Relativo +PREFERENCES_INTENT_SATURATION;Saturação +PREFERENCES_LIVETHUMBNAILS;Miniaturas em tempo real (mais lento) +PREFERENCES_MONITORICC;Monitorar perfil +PREFERENCES_OUTDIR;Diretório de Saída +PREFERENCES_OUTDIRFOLDERHINT;Colocar as imagens salvas na pasta selecionada +PREFERENCES_OUTDIRFOLDER;Salvar em folder +PREFERENCES_OUTDIRHINT;Você pode utilizar a seguinte formatação:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nEsta formatação se refere aos diretórios e subdiretórios do caminho do arquivo raw.\n\nPor exemplo, se /home/tom/image/02-09-2006/dsc0012.neffoi aberto, significa que a formatação é:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nSe você deseja salvar a imagem de saída onde está a original, escreva:\n%p1/%f\n\nSe você deseja salvar a imagem de saída em um diretório 'convertido' localizado no mesmo diretório que a original, escreva:\n%p1/converted/%f\n\nSe você deseja salvar a imagem de saída no diretório '/home/tom/converted' mantendo o mesmo subdiretório de datas, escreva:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;Você pode utilizar a seguinte formatação:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nEsta formatação se refere aos diretórios e subdiretórios do caminho do arquivo raw.\n\npor exemplo, se /home/tom/image/02-09-2006/dsc0012.neffoi aberto, significa que a formatação é:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nSe você deseja salvar a imagem de saída onde está a original, escreva:\n%p1/%f\n\nSe você deseja salvar a imagem de saída em um diretório 'convertido' localizado no mesmo diretório que a original, escreva:\n%p1/converted/%f\n\nSe você deseja salvar a imagem de saída no diretório '/home/tom/converted' mantendo o mesmo subdiretório de datas, escreva:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Usar Template +PREFERENCES_PARSEDEXTADD;Adicionar Extensão +PREFERENCES_PARSEDEXTADDHINT;escreva uma extensão e pressione este botão para adicionar à lista +PREFERENCES_PARSEDEXTDELHINT;Apagar extensão selecionada da lista +PREFERENCES_PARSEDEXT;Extensões analisadas gramaticalmente +PREFERENCES_PROFILEHANDLING;Manipulação de processamento de perfil +PREFERENCES_PROFILELOADPR;Prioridade de carregamento de perfil +PREFERENCES_PROFILEPRCACHE;Perfil no Cache +PREFERENCES_PROFILEPRFILE;Perfil próximo ao arquivo de entrada +PREFERENCES_PROFILESAVECACHE;Salvar parâmetros de processamento no cache +PREFERENCES_PROFILESAVEINPUT;Salvar parâmetros de processamento próximo ao arquivo de entrada +PREFERENCES_PSPATH;Diretório de instalação do Adobe Photoshop +PREFERENCES_SELECTICCDIRDLG;Selecione o diretório de perfil ICC... +PREFERENCES_SELECTLANG;Selecionar idioma +PREFERENCES_SELECTMONITORPROFDLG;Selecione o perfil ICC da visualização... +PREFERENCES_SELECTTHEME;Selecionar tema +PREFERENCES_SHOWBASICEXIF;Mostrar informações Exif básicas +PREFERENCES_SHOWDATETIME;Mostrar data e hora +PREFERENCES_SHOWONLYRAW;Mostrar somente arquivos RAW +PREFERENCES_SHTHRESHOLD;Limiar para sombras recortadas +PREFERENCES_STARTUPIMDIR;Diretório de Imagens ao Iniciar +PREFERENCES_TAB_BROWSER;Navegador de Arquivos +PREFERENCES_TAB_COLORMGR;Gerenciamento de Cores +PREFERENCES_TAB_GENERAL;Geral +PREFERENCES_TAB_IMPROC;Processamento de Imagem +PREFERENCES_TAB_OUTPUT;Opções de Saída +PREFERENCES_THUMBSIZE;Tamanho das Miniaturas +PROFILEPANEL_FILEDLGFILTERANY;Quaisquer arquivos +PROFILEPANEL_FILEDLGFILTERPP;Perfis de pós-processamento +PROFILEPANEL_LABEL;Perfis de pós-processamento +PROFILEPANEL_LOADDLGLABEL;Carregar parâmetros de pós-processamento... +PROFILEPANEL_PCUSTOM;Personalizado +PROFILEPANEL_PFILE;do Arquivo +PROFILEPANEL_PLASTPHOTO;Ùltima Foto +PROFILEPANEL_PLASTSAVED;Último Salvo +PROFILEPANEL_PROFILE;Perfil +PROFILEPANEL_SAVEDLGLABEL;Save parâmetros de pós-processamento... +PROFILEPANEL_TOOLTIPCOPY;Copiar perfil atual para a área de transferência +PROFILEPANEL_TOOLTIPLOAD;carregar perfil a partir de um arquivo +PROFILEPANEL_TOOLTIPPASTE; Colar perfil da área de transferência +PROFILEPANEL_TOOLTIPSAVE;Salvar perfil atual +PROGRESSBAR_DECODING;Decodificando arquivo raw... +PROGRESSBAR_DEMOSAICING;Removendo mosaico... +PROGRESSBAR_LOADING;Carregando Imagem... +PROGRESSBAR_LOADJPEG;Carregando arquivo JPEG... +PROGRESSBAR_LOADPNG;Carregando arquivo PNG... +PROGRESSBAR_LOADTIFF;Carregando arquivo TIFF... +PROGRESSBAR_PROCESSING;Processando imagem... +PROGRESSBAR_READY;Pronto. +PROGRESSBAR_SAVEJPEG;Salvando Arquivo JPEG... +PROGRESSBAR_SAVEPNG;Salvando Arquivo PNG... +PROGRESSBAR_SAVETIFF;Salvando Arquivo TIFF... +PROGRESSDLG_LOADING;Carregando arquivo... +PROGRESSDLG_PROCESSING;Processando imagem... +PROGRESSDLG_SAVING;Salvando arquivo... +QINFO_FOCALLENGTH;Distância focal +QINFO_ISO;ISO +QINFO_LENS;Lente +QINFO_NOEXIF;Dados Exif não disponíveis. +SAVEDLG_FILEFORMAT;Formato do Arquivo +SAVEDLG_JPEGQUAL;Qualidade do JPEG +SAVEDLG_JPGFILTER;Arquivos JPEG +SAVEDLG_PNGCOMPR;Compressão PNG +SAVEDLG_PNGFILTER;Arquivos PNG +SAVEDLG_PUTTOQUEUE;Colocar na fila de processamento +SAVEDLG_PUTTOQUEUEHEAD;Colocar no topo da fila de processamento +SAVEDLG_PUTTOQUEUETAIL;Colocar no final da fila de processamento +SAVEDLG_SAVEIMMEDIATELY;Salvar Imediatamente +SAVEDLG_SAVESPP;Salvar parâmetros de processamento com a imagem +SAVEDLG_TIFFFILTER;Arquivos TIFF +TOOLBAR_TOOLTIP_CROP;Seleção de Corte (Tecla de Atalho: C) +TOOLBAR_TOOLTIP_HAND;Ferramenta Mão (Tecla de Atalho: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Seleção de linha reta (Tecla de atalho: S) +TOOLBAR_TOOLTIP_WB;Balanço de branco em área (Tecla de atalho: W) +TP_CACORRECTION_BLUE;Azul +TP_CACORRECTION_LABEL;Correção C/A +TP_CACORRECTION_RED;Vermelho +TP_CHMIXER_BLUE;Azul +TP_CHMIXER_GREEN;Verde +TP_CHMIXER_LABEL;Misturador de Canais +TP_CHMIXER_RED;Vermelho +TP_COARSETRAF_DEGREE;graus: +TP_COARSETRAF_TOOLTIP_HFLIP;Inverter horizontalmente +TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotacionar à esquerda +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotacionar à direita +TP_COARSETRAF_TOOLTIP_VFLIP;Inverter verticalmente +TP_COLORBOOST_ACHANNEL;Canal "a" +TP_COLORBOOST_AMOUNT;Quantidade +TP_COLORBOOST_AVOIDCOLORCLIP;Evitar clipping de cor +TP_COLORBOOST_BCHANNEL;Canal "b" +TP_COLORBOOST_CHAB;a & b +TP_COLORBOOST_CHANNEL;Canal +TP_COLORBOOST_CHSEPARATE;separar +TP_COLORBOOST_ENABLESATLIMITER;Habilitar limite de saturação +TP_COLORBOOST_LABEL;Melhoria de Cor +TP_COLORBOOST_SATLIMIT;Limite de Saturação +TP_COLORDENOISE_EDGESENSITIVE;Sensitivo a bordas +TP_COLORDENOISE_EDGETOLERANCE;Tolerância de bordas +TP_COLORDENOISE_LABEL;Redução de Ruidos da Cor +TP_COLORDENOISE_RADIUS;Raio +TP_COLORSHIFT_BLUEYELLOW;Azul-Amarelo +TP_COLORSHIFT_GREENMAGENTA;Verde-Magenta +TP_COLORSHIFT_LABEL;Alternância de cor +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Relação Fixa: +TP_CROP_GTDIAGONALS;Regra das diagonais +TP_CROP_GTHARMMEANS1;Harmonico 1 +TP_CROP_GTHARMMEANS2;Harmonico 2 +TP_CROP_GTHARMMEANS3;Harmonico 3 +TP_CROP_GTHARMMEANS4;Harmonico 4 +TP_CROP_GTNONE;Nenhum +TP_CROP_GTRULETHIRDS;Regra de Terceiros +TP_CROP_GUIDETYPE;Tipo de guia: +TP_CROP_H;H +TP_CROP_LABEL;Cortar +TP_CROP_SELECTCROP; Selecione o Corte +TP_CROP_W;W +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Quantidade +TP_DISTORTION_LABEL;Distorção +TP_EXPOSURE_AUTOLEVELS;Níveis Automáticos +TP_EXPOSURE_BLACKLEVEL;Preto +TP_EXPOSURE_BRIGHTNESS;Brilho +TP_EXPOSURE_CLIP;Clip +TP_EXPOSURE_COMPRHIGHLIGHTS;Compressão de Luz +TP_EXPOSURE_COMPRSHADOWS;Compressão de Sombras +TP_EXPOSURE_CONTRAST;Contraste +TP_EXPOSURE_CURVEEDITOR;Curva de Tons +TP_EXPOSURE_EXPCOMP;Exp. Comp. +TP_EXPOSURE_LABEL;Exposição +TP_HLREC_CIELAB;Mistura CIELab +TP_HLREC_COLOR;Propagação de Cores +TP_HLREC_LABEL;Recuperação de Luz +TP_HLREC_LUMINANCE;Recuperação de Luminância +TP_HLREC_METHOD;Método: +TP_ICM_FILEDLGFILTERANY;Quaisquer Arquivos +TP_ICM_FILEDLGFILTERICM;Arquivos de perfis ICC +TP_ICM_GAMMABEFOREINPUT;Perfil aplica gama +TP_ICM_INPUTCAMERA;Padrão de Câmera +TP_ICM_INPUTCUSTOM;Personalizado +TP_ICM_INPUTDLGLABEL;Selecione perfil de entrada ICC... +TP_ICM_INPUTEMBEDDED;Use Embedded, se possível +TP_ICM_INPUTPROFILE;Perfil de entrada +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Sem ICM: Saída sRGB +TP_ICM_OUTPUTDLGLABEL;Selecione perfil de saída ICC... +TP_ICM_OUTPUTPROFILE;Perfil de Saída +TP_ICM_SAVEREFERENCE;Salvar imagem de referência para perfis +TP_ICM_WORKINGPROFILE;Perfil Utilizado +TP_LUMACURVE_BLACKLEVEL;Preto +TP_LUMACURVE_BRIGHTNESS;Brilho +TP_LUMACURVE_COMPRHIGHLIGHTS;Compressão da Luz +TP_LUMACURVE_COMPRSHADOWS;Compressão de Sombras +TP_LUMACURVE_CONTRAST;Contraste +TP_LUMACURVE_CURVEEDITOR;Curva de Luminância +TP_LUMACURVE_LABEL;Curva de Luminância +TP_LUMADENOISE_EDGETOLERANCE;Tolerância de Bordas +TP_LUMADENOISE_LABEL;Redução de ruídos da luminância +TP_LUMADENOISE_RADIUS;Raio +TP_RESIZE_BICUBIC;Bicúbico +TP_RESIZE_BICUBICSF;Bicúbico (mais suave) +TP_RESIZE_BICUBICSH;Bicúbic (mais nítido) +TP_RESIZE_BILINEAR;Bilinear +TP_RESIZE_FULLSIZE;Tamanho de Imagem Completo: +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Redimensionar +TP_RESIZE_METHOD;Método: +TP_RESIZE_NEAREST;Mais Próximo +TP_RESIZE_SCALE;Escala +TP_RESIZE_W;W: +TP_ROTATE_AUTOCROP;Cortar Automaticamente +TP_ROTATE_DEGREE;Graus +TP_ROTATE_FILL;Preencher +TP_ROTATE_LABEL;Rotacionar +TP_ROTATE_SELECTLINE; Selecionar Linha Reta +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Luzes +TP_SHADOWSHLIGHTS_HLTONALW;Largura de Tons +TP_SHADOWSHLIGHTS_LABEL;Sombras/Luzes +TP_SHADOWSHLIGHTS_LOCALCONTR;Contraste Local +TP_SHADOWSHLIGHTS_RADIUS;Raio +TP_SHADOWSHLIGHTS_SHADOWS;Sombras +TP_SHADOWSHLIGHTS_SHTONALW;largura de tons +TP_SHARPENING_AMOUNT;Quantidade +TP_SHARPENING_EDRADIUS;Raio +TP_SHARPENING_EDTOLERANCE;Tolerância de bordas +TP_SHARPENING_HALOCONTROL;Controle de luz +TP_SHARPENING_HCAMOUNT;Quantidade +TP_SHARPENING_LABEL;Nitidez +TP_SHARPENING_METHOD;Método +TP_SHARPENING_ONLYEDGES;tornar nítido somente as bordas +TP_SHARPENING_RADIUS;Raio +TP_SHARPENING_RLD_AMOUNT;Quantidade +TP_SHARPENING_RLD_DAMPING;Umedecimento +TP_SHARPENING_RLD_ITERATIONS;Iterações +TP_SHARPENING_RLD;RL Desconvolução +TP_SHARPENING_THRESHOLD;Limiar +TP_SHARPENING_USM;Máscara de Nitidez +TP_VIGNETTING_AMOUNT;Quantidade +TP_VIGNETTING_LABEL;Correção de vinheta +TP_VIGNETTING_RADIUS;Raio +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Câmera +TP_WBALANCE_CUSTOM;Personalizado +TP_WBALANCE_GREEN;Tonalidade +TP_WBALANCE_LABEL;Balanço do Branco +TP_WBALANCE_METHOD;Método +TP_WBALANCE_SIZE;Tamanho: +TP_WBALANCE_SPOTWB;Balanço de Branco de área +TP_WBALANCE_TEMPERATURE;Temperatura +ZOOMBAR_DETAIL;Detalhe +ZOOMBAR_HUGE;Muito Grande +ZOOMBAR_LARGE;Grande +ZOOMBAR_NORMAL;Normal +ZOOMBAR_PREVIEW;Pré-visualisação +ZOOMBAR_SCALE;Escala +ZOOMBAR_SMALL;Pequeno + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Russian b/rtdata/languages/Russian new file mode 100644 index 000000000..4dfa74468 --- /dev/null +++ b/rtdata/languages/Russian @@ -0,0 +1,706 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# Russian +# 23.12.2007 +# ArtDen +# 20.07.2008: Denis Artemov +# 16.02.2009: Kvark +# 26.02.2010: Sergey Smirnov AKA smiserg +ADJUSTER_RESET_TO_DEFAULT;По умолчанию +CURVEEDITOR_FILEDLGFILTERANY;Любые файлы +CURVEEDITOR_FILEDLGFILTERCURVE;Файлы тоновых кривых +CURVEEDITOR_LINEAR;Ð›Ð¸Ð½ÐµÐ¹Ð½Ð°Ñ +CURVEEDITOR_LOADDLGLABEL;Считать кривую... +CURVEEDITOR_SAVEDLGLABEL;Сохранить кривую... +CURVEEDITOR_TOOLTIPLINEAR;Ð’Ñ‹Ñтавить линейную тоновую кривую +CURVEEDITOR_TOOLTIPLOAD;Загрузить тоновую кривую +CURVEEDITOR_TOOLTIPSAVE;Сохранить тоновую кривую +EXIFFILTER_APERTURE;Диафрагма +EXIFFILTER_CAMERA;Камера +EXIFFILTER_DIALOGLABEL;Фильтр Exif +EXIFFILTER_FOCALLEN;ФокуÑное раÑÑтоÑние +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Объектив +EXIFFILTER_SHUTTER;Выдержка +EXIFPANEL_ADDEDITHINT;Добавить новый Ñ‚Ñг или редактировать тег +EXIFPANEL_ADDEDIT;Добавить/редактировать +EXIFPANEL_ADDTAGDLG_ENTERVALUE;ВвеÑти значение +EXIFPANEL_ADDTAGDLG_SELECTTAG;Выбрать тег +EXIFPANEL_ADDTAGDLG_TITLE;Добавить/редактировать тег +EXIFPANEL_KEEPHINT;СохранÑть выбранные теги при запиÑи файла +EXIFPANEL_KEEP;Сохранить +EXIFPANEL_REMOVEHINT;УдалÑть выбранные теги при запиÑи файла +EXIFPANEL_REMOVE;Удалить +EXIFPANEL_RESETALLHINT;СброÑить вÑе теги в первоначальные Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ +EXIFPANEL_RESETALL;СброÑить вÑе +EXIFPANEL_RESETHINT;СброÑить выбранные теги в первоначальные Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ +EXIFPANEL_RESET;СброÑить +EXIFPANEL_SUBDIRECTORY;Подкаталог +FILEBROWSER_APPLYPROFILE;Применить профиль +FILEBROWSER_ARRANGEMENTHINT;Вертикальное/горизонтальное раÑположение ÑÑкизов +FILEBROWSER_CLEARPROFILE;Удалить профиль +FILEBROWSER_COPYPROFILE;Скопировать профиль +FILEBROWSER_DELETEDLGLABEL;Подтверждение ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° +FILEBROWSER_DELETEDLGMSG;Ð’Ñ‹ уверены, что хотите удалить %1 выбранный(ых) файл(ов)? +FILEBROWSER_EMPTYTRASHHINT;Удалить файлы из корзины без возможноÑти воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ +FILEBROWSER_EMPTYTRASH;ОчиÑтить корзину +FILEBROWSER_EXIFFILTERAPPLYHINT;Включение/Ð²Ñ‹ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ñ„Ð¸Ð»ÑŒÑ‚Ñ€Ð° Exif в браузере +FILEBROWSER_EXIFFILTERAPPLY;Применить +FILEBROWSER_EXIFFILTERLABEL;Фильтр Exif +FILEBROWSER_EXIFFILTERSETTINGSHINT;ÐаÑтройка параметров фильтра Exif +FILEBROWSER_EXIFFILTERSETTINGS;ÐаÑтройка +FILEBROWSER_PARTIALPASTEPROFILE;ЧаÑÑ‚Ð¸Ñ‡Ð½Ð°Ñ Ð²Ñтавка +FILEBROWSER_PASTEPROFILE;Ð’Ñтавка Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ +FILEBROWSER_POPUPCANCELJOB;Отменить задание +FILEBROWSER_POPUPMOVEEND;ПеремеÑтить в конец очереди +FILEBROWSER_POPUPMOVEHEAD;ПеремеÑтить в начало очереди +FILEBROWSER_POPUPOPEN;Открыть +FILEBROWSER_POPUPPROCESS;ПомеÑтить в очередь на обработку +FILEBROWSER_POPUPRANK1;Рейтинг 1 +FILEBROWSER_POPUPRANK2;Рейтинг 2 +FILEBROWSER_POPUPRANK3;Рейтинг 3 +FILEBROWSER_POPUPRANK4;Рейтинг 4 +FILEBROWSER_POPUPRANK5;Рейтинг 5 +FILEBROWSER_POPUPREMOVE;Удалить Ñ Ð´Ð¸Ñка +FILEBROWSER_POPUPRENAME;Переименовать +FILEBROWSER_POPUPSELECTALL;Выбрать вÑе +FILEBROWSER_POPUPTRASH;Удалить в корзину +FILEBROWSER_POPUPUNRANK;СнÑть рейтинг +FILEBROWSER_POPUPUNTRASH;Удалить из корзины +FILEBROWSER_PROCESSINGSETTINGSHINT;Задать формат файла и выходной каталог +FILEBROWSER_PROCESSINGSETTINGS;Параметры +FILEBROWSER_RENAMEDLGLABEL;Переименовать файл +FILEBROWSER_RENAMEDLGMSG;Переименовать файл "%1" в: +FILEBROWSER_SHOWDIRHINT;Показать вÑе Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð² каталоге +FILEBROWSER_SHOWQUEUEHINT;Показать Ñодержимое очереди на обработку +FILEBROWSER_SHOWRANK1HINT;Показать Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ Ñ€ÐµÐ¹Ñ‚Ð¸Ð½Ð³Ð¾Ð¼ 1 +FILEBROWSER_SHOWRANK2HINT;Показать Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ Ñ€ÐµÐ¹Ñ‚Ð¸Ð½Ð³Ð¾Ð¼ 2 +FILEBROWSER_SHOWRANK3HINT;Показать Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ Ñ€ÐµÐ¹Ñ‚Ð¸Ð½Ð³Ð¾Ð¼ 3 +FILEBROWSER_SHOWRANK4HINT;Показать Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ Ñ€ÐµÐ¹Ñ‚Ð¸Ð½Ð³Ð¾Ð¼ 4 +FILEBROWSER_SHOWRANK5HINT;Показать Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ Ñ€ÐµÐ¹Ñ‚Ð¸Ð½Ð³Ð¾Ð¼ 5 +FILEBROWSER_SHOWTRASHHINT;Показать Ñодержимое корзины +FILEBROWSER_SHOWUNRANKHINT;Показать Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð±ÐµÐ· рейтинга +FILEBROWSER_STARTPROCESSINGHINT;ЗапуÑк обработки/ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð¼ÐµÑ‰ÐµÐ½Ð½Ñ‹Ñ… в очередь изображений +FILEBROWSER_STARTPROCESSING;Ðачать обработку +FILEBROWSER_STOPPROCESSINGHINT;Отмена обработки изображений +FILEBROWSER_STOPPROCESSING;ОÑтановить обработку +FILEBROWSER_THUMBSIZE;Размер ÑÑкиза +FILEBROWSER_ZOOMINHINT;Увеличить размер ÑÑкиза +FILEBROWSER_ZOOMOUTHINT;Уменьшить размер ÑÑкиза +GENERAL_ABOUT;О программе +GENERAL_CANCEL;Отмена +GENERAL_DISABLED;Выключено +GENERAL_DISABLE;Выключить +GENERAL_ENABLED;Включено +GENERAL_ENABLE;Включить +GENERAL_LANDSCAPE;Ðльбомный +GENERAL_LOAD;Загрузить +GENERAL_NA;Ð/Д +GENERAL_NO;Ðет +GENERAL_OK;OK +GENERAL_PORTRAIT;Портретный +GENERAL_SAVE;Сохранить +GENERAL_YES;Да +HISTOGRAM_LABEL;ГиÑтограмма +HISTOGRAM_TOOLTIP_B;Показать/Ñкрыть СИÐИЙ канал гиÑтограммы +HISTOGRAM_TOOLTIP_G;Показать/Ñкрыть ЗЕЛÐÐЫЙ канал гиÑтограммы +HISTOGRAM_TOOLTIP_L;Показать/Ñкрыть CIELAB канал гиÑтограммы +HISTOGRAM_TOOLTIP_R;Показать/Ñкрыть КРÐСÐЫЙ канал гиÑтограммы +HISTORY_CHANGED;Изменено +HISTORY_CUSTOMCURVE;ПользовательÑÐºÐ°Ñ ÐºÑ€Ð¸Ð²Ð°Ñ +HISTORY_DELSNAPSHOT;Удалить Ñнимок +HISTORY_FROMCLIPBOARD;Из буфера обмена +HISTORY_LABEL;ИÑÑ‚Ð¾Ñ€Ð¸Ñ +HISTORY_MSG_10;Сжатие теней +HISTORY_MSG_11;Ð¢Ð¾Ð½Ð¾Ð²Ð°Ñ ÐºÑ€Ð¸Ð²Ð°Ñ +HISTORY_MSG_12;ÐвтоматичеÑÐºÐ°Ñ Ð½Ð°Ñтройка +HISTORY_MSG_13;Ограничение ÑкÑпозиции +HISTORY_MSG_14;Luminance ЯркоÑть +HISTORY_MSG_15;Luminance КонтраÑÑ‚ +HISTORY_MSG_16;Luminance Уровень чёрного +HISTORY_MSG_17;Luminance Сжатие Ñветов +HISTORY_MSG_18;Luminance Сжатие теней +HISTORY_MSG_19;Luminance Ð¢Ð¾Ð½Ð¾Ð²Ð°Ñ ÐºÑ€Ð¸Ð²Ð°Ñ +HISTORY_MSG_1;Фото загружено +HISTORY_MSG_20;РезкоÑть +HISTORY_MSG_21;Ð Ð°Ð´Ð¸ÑƒÑ Ñ€ÐµÐ·ÐºÐ¾Ñти +HISTORY_MSG_22;Величина резкоÑти +HISTORY_MSG_23;Порог резкоÑти +HISTORY_MSG_24;РезкоÑть: Только границы +HISTORY_MSG_25;РезкоÑть: Ð Ð°Ð´Ð¸ÑƒÑ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð³Ñ€Ð°Ð½Ð¸Ñ† +HISTORY_MSG_26;РезкоÑть: ДопуÑк Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð³Ñ€Ð°Ð½Ð¸Ñ† +HISTORY_MSG_27;РезкоÑть: Управление ореолом +HISTORY_MSG_28;РезкоÑть: Величина Halo +HISTORY_MSG_29;РезкоÑть: Метод +HISTORY_MSG_2;Профиль загружен +HISTORY_MSG_30;Deconvolution: Ð Ð°Ð´Ð¸ÑƒÑ +HISTORY_MSG_31;Deconvolution: Значение +HISTORY_MSG_32;Deconvolution: ОÑлабление +HISTORY_MSG_33;Deconvolution: Повторов +HISTORY_MSG_34;Предотвращать Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ñ†Ð²ÐµÑ‚Ð¾Ð² +HISTORY_MSG_35;Ограничитель наÑыщенноÑти +HISTORY_MSG_36;Ограничение наÑыщенноÑти +HISTORY_MSG_37;УÑиление цвета +HISTORY_MSG_38;Метод Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð±Ð°Ð»Ð°Ð½Ñа белого +HISTORY_MSG_39;Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ñ‚ÐµÐ¼Ð¿ÐµÑ€Ð°Ñ‚ÑƒÑ€Ð° +HISTORY_MSG_3;Профиль изменён +HISTORY_MSG_40;Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾: оттенок +HISTORY_MSG_41;Сдвиг цвета "A" +HISTORY_MSG_42;Сдвиг цвета "B" +HISTORY_MSG_43;Удаление шума +HISTORY_MSG_44;Удаление шума: Ñ€Ð°Ð´Ð¸ÑƒÑ +HISTORY_MSG_45;Удаление шума: чувÑтвительноÑть к границам +HISTORY_MSG_46;Удаление цветового шума +HISTORY_MSG_47;Удаление цветового шума: Ñ€Ð°Ð´Ð¸ÑƒÑ +HISTORY_MSG_48;Удаление цветового шума: чувÑтвительноÑть к границам +HISTORY_MSG_49;Удаление цветового шума Ñ ÑƒÑ‡ÐµÑ‚Ð¾Ð¼ границ +HISTORY_MSG_4;ПроÑмотр иÑтории +HISTORY_MSG_50;ИнÑтрумент "Тени/Света" +HISTORY_MSG_51;Подъём Ñветов +HISTORY_MSG_52;Подъём теней +HISTORY_MSG_53;Уровень Ñветов +HISTORY_MSG_54;Уровень теней +HISTORY_MSG_55;Локальный контраÑÑ‚ +HISTORY_MSG_56;Ð Ð°Ð´Ð¸ÑƒÑ Ñветов/теней +HISTORY_MSG_57;Грубый поворот +HISTORY_MSG_58;Зеркальное отражение по горизонтали +HISTORY_MSG_59;Зеркальное отражение по вертикали +HISTORY_MSG_5;ЯркоÑть +HISTORY_MSG_60;Поворот +HISTORY_MSG_61;Поворот +HISTORY_MSG_62;ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð¸Ñкажений оптики +HISTORY_MSG_63;Закладка выбрана +HISTORY_MSG_64;Кадрирование +HISTORY_MSG_65;ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð¥Ð +HISTORY_MSG_66;ВоÑÑтановление Ñветов +HISTORY_MSG_67;Величина воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñветов +HISTORY_MSG_68;СпоÑоб воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñветов +HISTORY_MSG_69;Рабочее цветовое проÑтранÑтво +HISTORY_MSG_6;КонтраÑÑ‚ +HISTORY_MSG_70;Выходное цветовое проÑтранÑтво +HISTORY_MSG_71;Входное цветовое проÑтранÑтво +HISTORY_MSG_72;Виньетирование +HISTORY_MSG_73;Цветовые каналы +HISTORY_MSG_74;МаÑштаб Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð¾Ð² +HISTORY_MSG_75;СпоÑоб Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð¾Ð² +HISTORY_MSG_76;Метаданные Exif +HISTORY_MSG_77;Метаданные IPTC +HISTORY_MSG_78;Данные Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð¾Ð² +HISTORY_MSG_79;Ширина Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð¾Ð² +HISTORY_MSG_7;Уровень чёрного +HISTORY_MSG_80;Ð’Ñ‹Ñота Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð¾Ð² +HISTORY_MSG_81;Изменение размеров включено +HISTORY_MSG_8;КомпенÑÐ°Ñ†Ð¸Ñ ÑкÑпозиции +HISTORY_MSG_9;Сжатие Ñветов +HISTORY_NEWSNAPSHOTAS;Как... +HISTORY_NEWSNAPSHOT;Ðовый Ñнимок +HISTORY_NEWSSDIALOGLABEL;Ðазвание Ñнимка: +HISTORY_NEWSSDIALOGTITLE;Добавить Ñнимок +HISTORY_SETTO;УÑтановить в +HISTORY_SNAPSHOTS;Снимки +HISTORY_SNAPSHOT;Снимок +ICMPANEL_FILEDLGFILTERANY;Любые файлы +ICMPANEL_FILEDLGFILTERICM;Файлы ICC профилей +ICMPANEL_GAMMABEFOREINPUT;ПрименÑть гамму Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ +ICMPANEL_INPUTCAMERA;По умолчанию Ð´Ð»Ñ ÐºÐ°Ð¼ÐµÑ€Ñ‹ +ICMPANEL_INPUTCUSTOM;ПользовательÑкий +ICMPANEL_INPUTDLGLABEL;Выберите входной ICC профиль... +ICMPANEL_INPUTEMBEDDED;ИÑпользовать вÑтроенный, еÑли Ñто возможно +ICMPANEL_INPUTPROFILE;Входной профиль +ICMPANEL_NOICM;Без ICM: sRGB на выходе +ICMPANEL_OUTPUTDLGLABEL;Выберите выходной ICC профиль... +ICMPANEL_OUTPUTPROFILE;Выходной профиль +ICMPANEL_SAVEREFERENCE;Сохранить иÑходное изображение Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ +ICMPANEL_WORKINGPROFILE;Рабочий профиль +IMAGEAREA_DETAILVIEW;Детальный проÑмотр +IPTCPANEL_AUTHORHINT;Ð˜Ð¼Ñ ÑÐ¾Ð·Ð´Ð°Ñ‚ÐµÐ»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð° (пиÑателÑ, фотографа или художника) (By-line) +IPTCPANEL_AUTHORSPOSITIONHINT;Ðазвание автора или авторов объекта (By-line Title). +IPTCPANEL_AUTHORSPOSITION;ÐŸÐ¾Ð·Ð¸Ñ†Ð¸Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð° +IPTCPANEL_AUTHOR;Ðвтор +IPTCPANEL_CAPTIONHINT;ТекÑтовое опиÑание данных (Caption - Abstract) +IPTCPANEL_CAPTIONWRITERHINT;Ð˜Ð¼Ñ Ñ‡ÐµÐ»Ð¾Ð²ÐµÐºÐ°, учаÑтвовавшего в Ñоздании, изменении или редактировании Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð»Ð¸Ð±Ð¾ подпиÑи (Writer - Editor). +IPTCPANEL_CAPTIONWRITER;Ðвтор подпиÑи +IPTCPANEL_CAPTION;ПодпиÑÑŒ +IPTCPANEL_CATEGORYHINT;УÑтанавливает тему Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (Category) +IPTCPANEL_CATEGORY;ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ +IPTCPANEL_CITYHINT;Город (City). +IPTCPANEL_CITY;Город +IPTCPANEL_COPYHINT;Копировать данные IPTC в буфер обмена +IPTCPANEL_COPYRIGHTHINT;Любые Ð¿Ñ€ÐµÐ´ÑƒÐ¿Ñ€ÐµÐ¶Ð´ÐµÐ½Ð¸Ñ Ð¾Ð± авторÑких правах (Copyright Notice). +IPTCPANEL_COPYRIGHT;ÐвторÑкие права +IPTCPANEL_COUNTRYHINT;Ðазвание Ñтраны/начального меÑÑ‚Ð¾Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ (Country - Primary Location Name). +IPTCPANEL_COUNTRY;Страна +IPTCPANEL_CREDITHINT;Лица и организации, оÑущеÑтвлÑющие какую либо поддержку Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (Credit). +IPTCPANEL_CREDIT;Поддержка +IPTCPANEL_DATECREATEDHINT;Дата ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¸Ð½Ñ‚ÐµÐ»Ð»ÐµÐºÑ‚ÑƒÐ°Ð»ÑŒÐ½Ð¾Ð³Ð¾ ÑÐ¾Ð´ÐµÑ€Ð¶Ð°Ð½Ð¸Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ; Формат: ГГГГММДД (Date Created). +IPTCPANEL_DATECREATED;Дата ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ +IPTCPANEL_EMBEDDEDHINT;СброÑить данные IPTC, вÑтроенные в файл Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ +IPTCPANEL_EMBEDDED;Ð’Ñтроенный +IPTCPANEL_HEADLINEHINT;ПодходÑщий Ð´Ð»Ñ Ð¿ÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸ краткий обзор Ñодержимого Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (Headline). +IPTCPANEL_HEADLINE;Заголовок +IPTCPANEL_INSTRUCTIONSHINT;Прочие редакторÑкие инÑтрукции об иÑпользовании Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (Special Instructions). +IPTCPANEL_INSTRUCTIONS;ИнÑтрукции +IPTCPANEL_KEYWORDSHINT;Ключевые Ñлова, иÑпользуемые Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка (Keywords). +IPTCPANEL_KEYWORDS;Ключевые Ñлова +IPTCPANEL_PASTEHINT;Ð’Ñтавить данные IPTC из буфера обмена +IPTCPANEL_PROVINCEHINT;ПровинциÑ/штат (Province-State). +IPTCPANEL_PROVINCE;ÐŸÑ€Ð¾Ð²Ð¸Ð½Ñ†Ð¸Ñ +IPTCPANEL_RESETHINT;СброÑить профиль на Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию +IPTCPANEL_RESET;СброÑить +IPTCPANEL_SOURCEHINT;Первоначальный владелец интеллектуального ÑÐ¾Ð´ÐµÑ€Ð¶Ð°Ð½Ð¸Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (Source). +IPTCPANEL_SOURCE;ИÑточник +IPTCPANEL_SUPPCATEGORIESHINT;Дополнительные ÑƒÑ‚Ð¾Ñ‡Ð½ÐµÐ½Ð¸Ñ Ñ‚ÐµÐ¼Ñ‹ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Доп. категории +IPTCPANEL_TITLEHINT;ПроÑтое опиÑание Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (Object Name). +IPTCPANEL_TITLE;Ðазвание +IPTCPANEL_TRANSREFERENCEHINT;Код, облегчающий отÑлеживание Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸ передаче в обработку на Ñторону (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Код поддержки +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;ÐаÑтройки +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;Как... +MAIN_BUTTON_SAVE;Сохранить изображение +MAIN_BUTTON_SENDTOEDITOR;Открыть в редакторе +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Файл уже ÑущеÑтвует. +MAIN_MSG_CANNOTLOAD;Ðевозможно загрузить изображение +MAIN_MSG_CANNOTSAVE;Ошибка при Ñохранении файла +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;ПожалуйÑта, уÑтановите правильный путь в диалоге "ÐаÑтройки". +MAIN_MSG_CANNOTSTARTEDITOR;не удалоÑÑŒ запуÑтить редактор. +MAIN_MSG_EXITJOBSINQUEUEINFO;Ðеобработанные изображениÑ, находÑщиеÑÑ Ð² очереди,будут утерÑны при выходе из программы. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Ð’Ñ‹ уверены, что хотите выйти из программы? Ð’ очереди оÑталиÑÑŒ необработанные изображениÑ. +MAIN_MSG_JOBSINQUEUE;Идёт обработка +MAIN_MSG_QOVERWRITE;Ð’Ñ‹ хотите перезапиÑать его? +MAIN_TAB_BASIC;ОÑновные +MAIN_TAB_COLOR;Цвет +MAIN_TAB_DETAIL;Ð”ÐµÑ‚Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;ЭкÑÐ¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Метаданные +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;ÐŸÑ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ +MAIN_TOOLTIP_HIDEFP;Показать/Ñкрыть нижнюю панель (каталоги и ÑпиÑок файлов, горÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: F) +MAIN_TOOLTIP_HIDEHP;Показать/Ñкрыть левую панель (Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð¸Ñторию, горÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: H) +MAIN_TOOLTIP_INDCLIPPEDH;Индикатор переÑветов +MAIN_TOOLTIP_INDCLIPPEDS;Индикатор затемнений +MAIN_TOOLTIP_PREFERENCES;задать наÑтройки +MAIN_TOOLTIP_QINFO;Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± изображении +MAIN_TOOLTIP_SAVEAS;Сохранить изображение в... +MAIN_TOOLTIP_SAVE;Сохранить изображение в каталог по умолчанию +PARTIALPASTE_BASICGROUP;Базовые наÑтройки +PARTIALPASTE_CACORRECTION;ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ C/A +PARTIALPASTE_COARSETRANS;поворот на 90 гр. / отражение +PARTIALPASTE_COLORBOOST;УÑиление цвета +PARTIALPASTE_COLORDENOISE;Удаление цветового шума +PARTIALPASTE_COLORGROUP;ÐаÑтройка цвета +PARTIALPASTE_COLORMIXER;Цветовой микшер +PARTIALPASTE_COLORSHIFT;ИÑкажение цвета +PARTIALPASTE_COMPOSITIONGROUP;Параметры компоновки +PARTIALPASTE_CROP;Кадрирование +PARTIALPASTE_DIALOGLABEL;ЧаÑÑ‚Ð¸Ñ‡Ð½Ð°Ñ Ð²Ñтавка параметров обработки +PARTIALPASTE_DISTORTION;ДиÑторÑÐ¸Ñ +PARTIALPASTE_EXIFCHANGES;Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… Exif +PARTIALPASTE_EXPOSURE;ЭкÑÐ¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ +PARTIALPASTE_HLRECOVERY;ВоÑÑтановление Ñветов +PARTIALPASTE_ICMSETTINGS;Параметры ICM +PARTIALPASTE_IPTCINFO;Данные IPTC +PARTIALPASTE_LENSGROUP;Параметры Ñъемки +PARTIALPASTE_LUMACURVE;ÐšÑ€Ð¸Ð²Ð°Ñ ÑркоÑти +PARTIALPASTE_LUMADENOISE;Удаление ÑркоÑтного шума +PARTIALPASTE_LUMINANCEGROUP;ÐаÑтройка параметров ÑркоÑти +PARTIALPASTE_METAICMGROUP;ÐаÑтройка метаданных/параметров ICM +PARTIALPASTE_RESIZE;Изменение размера +PARTIALPASTE_ROTATION;Поворот +PARTIALPASTE_SHADOWSHIGHLIGHTS;Тени/Ñвета +PARTIALPASTE_SHARPENING;Повышение резкоÑти +PARTIALPASTE_VIGNETTING;ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð²Ð¸Ð½ÑŒÐµÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ +PARTIALPASTE_WHITEBALANCE;Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾ +PREFERENCES_APPLNEXTSTARTUP;Ðужен перезапуÑк программы +PREFERENCES_BLINKCLIPPED;Мигать проблемными зонами +PREFERENCES_CACHECLEARALL;Удалить вÑе +PREFERENCES_CACHECLEARPROFILES;Удалить параметры обработки +PREFERENCES_CACHECLEARTHUMBS;Удалить ÑÑкизы +PREFERENCES_CACHEFORMAT1;Свой (быÑтрее, выше качеÑтво) +PREFERENCES_CACHEFORMAT2;JPEG (меньший меÑта на диÑке) +PREFERENCES_CACHEMAXENTRIES;МакÑимальное чиÑло Ñлементов в кÑше +PREFERENCES_CACHEOPTS;Параметры кÑÑˆÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ +PREFERENCES_CACHESTRAT1;Выше ÑкороÑть - больше раÑход ОЗУ +PREFERENCES_CACHESTRAT2;Меньше раÑход памÑти - ÑкороÑть ниже +PREFERENCES_CACHESTRAT;Ð¡Ñ‚Ñ€Ð°Ñ‚ÐµÐ³Ð¸Ñ ÐºÑÑˆÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ +PREFERENCES_CACHETHUMBFORM;Формат кÑÑˆÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ ÑÑкизов +PREFERENCES_CACHETHUMBHEIGHT;МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð²Ñ‹Ñота ÑÑкиза +PREFERENCES_CLEARDLG_LINE1;ОчиÑтка кÑша +PREFERENCES_CLEARDLG_LINE2;Это может занÑть неÑколько Ñекунд. +PREFERENCES_CLEARDLG_TITLE;ПожалуйÑта, подождите +PREFERENCES_CLIPPINGIND;Ð˜Ð½Ð´Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð¿ÐµÑ€ÐµÑветов/затемнений +PREFERENCES_CMETRICINTENT;КолориметричеÑкое преобразование +PREFERENCES_DATEFORMATHINT;Ð’Ñ‹ можете иÑпользовать Ñледующие Ñлементы форматированиÑ:\n%y : год\n%m : меÑÑц\n%d : день\n\nÐапример, венгерÑкий формат даты такой:\n%y/%m/%d +PREFERENCES_DATEFORMAT;Формат даты +PREFERENCES_DEFAULTLANG;Язык по умолчанию +PREFERENCES_DEFAULTTHEME;Тема по умолчанию +PREFERENCES_DEMOSAICINGALGO;Ðлгоритм Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ +PREFERENCES_DIRHOME;Домашний каталог +PREFERENCES_DIRLAST;ПоÑледний каталог +PREFERENCES_DIROTHER;Другой +PREFERENCES_DIRSELECTDLG;Выберите каталог Ð´Ð»Ñ Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ð¹ +PREFERENCES_DIRSOFTWARE;Каталог уÑтановки +PREFERENCES_DMETHOD;Метод +PREFERENCES_EDITORCMDLINE;Другой (путь к иÑполнÑемому файлу) +PREFERENCES_EXTERNALEDITOR;Внешний редактор +PREFERENCES_FALSECOLOR;ЧиÑло шагов Ð´Ð»Ñ Ð¿Ð¾Ð´Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½ÐµÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ñ‹Ñ… цветов +PREFERENCES_FBROWSEROPTS;ÐаÑтройки +PREFERENCES_FILEFORMAT;Формат файлов +PREFERENCES_FORIMAGE;Ð”Ð»Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ð¹ +PREFERENCES_FORRAW;Ð”Ð»Ñ RAW файлов +PREFERENCES_GIMPPATH;Путь уÑтановки GIMP +PREFERENCES_GTKTHEME;GTK по умолчанию +PREFERENCES_HINT;ПодÑказка +PREFERENCES_HLTHRESHOLD;Порог ÑÑ€Ð°Ð±Ð°Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð¿ÐµÑ€ÐµÑветов +PREFERENCES_ICCDIR;Каталог ICC профилей +PREFERENCES_IMPROCPARAMS;Параметры обработки по умолчанию +PREFERENCES_INTENT_ABSOLUTE;ÐбÑолютное +PREFERENCES_INTENT_PERCEPTUAL;Перцепционное +PREFERENCES_INTENT_RELATIVE;ОтноÑительное +PREFERENCES_INTENT_SATURATION;По наÑыщенноÑти +PREFERENCES_LIVETHUMBNAILS;ЭÑкизы в реальном времени (медленно) +PREFERENCES_MONITORICC;Профиль монитора +PREFERENCES_OUTDIRFOLDERHINT;Сохранение изображений в выбранный каталог +PREFERENCES_OUTDIRFOLDER;Каталог Ð´Ð»Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ð¹ +PREFERENCES_OUTDIRHINT;Ð’Ñ‹ можете иÑпользовать Ñледующие Ñлементы форматированиÑ:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nЭти Ñлементы ÑоответÑтвуют каталогам и подкаталогам в пути к RAW-файлу.\n\nÐапример, еÑли путь к файлу - /home/tom/image/02-09-2006/dsc0012.nef, то Ñлементы Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð±ÑƒÐ´ÑƒÑ‚ Ñледующими:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nЕÑли вы хотите ÑохранÑть Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð² один каталог Ñ Ð¾Ñ€Ð¸Ð³Ð¸Ð½Ð°Ð»Ð¾Ð¼, введите Ñтроку:\n%p1/%f\n\nЕÑли вы хотите ÑохранÑть Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð² подкаталог "converted" в каталоге оригинального файла, введите Ñтроку:\n%p1/converted/%f\n\nÐ”Ð»Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ð¹ в каталог "/home/tom/converted" Ñ Ñохранением подкаталогов Ñ Ð´Ð°Ñ‚Ð°Ð¼Ð¸, введите Ñтроку:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;Ð’Ñ‹ можете иÑпользовать Ñледующие Ñлементы форматированиÑ:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nЭти Ñлементы ÑоответÑтвуют каталогам и подкаталогам в пути к RAW-файлу.\n\nÐапример, еÑли был открыт каталог /home/tom/image/02-09-2006/dsc0012.nef, то Ñлементы Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð±ÑƒÐ´ÑƒÑ‚ выглÑдеть так:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nЕÑли вы хотите ÑохранÑть Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð² каталоге Ñ Ð¾Ñ€Ð¸Ð³Ð¸Ð½Ð°Ð»Ð¾Ð¼, введите:\n%p1/%f\n\nЕÑли вы хотите ÑохранÑть Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð² каталоге "converted", раÑположенной в каталоге оригинального файла, введите Ñтроку:\n%p1/converted/%f\n\nÐ”Ð»Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ð¹ папке в "/home/tom/converted" Ñ Ñохранением подкаталогов Ñ Ð´Ð°Ñ‚Ð°Ð¼Ð¸, введите Ñтроку:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;ИÑпользовать шаблон +PREFERENCES_OUTDIR;Каталог +PREFERENCES_PARSEDEXTADDHINT;Введите раÑширение и нажмите на Ñту кнопку, чтобы добавить его в ÑпиÑок +PREFERENCES_PARSEDEXTADD;Добавить +PREFERENCES_PARSEDEXTDELHINT;Удаление выбранных раÑширений из ÑпиÑка +PREFERENCES_PARSEDEXT;РаÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´Ð¿Ñ€Ð¾Ñмотра +PREFERENCES_PROFILEHANDLING;Профиль поÑтобработки +PREFERENCES_PROFILELOADPR;Приоритет загрузки Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ Ð¿Ð¾Ñтобработки +PREFERENCES_PROFILEPRCACHE;загружать из кÑша +PREFERENCES_PROFILEPRFILE;загружать из каталога Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð¼ +PREFERENCES_PROFILESAVECACHE;Сохранить профиль поÑтобработки в кÑше +PREFERENCES_PROFILESAVEINPUT;Сохранить профиль поÑтобработки в одном каталоге Ñ Ð¸Ñходным файлом +PREFERENCES_PSPATH;Путь уÑтановки Adobe Photoshop +PREFERENCES_SELECTICCDIRDLG;Выберите каталог Ð´Ð»Ñ ICC профилÑ... +PREFERENCES_SELECTLANG;Выберите Ñзык +PREFERENCES_SELECTMONITORPROFDLG;Выберите каталог Ð´Ð»Ñ ICC Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ Ð¼Ð¾Ð½Ð¸Ñ‚Ð¾Ñ€Ð°... +PREFERENCES_SELECTTHEME;Выбрать тему +PREFERENCES_SHOWBASICEXIF;Показывать оÑновные Exif данные +PREFERENCES_SHOWDATETIME;Показывать дату и Ð²Ñ€ÐµÐ¼Ñ +PREFERENCES_SHOWONLYRAW;Показывать только RAW-файлы +PREFERENCES_SHTHRESHOLD;Порог ÑÑ€Ð°Ð±Ð°Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð·Ð°Ñ‚ÐµÐ¼Ð½ÐµÐ½Ð¸Ð¹ +PREFERENCES_STARTUPIMDIR;Каталог изображений при запуÑке +PREFERENCES_TAB_BROWSER;Браузер файлов +PREFERENCES_TAB_COLORMGR;Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ†Ð²ÐµÑ‚Ð¾Ð¼ +PREFERENCES_TAB_GENERAL;ОÑновные +PREFERENCES_TAB_IMPROC;Обработка Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ +PREFERENCES_TAB_OUTPUT;Сохранение +PREFERENCES_THUMBSIZE;Размер миниатюры +PROFILEPANEL_FILEDLGFILTERANY;Любые файлы +PROFILEPANEL_FILEDLGFILTERPP;Профили поÑтобработки +PROFILEPANEL_LABEL;Профиль поÑтобработки +PROFILEPANEL_LOADDLGLABEL;Загрузить профиль поÑтобработки... +PROFILEPANEL_PCUSTOM;ПользовательÑкий +PROFILEPANEL_PFILE;Из файла +PROFILEPANEL_PLASTPHOTO;Из прошлого Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ +PROFILEPANEL_PLASTSAVED;ПоÑлед. Ñохр. +PROFILEPANEL_PROFILE;Профиль +PROFILEPANEL_SAVEDLGLABEL;Сохранить профиль поÑтобработки... +PROFILEPANEL_TOOLTIPCOPY;Скопировать текущий профиль в буфер обмена +PROFILEPANEL_TOOLTIPLOAD;Загрузить профиль из файла +PROFILEPANEL_TOOLTIPPASTE;Ð’Ñтавить профиль из буфера обмена +PROFILEPANEL_TOOLTIPSAVE;Сохранить текущий профиль +PROGRESSBAR_DECODING;Декодирование RAW файла... +PROGRESSBAR_DEMOSAICING;ПоÑтроение изображениÑ... +PROGRESSBAR_LOADING;Загрузка изображениÑ... +PROGRESSBAR_LOADJPEG;Чтение JPEG файла... +PROGRESSBAR_LOADPNG;Чтение PNG файла... +PROGRESSBAR_LOADTIFF;Чтение TIFF файла... +PROGRESSBAR_PROCESSING;Обработка изображениÑ... +PROGRESSBAR_READY;Готово. +PROGRESSBAR_SAVEJPEG;Сохранение JPEG файла... +PROGRESSBAR_SAVEPNG;Сохранение PNG файла... +PROGRESSBAR_SAVETIFF;Сохранение TIFF файла... +PROGRESSDLG_LOADING;Загрузка файла... +PROGRESSDLG_PROCESSING;Обработка изображениÑ... +PROGRESSDLG_SAVING;Сохранение файла... +QINFO_FOCALLENGTH;Focal Lenth +QINFO_ISO;ISO +QINFO_LENS;Объектив +QINFO_NOEXIF;Данные Exif недоÑтупны +SAVEDLG_FILEFORMAT;Формат файла +SAVEDLG_JPEGQUAL;КачеÑтво JPEG +SAVEDLG_JPGFILTER;Файлы JPEG +SAVEDLG_PNGCOMPR;Сжатие PNG +SAVEDLG_PNGFILTER;Файлы PNG +SAVEDLG_PUTTOQUEUEHEAD;ПомеÑтить в начало очереди на обработку +SAVEDLG_PUTTOQUEUETAIL;ПомеÑтить в конец очереди на обработку +SAVEDLG_PUTTOQUEUE;ПомеÑтить в очередь на обработку +SAVEDLG_SAVEIMMEDIATELY;Сохранить ÑÐµÐ¹Ñ‡Ð°Ñ +SAVEDLG_SAVESPP;СохранÑть параметры обработки вмеÑте Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸ÐµÐ¼ +SAVEDLG_TIFFFILTER;Файлы TIFF +TOOLBAR_TOOLTIP_CROP;Кадрирование (горÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: C) +TOOLBAR_TOOLTIP_HAND;ИнÑтрумент "Рука" (горÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;УÑтановка прÑмой линии (горÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: S) +TOOLBAR_TOOLTIP_WB;Указать белую точку (горÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: W) +TP_CACORRECTION_BLUE;Синий +TP_CACORRECTION_LABEL;ХроматичеÑкие аберрации +TP_CACORRECTION_RED;КраÑный +TP_CHMIXER_BLUE;Синий +TP_CHMIXER_GREEN;Зелёный +TP_CHMIXER_LABEL;Цветовые каналы +TP_CHMIXER_RED;КраÑный +TP_COARSETRAF_DEGREE;угол: +TP_COARSETRAF_TOOLTIP_HFLIP;Гориз. зеркальное отражение +TP_COARSETRAF_TOOLTIP_ROTLEFT;Повернуть влево +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Повернуть вправо +TP_COARSETRAF_TOOLTIP_VFLIP;Верт. зеркальное отражение +TP_COLORBOOST_ACHANNEL;Канал "a" +TP_COLORBOOST_AMOUNT;Величина +TP_COLORBOOST_AVOIDCOLORCLIP;Избегать Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ñ†Ð²ÐµÑ‚Ð¾Ð² +TP_COLORBOOST_BCHANNEL;Канал "b" +TP_COLORBOOST_CHAB;a & b +TP_COLORBOOST_CHANNEL;Канал +TP_COLORBOOST_CHSEPARATE;По отдельноÑти +TP_COLORBOOST_ENABLESATLIMITER;Ограничение наÑыщенноÑти +TP_COLORBOOST_LABEL;УÑиление цвета +TP_COLORBOOST_SATLIMIT;Ограничение наÑыщенноÑти +TP_COLORDENOISE_EDGESENSITIVE;ЧувÑтвительноÑть к границам +TP_COLORDENOISE_EDGETOLERANCE;УÑтойчивоÑть к границам +TP_COLORDENOISE_LABEL;Удаление цветового шума +TP_COLORDENOISE_RADIUS;Ð Ð°Ð´Ð¸ÑƒÑ +TP_COLORSHIFT_BLUEYELLOW;Синий-Жёлтый +TP_COLORSHIFT_GREENMAGENTA;Зелёный-Пурпурный +TP_COLORSHIFT_LABEL;Сдвиг цвета +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;ПропорциÑ: +TP_CROP_GTDIAGONALS;Правило диагоналей +TP_CROP_GTHARMMEANS1;Среднее гармоничеÑкое 1 +TP_CROP_GTHARMMEANS2;Среднее гармоничеÑкое 2 +TP_CROP_GTHARMMEANS3;Среднее гармоничеÑкое 3 +TP_CROP_GTHARMMEANS4;Среднее гармоничеÑкое 4 +TP_CROP_GTNONE;Ðет +TP_CROP_GTRULETHIRDS;Правило третей +TP_CROP_GUIDETYPE;Тип направлÑющей: +TP_CROP_H;Ð’ +TP_CROP_LABEL;Кадрирование +TP_CROP_SELECTCROP; Вкл. режим обрезки +TP_CROP_W;Ш +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Величина +TP_DISTORTION_LABEL;ДиÑторÑÐ¸Ñ +TP_EXPOSURE_AUTOLEVELS;ÐвтоматичеÑкие уровни +TP_EXPOSURE_BLACKLEVEL;Уровень чёрного +TP_EXPOSURE_BRIGHTNESS;ЯркоÑть +TP_EXPOSURE_CLIP;Ограничить +TP_EXPOSURE_COMPRHIGHLIGHTS;Сжатие Ñветов +TP_EXPOSURE_COMPRSHADOWS;Сжатие теней +TP_EXPOSURE_CONTRAST;КонтраÑÑ‚ +TP_EXPOSURE_CURVEEDITOR;Ð¢Ð¾Ð½Ð¾Ð²Ð°Ñ ÐºÑ€Ð¸Ð²Ð°Ñ +TP_EXPOSURE_EXPCOMP;КомпенÑÐ°Ñ†Ð¸Ñ ÑкÑпозиции +TP_EXPOSURE_LABEL;ЭкÑÐ¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ +TP_HLREC_CIELAB;Смешивание CIELab +TP_HLREC_COLOR;РеконÑÑ‚Ñ€ÑƒÐºÑ†Ð¸Ñ Ñ†Ð²ÐµÑ‚Ð° +TP_HLREC_LABEL;ВоÑÑтановление Ñрких учаÑтков +TP_HLREC_LUMINANCE;ВоÑÑтановление ÑркоÑти +TP_HLREC_METHOD;Метод: +TP_ICM_FILEDLGFILTERANY;Любые файлы +TP_ICM_FILEDLGFILTERICM;Файлы ICC профилей +TP_ICM_GAMMABEFOREINPUT;ПрименÑть гамму Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ +TP_ICM_INPUTCAMERA;По умолчанию Ð´Ð»Ñ ÐºÐ°Ð¼ÐµÑ€Ñ‹ +TP_ICM_INPUTCUSTOM;ПользовательÑкий +TP_ICM_INPUTDLGLABEL;Выберите входной ICC профиль... +TP_ICM_INPUTEMBEDDED;ИÑпользовать вÑтроенный, еÑли Ñто возможно +TP_ICM_INPUTPROFILE;Входной профиль +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Без ICM: sRGB на выходе +TP_ICM_OUTPUTDLGLABEL;Выберите выходной ICC профиль... +TP_ICM_OUTPUTPROFILE;Выходной профиль +TP_ICM_SAVEREFERENCE;Сохранить иÑходное изображение Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ +TP_ICM_WORKINGPROFILE;Рабочий профиль +TP_LUMACURVE_BLACKLEVEL;Уровень чёрного +TP_LUMACURVE_BRIGHTNESS;ЯркоÑть +TP_LUMACURVE_COMPRHIGHLIGHTS;Сжатие Ñветов +TP_LUMACURVE_COMPRSHADOWS;Сжатие теней +TP_LUMACURVE_CONTRAST;КонтраÑÑ‚ +TP_LUMACURVE_CURVEEDITOR;Ð¢Ð¾Ð½Ð¾Ð²Ð°Ñ ÐºÑ€Ð¸Ð²Ð°Ñ +TP_LUMACURVE_LABEL;ÐšÑ€Ð¸Ð²Ð°Ñ ÑркоÑти +TP_LUMADENOISE_EDGETOLERANCE;УÑтойчивоÑть к границам +TP_LUMADENOISE_LABEL;Удаление шума +TP_LUMADENOISE_RADIUS;Ñ€Ð°Ð´Ð¸ÑƒÑ +TP_RESIZE_BICUBICSF;МÑгкий бикубичеÑкий +TP_RESIZE_BICUBICSH;Резкий бикубичеÑкий +TP_RESIZE_BICUBIC;БикубичеÑкий +TP_RESIZE_BILINEAR;Билинейный +TP_RESIZE_FULLSIZE;Размер изображениÑ: +TP_RESIZE_H;Ð’: +TP_RESIZE_LABEL;Изменение размера +TP_RESIZE_METHOD;Метод: +TP_RESIZE_NEAREST;Ближайшие точки +TP_RESIZE_SCALE;МаÑштаб +TP_RESIZE_W;Ш: +TP_ROTATE_AUTOCROP;Ðвто-кадрирование +TP_ROTATE_DEGREE;Угол +TP_ROTATE_FILL;Ðвтообрезка +TP_ROTATE_LABEL;Поворот +TP_ROTATE_SELECTLINE; Выбрать прÑмую линию +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Света +TP_SHADOWSHLIGHTS_HLTONALW;Уровень +TP_SHADOWSHLIGHTS_LABEL;Тени/Ñвета +TP_SHADOWSHLIGHTS_LOCALCONTR;Локальный контраÑÑ‚ +TP_SHADOWSHLIGHTS_RADIUS;Ð Ð°Ð´Ð¸ÑƒÑ +TP_SHADOWSHLIGHTS_SHADOWS;Тени +TP_SHADOWSHLIGHTS_SHTONALW;Уровень +TP_SHARPENING_AMOUNT;Величина +TP_SHARPENING_EDRADIUS;Ð Ð°Ð´Ð¸ÑƒÑ +TP_SHARPENING_EDTOLERANCE;Границы краёв +TP_SHARPENING_HALOCONTROL;Регулировка хром. аберраций +TP_SHARPENING_HCAMOUNT;Величина +TP_SHARPENING_LABEL;РезкоÑть +TP_SHARPENING_METHOD;Метод +TP_SHARPENING_ONLYEDGES;Только границы +TP_SHARPENING_RADIUS;Ð Ð°Ð´Ð¸ÑƒÑ +TP_SHARPENING_RLD_AMOUNT;Величина +TP_SHARPENING_RLD_DAMPING;ОÑлабление +TP_SHARPENING_RLD_ITERATIONS;Повторений +TP_SHARPENING_RLD;ÐžÐ±Ñ€Ð°Ñ‰Ñ‘Ð½Ð½Ð°Ñ Ñвёртка RL +TP_SHARPENING_THRESHOLD;Порог +TP_SHARPENING_USM;МаÑка Ñ€Ð°Ð·Ð¼Ñ‹Ñ‚Ð¸Ñ +TP_VIGNETTING_AMOUNT;Величина +TP_VIGNETTING_LABEL;Виньетирование +TP_VIGNETTING_RADIUS;Ð Ð°Ð´Ð¸ÑƒÑ +TP_WBALANCE_AUTO;ÐвтоматичеÑкий +TP_WBALANCE_CAMERA;Камера +TP_WBALANCE_CUSTOM;ПользовательÑкий +TP_WBALANCE_GREEN;Оттенок +TP_WBALANCE_LABEL;Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾ +TP_WBALANCE_METHOD;Метод +TP_WBALANCE_SIZE;Размер пипетки: +TP_WBALANCE_SPOTWB;Указать точку белого +TP_WBALANCE_TEMPERATURE;Температура +ZOOMBAR_DETAIL;Увеличение +ZOOMBAR_HUGE;МакÑимальное +ZOOMBAR_LARGE;Большое +ZOOMBAR_NORMAL;Среднее +ZOOMBAR_PREVIEW;ПредпроÑмотр +ZOOMBAR_SCALE;МаÑштаб +ZOOMBAR_SMALL;Минимальное + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Slovak b/rtdata/languages/Slovak new file mode 100644 index 000000000..36fc3b5dd --- /dev/null +++ b/rtdata/languages/Slovak @@ -0,0 +1,704 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# SlovenÄina +# 08.05.2008 +# 01.02.2009 +# (Slapo) +ADJUSTER_RESET_TO_DEFAULT;ResetovaÅ¥ na predvolené nastavenia +CURVEEDITOR_FILEDLGFILTERANY;VÅ¡etky súbory +CURVEEDITOR_FILEDLGFILTERCURVE;Súbory kriviek +CURVEEDITOR_LINEAR;Lineárna +CURVEEDITOR_LOADDLGLABEL;NaÄítaÅ¥ krivku... +CURVEEDITOR_SAVEDLGLABEL;UložiÅ¥ krivku... +CURVEEDITOR_TOOLTIPLINEAR;ResetovaÅ¥ krivku na lineárnu +CURVEEDITOR_TOOLTIPLOAD;NaÄítaÅ¥ krivku zo súboru +CURVEEDITOR_TOOLTIPSAVE;UložiÅ¥ súÄasnú krivku +EXIFFILTER_APERTURE;Clona +EXIFFILTER_CAMERA;Fotoaparát +EXIFFILTER_DIALOGLABEL;Exif filter +EXIFFILTER_FOCALLEN;Ohnisková vzdialenosÅ¥ +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objektív +EXIFFILTER_SHUTTER;Uzávierka +EXIFPANEL_ADDEDITHINT;PridaÅ¥ novú znaÄku alebo upraviÅ¥ znaÄku +EXIFPANEL_ADDEDIT;PridaÅ¥/UpraviÅ¥ +EXIFPANEL_ADDTAGDLG_ENTERVALUE;VložiÅ¥ hodnotu +EXIFPANEL_ADDTAGDLG_SELECTTAG;VybraÅ¥ znaÄku +EXIFPANEL_ADDTAGDLG_TITLE;PridaÅ¥/UpraviÅ¥ znaÄku +EXIFPANEL_KEEPHINT;PonechaÅ¥ vybrané znaÄky pri písaní výstupného súboru +EXIFPANEL_KEEP;PonechaÅ¥ +EXIFPANEL_REMOVEHINT;OdstrániÅ¥ vybrané znaÄky pri písaní výstupného súboru +EXIFPANEL_REMOVE;OdstrániÅ¥ +EXIFPANEL_RESETALLHINT;ResetovaÅ¥ vÅ¡etky znaÄky na ich pôvodné hodnoty +EXIFPANEL_RESETALL;ResetovaÅ¥ vÅ¡etky +EXIFPANEL_RESETHINT;ResetovaÅ¥ vybrané znaÄky na ich pôvodné hodnoty +EXIFPANEL_RESET;ResetovaÅ¥ +EXIFPANEL_SUBDIRECTORY;Podadresár +FILEBROWSER_APPLYPROFILE;PoužiÅ¥ profil +FILEBROWSER_ARRANGEMENTHINT;ZmeniÅ¥ medzi vertikálnym/horizontálnym zarovnaním zmenÅ¡enín +FILEBROWSER_CLEARPROFILE;VyÄistiÅ¥ profil +FILEBROWSER_COPYPROFILE;KopírovaÅ¥ profil +FILEBROWSER_DELETEDLGLABEL;Potvrdenie odstránenia súboru +FILEBROWSER_DELETEDLGMSG;Ste si istí, že chcete odstrániÅ¥ vybrané %1 súbory? +FILEBROWSER_EMPTYTRASHHINT;Permanentne odstrániÅ¥ súbory z koÅ¡a +FILEBROWSER_EMPTYTRASH;VyprázdniÅ¥ kôš +FILEBROWSER_EXIFFILTERAPPLYHINT;Zapnúť/vypnúť EXIF filter prehliadaÄa súborov +FILEBROWSER_EXIFFILTERAPPLY;PoužiÅ¥ +FILEBROWSER_EXIFFILTERLABEL;Exif Filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Zmeňte nastavenia EXIF filtra +FILEBROWSER_EXIFFILTERSETTINGS;Nastavenia +FILEBROWSER_PARTIALPASTEPROFILE;ÄŒiastoÄné vloženie +FILEBROWSER_PASTEPROFILE;VložiÅ¥ profil +FILEBROWSER_POPUPCANCELJOB;ZruÅ¡iÅ¥ úlohu +FILEBROWSER_POPUPMOVEEND;Presunúť na koniec radu +FILEBROWSER_POPUPMOVEHEAD;Presunúť na zaÄiatok radu +FILEBROWSER_POPUPOPEN;OtvoriÅ¥ +FILEBROWSER_POPUPPROCESS;VložiÅ¥ do radu na spracovanie +FILEBROWSER_POPUPRANK1;Trieda 1 +FILEBROWSER_POPUPRANK2;Trieda 2 +FILEBROWSER_POPUPRANK3;Trieda 3 +FILEBROWSER_POPUPRANK4;Trieda 4 +FILEBROWSER_POPUPRANK5;Trieda 5 +FILEBROWSER_POPUPREMOVE;OdstrániÅ¥ zo systému súborov +FILEBROWSER_POPUPRENAME;PremenovaÅ¥ +FILEBROWSER_POPUPSELECTALL;VybraÅ¥ vÅ¡etko +FILEBROWSER_POPUPTRASH;Presunúť do koÅ¡a +FILEBROWSER_POPUPUNRANK;ZruÅ¡iÅ¥ triedu +FILEBROWSER_POPUPUNTRASH;OdstrániÅ¥ z koÅ¡a +FILEBROWSER_PROCESSINGSETTINGSHINT;NastaviÅ¥ formát súborov a výstupný adresár +FILEBROWSER_PROCESSINGSETTINGS;Nastavenia +FILEBROWSER_RENAMEDLGLABEL;PremenovaÅ¥ súbor +FILEBROWSER_RENAMEDLGMSG;PremenovaÅ¥ súbor "%1" na: +FILEBROWSER_SHOWDIRHINT;UkázaÅ¥ vÅ¡etky obrázky v adresári +FILEBROWSER_SHOWQUEUEHINT;ZobraziÅ¥ obsah radu na spracovanie +FILEBROWSER_SHOWRANK1HINT;UkázaÅ¥ obrázky triedy 1 hviezda +FILEBROWSER_SHOWRANK2HINT;UkázaÅ¥ obrázky triedy 2 hviezda +FILEBROWSER_SHOWRANK3HINT;UkázaÅ¥ obrázky triedy 3 hviezda +FILEBROWSER_SHOWRANK4HINT;UkázaÅ¥ obrázky triedy 4 hviezda +FILEBROWSER_SHOWRANK5HINT;UkázaÅ¥ obrázky triedy 5 hviezda +FILEBROWSER_SHOWTRASHHINT;ZobraziÅ¥ obsah koÅ¡a +FILEBROWSER_SHOWUNRANKHINT;ZobraziÅ¥ obrázky bez triedy +FILEBROWSER_STARTPROCESSINGHINT;ZaÄaÅ¥ spracovanie/ukladanie obrázkov v rade +FILEBROWSER_STARTPROCESSING;ZaÄaÅ¥ spracovanie +FILEBROWSER_STOPPROCESSINGHINT;ZastaviÅ¥ spracovanie obrázkov +FILEBROWSER_STOPPROCESSING;ZastaviÅ¥ spracovanie +FILEBROWSER_THUMBSIZE;VeľkosÅ¥ zmenÅ¡enín +FILEBROWSER_ZOOMINHINT;ZväÄÅ¡iÅ¥ veľkosÅ¥ zmenÅ¡enín +FILEBROWSER_ZOOMOUTHINT;ZmenÅ¡iÅ¥ veľkosÅ¥ zmenÅ¡enín +GENERAL_ABOUT;O programe +GENERAL_CANCEL;ZruÅ¡iÅ¥ +GENERAL_DISABLED;Zakázané +GENERAL_DISABLE;ZakázaÅ¥ +GENERAL_ENABLED;Povolené +GENERAL_ENABLE;PovoliÅ¥ +GENERAL_LANDSCAPE;Krajina +GENERAL_LOAD;NaÄítaÅ¥ +GENERAL_NA;n/a +GENERAL_NO;Nie +GENERAL_OK;OK +GENERAL_PORTRAIT;Portrét +GENERAL_SAVE;UložiÅ¥ +GENERAL_YES;Ãno +HISTOGRAM_LABEL;Histogram +HISTOGRAM_TOOLTIP_B;ZobraziÅ¥/SchovaÅ¥ MODRà histogram +HISTOGRAM_TOOLTIP_G;ZobraziÅ¥/SchovaÅ¥ ZELENà histogram +HISTOGRAM_TOOLTIP_L;ZobraziÅ¥/SchovaÅ¥ histogram CIELAB svietivosti +HISTOGRAM_TOOLTIP_R;ZobraziÅ¥/SchovaÅ¥ ÄŒERVENà histogram +HISTORY_CHANGED;Zmenené +HISTORY_CUSTOMCURVE;Vlastná krivka +HISTORY_DELSNAPSHOT;OdstrániÅ¥ Snímok +HISTORY_FROMCLIPBOARD;Zo schránky +HISTORY_LABEL;História +HISTORY_MSG_10;Kompresia tieňov +HISTORY_MSG_11;Krivka tónov +HISTORY_MSG_12;Auto expozícia +HISTORY_MSG_13;Orezávanie expozície +HISTORY_MSG_14;Jas svietivosti +HISTORY_MSG_15;Kontrast svietivosti +HISTORY_MSG_16;ÄŒierna svietivosti +HISTORY_MSG_17;Kompresia najvyšších svetiel v oblasti svietivosti +HISTORY_MSG_18;Kompresia tieňov v oblasti svietivosti +HISTORY_MSG_19;Krivka svietivosti +HISTORY_MSG_1;Fotka naÄítaná +HISTORY_MSG_20;Doostrenie +HISTORY_MSG_21;Polomer doostrenia +HISTORY_MSG_22;Množstvo doostrenia +HISTORY_MSG_23;Prah doostrenia +HISTORY_MSG_24;DoostriÅ¥ len okraje +HISTORY_MSG_25;Polomer detekcie okrajov pri doostrení +HISTORY_MSG_26;Tolerancia okrajov pri doostrení +HISTORY_MSG_27;Kontrola svätožiary pri doostrení +HISTORY_MSG_28;Množstvo kontroly svätožiary +HISTORY_MSG_29;Doostrovacia metóda +HISTORY_MSG_2;Profil naÄítaný +HISTORY_MSG_30;Polomer dekonvolúcie +HISTORY_MSG_31;Množstvo dekonvolúcie +HISTORY_MSG_32;Tlmenie dekonvolúcie +HISTORY_MSG_33;Iterácie dekonvolúcie +HISTORY_MSG_34;Vyhnúť sa orezaniu farieb +HISTORY_MSG_35;ObmedzovaÄ sýtosti +HISTORY_MSG_36;Hranica sýtosti +HISTORY_MSG_37;Zosilnenie farieb +HISTORY_MSG_38;Metóda vyváženia bielej +HISTORY_MSG_39;Farebná teplota +HISTORY_MSG_3;Profil zmenený +HISTORY_MSG_40;Nádych vyváženia bielej +HISTORY_MSG_41;Farebný posun "A" +HISTORY_MSG_42;Farebný posun "B" +HISTORY_MSG_43;OdÅ¡umenie svietivosti +HISTORY_MSG_44;Polomer odÅ¡umenia svietivosti +HISTORY_MSG_45;Tolerancia okrajov odÅ¡umenia svietivosti +HISTORY_MSG_46;Farebné odÅ¡umenie +HISTORY_MSG_47;Polomer farebného odÅ¡umenia +HISTORY_MSG_48;Tolerancia okrajov farebného odÅ¡umenia +HISTORY_MSG_49;CitlivosÅ¥ na okraje pri farebnom odÅ¡umení +HISTORY_MSG_4;História prehliadania +HISTORY_MSG_50;Nástroj Tiene/Najvyššie svetlá +HISTORY_MSG_51;Zosilnenie najvyšších svetiel +HISTORY_MSG_52;Zosilnenie tieňov +HISTORY_MSG_53;Tonálna šírka najvyšších svetiel +HISTORY_MSG_54;Tonálna šírka tieňov +HISTORY_MSG_55;Miestny kontrast +HISTORY_MSG_56;Polomer Tiene/Najvyššie svetlá +HISTORY_MSG_57;Hrubé otoÄenie +HISTORY_MSG_58;Horizontálne preklápanie +HISTORY_MSG_59;Vertikálne preklápanie +HISTORY_MSG_5;Jas +HISTORY_MSG_60;OtoÄenie +HISTORY_MSG_61;OtoÄenie +HISTORY_MSG_62;Korekcia zakrivenia objektívu +HISTORY_MSG_63;Záložka vybraná +HISTORY_MSG_64;Orezanie fotky +HISTORY_MSG_65;Korekcia chromatickej aberácie +HISTORY_MSG_66;Obnova najvyšších svetiel +HISTORY_MSG_67;Množstvo obnovy najvyšších svetiel +HISTORY_MSG_68;Metóda obnovy najvyšších svetiel +HISTORY_MSG_69;Pracovný farebný priestor +HISTORY_MSG_6;Kontrast +HISTORY_MSG_70;Výstupný farebný priestor +HISTORY_MSG_71;Vstupný farebný priestor +HISTORY_MSG_72;Korekcia vignetácie +HISTORY_MSG_73;Mixér kanálov +HISTORY_MSG_74;ZmeniÅ¥ veľkosÅ¥ - Rozmer +HISTORY_MSG_75;ZmeniÅ¥ veľkosÅ¥ - Metóda +HISTORY_MSG_76;Exif Metadáta +HISTORY_MSG_77;IPTC Metadáta +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;ÄŒierna +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;Kompenzácia expozície +HISTORY_MSG_9;Kompresia najvyšších svetiel +HISTORY_NEWSNAPSHOTAS;Ako... +HISTORY_NEWSNAPSHOT;Nový Snímok +HISTORY_NEWSSDIALOGLABEL;Menovka snímku: +HISTORY_NEWSSDIALOGTITLE;PridaÅ¥ nový snímok +HISTORY_SETTO;NastaviÅ¥ na +HISTORY_SNAPSHOT;Snímok +HISTORY_SNAPSHOTS;Snímky +ICMPANEL_FILEDLGFILTERANY;VÅ¡etky súbory +ICMPANEL_FILEDLGFILTERICM;Súbory ICC profilu +ICMPANEL_GAMMABEFOREINPUT;Profil aplikuje Gamu +ICMPANEL_INPUTCAMERA;Predvolený aparátu +ICMPANEL_INPUTCUSTOM;Vlastný +ICMPANEL_INPUTDLGLABEL;VybraÅ¥ vstupný ICC profil... +ICMPANEL_INPUTEMBEDDED;PoužiÅ¥ vstavaný, ak je to možné +ICMPANEL_INPUTPROFILE;Vstupný profil +ICMPANEL_NOICM;Bez správy farieb: sRGB výstup +ICMPANEL_OUTPUTDLGLABEL;VybraÅ¥ výstupný ICC profil... +ICMPANEL_OUTPUTPROFILE;Výstupný profil +ICMPANEL_SAVEREFERENCE;UložiÅ¥ referenÄný obrázok pre tvorbu profilu +ICMPANEL_WORKINGPROFILE;Pracovný profil +IMAGEAREA_DETAILVIEW;Zobrazenie detailov +IPTCPANEL_AUTHOR;Autor +IPTCPANEL_AUTHORHINT;Meno tvorcu objektu, napr. pisateľa, fotografa alebo grafika (Meno autora). +IPTCPANEL_AUTHORSPOSITION;Autorov titul +IPTCPANEL_AUTHORSPOSITIONHINT;Titul tvorcu alebo tvorcov objektu (Titul pri mene autora). +IPTCPANEL_CAPTIONHINT;Textový opis údajov (Titul - Abstrakt). +IPTCPANEL_CAPTION;Titul +IPTCPANEL_CAPTIONWRITERHINT;Meno osoby, ktorá titul/abstrakt obrazu napísala, upravila alebo opravila (Pisateľ - Editor). +IPTCPANEL_CAPTIONWRITER;Pisateľ titulu +IPTCPANEL_CATEGORYHINT;Identifikuje subjekt obrázka podľa názoru poskytovateľa (Kategória). +IPTCPANEL_CATEGORY;Kategória +IPTCPANEL_CITYHINT;Mesto pôvodu (Mesto). +IPTCPANEL_CITY;Mesto +IPTCPANEL_COPYHINT;KopírovaÅ¥ IPTC nastavenia do schránky +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COPYRIGHTHINT;Akýkoľvek potrebný oznam o copyrighte (Oznam o copyrighte). +IPTCPANEL_COUNTRYHINT;Názov krajiny/miesta pôvodu (Krajina - miesto pôvodu). +IPTCPANEL_COUNTRY;Krajina +IPTCPANEL_CREDITHINT;Identifikuje poskytovateľa obrázka, nemusí byÅ¥ nevyhnutne vlastníkom/tvorcom (Kredit). +IPTCPANEL_CREDIT;Kredit +IPTCPANEL_DATECREATED;Dátum vytvorenia +IPTCPANEL_DATECREATEDHINT;Dátum, kedy bol vytvorený intelektuálny obsah obrázka; Formát: RRRRMMDD (Deň vytvorenia). +IPTCPANEL_EMBEDDEDHINT;ResetovaÅ¥ na IPTV údaje vložené do obrázka +IPTCPANEL_EMBEDDED;Vložené +IPTCPANEL_HEADLINEHINT;Publikovateľný vstup poskytujúci zhrnutie obsahu obrázka (Nadpis). +IPTCPANEL_HEADLINE;Nadpis +IPTCPANEL_INSTRUCTIONSHINT;Iné pokyny ohľadne použitia obrázka (Å peciálne pokyny). +IPTCPANEL_INSTRUCTIONS;Pokyny +IPTCPANEL_KEYWORDSHINT;Používa sa na indikáciu kľúÄových slov. +IPTCPANEL_KEYWORDS;KľúÄové slová +IPTCPANEL_PASTEHINT;PrilepiÅ¥ IPTC nastavenia zo schránky +IPTCPANEL_PROVINCEHINT;Provincia/Å¡tát pôvodu obrázka (Provincia-Å¡tát). +IPTCPANEL_PROVINCE;Provincia/Å¡tát +IPTCPANEL_RESETHINT;ResetovaÅ¥ na predvolené profilom +IPTCPANEL_RESET;ResetovaÅ¥ +IPTCPANEL_SOURCEHINT;Pôvodný vlastník intektuálneho obsahu obrázka (Zdroj). +IPTCPANEL_SOURCE;Zdroj +IPTCPANEL_SUPPCATEGORIES;DodatoÄné kategórie +IPTCPANEL_SUPPCATEGORIESHINT;ÄŽalej upresňuje subjekt obrázka (DodatoÄné kategórie). +IPTCPANEL_TITLEHINT;Krátka referencia pre obrázok (Meno objektu). +IPTCPANEL_TITLE;Názov +IPTCPANEL_TRANSREFERENCEHINT;Kód reprezentujúci miesto pôvodného prenosu (Pôvodná referencia prenosu). +IPTCPANEL_TRANSREFERENCE;Referencia prenosu +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Predvoľby +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;Ako... +MAIN_BUTTON_SAVE;UložiÅ¥ obrázok +MAIN_BUTTON_SENDTOEDITOR;OdoslaÅ¥ do editora +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Súbor už existuje. +MAIN_MSG_CANNOTLOAD;Nemôžem naÄítaÅ¥ obrázok +MAIN_MSG_CANNOTSAVE;Chyba pri ukladaní súboru +MAIN_MSG_CANNOTSTARTEDITOR;Nebolo možné spustiÅ¥ editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Prosím, nastavte správnu cestu v dialógu "Predvoľby". +MAIN_MSG_EXITJOBSINQUEUEINFO;Nespracované obrázky v rade budú pri ukonÄení programu stratené. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Ste si istí, že chcete ukonÄiÅ¥ program? V rade sú nespracované obrázky. +MAIN_MSG_JOBSINQUEUE;Úlohy v rade +MAIN_MSG_QOVERWRITE;Chcete ho prepísaÅ¥? +MAIN_TAB_BASIC;Základné +MAIN_TAB_COLOR;Farba +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Expozícia +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadáta +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Transformácie +MAIN_TOOLTIP_HIDEFP;ZobraziÅ¥/ukázaÅ¥ panel tlaÄidiel (prehliadaÄ adresárov a súborov, shortcut key: F) +MAIN_TOOLTIP_HIDEHP;ZobraziÅ¥/ukázaÅ¥ ľavý panel (vrátane histórie, shortcut key: H) +MAIN_TOOLTIP_INDCLIPPEDH;Indikácia orezania najvyšších svetiel +MAIN_TOOLTIP_INDCLIPPEDS;Indikácia orezania tieňov +MAIN_TOOLTIP_PREFERENCES;NastaviÅ¥ predvoľby +MAIN_TOOLTIP_QINFO;Rýchle informácie o obrázku +MAIN_TOOLTIP_SAVEAS;UložiÅ¥ obrázok do vybraného adresára +MAIN_TOOLTIP_SAVE;UložiÅ¥ obrázok do predvoleného adresára +PARTIALPASTE_BASICGROUP;Základné nastavenia +PARTIALPASTE_CACORRECTION;Korekcia C/A +PARTIALPASTE_COARSETRANS;90° otoÄenie/preklopenie +PARTIALPASTE_COLORBOOST;Zosilnenie farieb +PARTIALPASTE_COLORDENOISE;Farebné odÅ¡umenie +PARTIALPASTE_COLORGROUP;Nastavenia súvisiace s farbou +PARTIALPASTE_COLORMIXER;Mixér farieb +PARTIALPASTE_COLORSHIFT;Farebný posun +PARTIALPASTE_COMPOSITIONGROUP;Nastavenia kompozície +PARTIALPASTE_CROP;Orez +PARTIALPASTE_DIALOGLABEL;Profil spracovania ÄiastoÄného vloženia +PARTIALPASTE_DISTORTION;Korekcia skreslenia +PARTIALPASTE_EXIFCHANGES;Zmeny v EXIF údajochChanges to exif data +PARTIALPASTE_EXPOSURE;Expozícia +PARTIALPASTE_HLRECOVERY;Obnova najvyšších svetiel +PARTIALPASTE_ICMSETTINGS;Nastavenia ICM +PARTIALPASTE_IPTCINFO;IPTC informácie +PARTIALPASTE_LENSGROUP;Nastavenia súvisiace s objektívom +PARTIALPASTE_LUMACURVE;Krivka svietivosti +PARTIALPASTE_LUMADENOISE;Redukcia Å¡umu v oblasti svietivosti +PARTIALPASTE_LUMINANCEGROUP;Nastavenia súvisiace so svietivosÅ¥ou +PARTIALPASTE_METAICMGROUP;Nastavenia metadát/ICM +PARTIALPASTE_RESIZE;ZmeniÅ¥ veľkosÅ¥ +PARTIALPASTE_ROTATION;OtoÄenie +PARTIALPASTE_SHADOWSHIGHLIGHTS;Tiene/Najvyššie svetlá +PARTIALPASTE_SHARPENING;Doostrenie +PARTIALPASTE_VIGNETTING;Korekcia vignetácie +PARTIALPASTE_WHITEBALANCE;Vyváženie bielej +PREFERENCES_APPLNEXTSTARTUP;Aplikovaný pri ÄalÅ¡om spustení +PREFERENCES_BLINKCLIPPED;BlikaÅ¥ orezanými miestami +PREFERENCES_CACHECLEARALL;VyÄistiÅ¥ vÅ¡etko +PREFERENCES_CACHECLEARPROFILES;VyÄistiÅ¥ profily +PREFERENCES_CACHECLEARTHUMBS;VyÄistiÅ¥ zmenÅ¡eniny +PREFERENCES_CACHEFORMAT1;Vlastné (rýchlejÅ¡ie a kvalitnejÅ¡ie) +PREFERENCES_CACHEFORMAT2;JPEG (menÅ¡ia veľkosÅ¥ na disku) +PREFERENCES_CACHEMAXENTRIES;Maximálny poÄet vstupov v cache +PREFERENCES_CACHEOPTS;Možnosti cache +PREFERENCES_CACHESTRAT1;UprednostniÅ¥ rýchlosÅ¥ pred malou spotrebou pamäte +PREFERENCES_CACHESTRAT2;UprednostniÅ¥ malú spotrebu pamäte pred rýchlosÅ¥ou +PREFERENCES_CACHESTRAT;Stratégia použitia cache +PREFERENCES_CACHETHUMBFORM;Formát zmenÅ¡enín pre cache +PREFERENCES_CACHETHUMBHEIGHT;Maximálna výška zmenÅ¡enín +PREFERENCES_CLEARDLG_LINE1;ÄŒistím cache +PREFERENCES_CLEARDLG_LINE2;Môže to pár sekúnd trvaÅ¥. +PREFERENCES_CLEARDLG_TITLE;Prosím, Äakajte. +PREFERENCES_CLIPPINGIND;Indikácia orezu +PREFERENCES_CMETRICINTENT;Kolorimetrický zámer +PREFERENCES_DATEFORMAT;Formát dátumu +PREFERENCES_DATEFORMATHINT;Môžete použiÅ¥ nasledujúce formátovacie reÅ¥azce:\n%y : rok\n%m : mesiac\n%d : deň\n\nNapríklad, slovenský formát je:\n%d.%m.%y +PREFERENCES_DEFAULTLANG;Predvolený jazyk +PREFERENCES_DEFAULTTHEME;Predvolený vzhľad +PREFERENCES_DEMOSAICINGALGO;Demozaikovací algoritmus +PREFERENCES_DIRHOME;Domovský adresár +PREFERENCES_DIRLAST;Posledný navÅ¡tívený adresár +PREFERENCES_DIROTHER;Iný +PREFERENCES_DIRSELECTDLG;VybraÅ¥ adresár s obrázkami pri spustení... +PREFERENCES_DIRSOFTWARE;InÅ¡talaÄný adresár +PREFERENCES_DMETHOD;Metóda +PREFERENCES_EDITORCMDLINE;Iný príkazový riadok +PREFERENCES_EXTERNALEDITOR;Externý editor +PREFERENCES_FALSECOLOR;Kroky potlaÄenia chybných farieb +PREFERENCES_FBROWSEROPTS;Voľby prehliadaÄa súborov +PREFERENCES_FILEFORMAT;Formát súborov +PREFERENCES_FORIMAGE;Pre obrazové súbory +PREFERENCES_FORRAW;Pre RAW súbory +PREFERENCES_GIMPPATH;InÅ¡talaÄný adresár GIMPu +PREFERENCES_GTKTHEME;GTK predvolený +PREFERENCES_HINT;Tip +PREFERENCES_HLTHRESHOLD;Prah pre orezanie najvyšších svetiel +PREFERENCES_ICCDIR;Adresár s ICC profilmy +PREFERENCES_IMPROCPARAMS;Predvolené parametre spracovania obrazu +PREFERENCES_INTENT_ABSOLUTE;Absolútny kolorimetrický +PREFERENCES_INTENT_PERCEPTUAL;Vnímaný +PREFERENCES_INTENT_RELATIVE;Relatívny kolorimetrický +PREFERENCES_INTENT_SATURATION;SýtosÅ¥ +PREFERENCES_LIVETHUMBNAILS;Živé zmenÅ¡eniny (pomalÅ¡ie) +PREFERENCES_MONITORICC;Profil monitora +PREFERENCES_OUTDIRFOLDERHINT;UložiÅ¥ obrázky do vybraného adresára +PREFERENCES_OUTDIRFOLDER;UložiÅ¥ do adresára +PREFERENCES_OUTDIRHINT;Môžete použiÅ¥ nasledujúce formátovacie reÅ¥azce:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nTieto formátovacie reÅ¥azce odkazujú na adresáre a Äasti cesty k raw súboru.\n\nNapríklad, ak bol /home/tom/image/02-09-2006/dsc0012.nefotvorený, význam formátovacích reÅ¥azcov je:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nAk chcete uložiÅ¥ výstupný obraz tam, kde je originál, napíšte:\n%p1/%f\n\nAk chcete uložiÅ¥ výstupný obraz v adresári 'converted' nachádzajúcom sa v adresári s originálom, napíšte:\n%p1/converted/%f\n\nAk chcete uložiÅ¥ výstupný obraz v adresári '/home/tom/converted' pri zachovaní toho istého podadresára s dátumami, napíšte:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;Môžete použiÅ¥ nasledujúce formátovacie reÅ¥azce:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nTieto formátovacie reÅ¥azce odkazujú na adresáre a Äasti cesty k raw súboru.\n\nNapríklad, ak bol /home/tom/image/02-09-2006/dsc0012.nefotvorený, význam formátovacích reÅ¥azcov je:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nAk chcete uložiÅ¥ výstupný obraz tam, kde je originál, napíšte:\n%p1/%f\n\nAk chcete uložiÅ¥ výstupný obraz v adresári 'converted' nachádzajúcom sa v adresári s originálom, napíšte:\n%p1/converted/%f\n\nAk chcete uložiÅ¥ výstupný obraz v adresári '/home/tom/converted' pri zachovaní toho istého podadresára s dátumami, napíšte:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;PoužiÅ¥ Å¡ablónu +PREFERENCES_OUTDIR;Výstupný adresár +PREFERENCES_PARSEDEXTADDHINT;Napíšte príponu a stlaÄte tento gombík pre pripojenie k zoznamu +PREFERENCES_PARSEDEXTADD;PridaÅ¥ príponu +PREFERENCES_PARSEDEXTDELHINT;OdstrániÅ¥ vybranú príponu zo zoznamu +PREFERENCES_PARSEDEXT;Spracúvané prípony +PREFERENCES_PROFILEHANDLING;Zaobchádzanie s profilom spracovania +PREFERENCES_PROFILELOADPR;Priorita naÄítavania profilu +PREFERENCES_PROFILEPRCACHE;Profil v cache +PREFERENCES_PROFILEPRFILE;Profil pri vstupnom súbore +PREFERENCES_PROFILESAVECACHE;UložiÅ¥ parametre spracovania do cache +PREFERENCES_PROFILESAVEINPUT;UložiÅ¥ parametre spracovania k vstupnému súboru +PREFERENCES_PSPATH;InÅ¡talaÄný adresár Adobe Photoshop +PREFERENCES_SELECTICCDIRDLG;VybraÅ¥ adresár s ICC profilmi... +PREFERENCES_SELECTLANG;VybraÅ¥ si jazyk +PREFERENCES_SELECTMONITORPROFDLG;VybraÅ¥ ICC profil monitora... +PREFERENCES_SELECTTHEME;VybraÅ¥ vzhľad +PREFERENCES_SHOWBASICEXIF;ZobrazovaÅ¥ základné EXIF informácie +PREFERENCES_SHOWDATETIME;UkázovaÅ¥ dátum a Äas +PREFERENCES_SHOWONLYRAW;UkazovaÅ¥ len RAW súbory +PREFERENCES_SHTHRESHOLD;Prah pre orezané tiene +PREFERENCES_STARTUPIMDIR;Adresár s obrázkami pri spustení +PREFERENCES_TAB_BROWSER;PrehliadaÄ súborov +PREFERENCES_TAB_COLORMGR;Správa farieb +PREFERENCES_TAB_GENERAL;VÅ¡eobecné +PREFERENCES_TAB_IMPROC;Spracovanie obrazu +PREFERENCES_TAB_OUTPUT;Výstupné možnosti +PREFERENCES_THUMBSIZE;VeľkosÅ¥ zmenÅ¡eniny +PROFILEPANEL_FILEDLGFILTERANY;VÅ¡etky súbory +PROFILEPANEL_FILEDLGFILTERPP;Profily spracovania +PROFILEPANEL_LABEL;Profily spracovania +PROFILEPANEL_LOADDLGLABEL;NaÄítaÅ¥ parametre spracovania... +PROFILEPANEL_PCUSTOM;Vlastné +PROFILEPANEL_PFILE;Zo súboru +PROFILEPANEL_PLASTPHOTO;Posledná fotka +PROFILEPANEL_PLASTSAVED;Posledné uložené +PROFILEPANEL_PROFILE;Profil +PROFILEPANEL_SAVEDLGLABEL;UložiÅ¥ parametre spracovania... +PROFILEPANEL_TOOLTIPCOPY;KopírovaÅ¥ súÄasný profil do schránky +PROFILEPANEL_TOOLTIPLOAD;NaÄítaÅ¥ profil zo súboru +PROFILEPANEL_TOOLTIPPASTE;VložiÅ¥ profil zo schránky +PROFILEPANEL_TOOLTIPSAVE;UložiÅ¥ súÄasný profil +PROGRESSBAR_DECODING;Dekódujem raw súbor... +PROGRESSBAR_DEMOSAICING;Demozaikujem... +PROGRESSBAR_LOADING;NaÄítavam obrázok... +PROGRESSBAR_LOADJPEG;Ukladám JPEG súbor... +PROGRESSBAR_LOADPNG;Ukladám PNG súbor... +PROGRESSBAR_LOADTIFF;Ukladám TIFF súbor... +PROGRESSBAR_PROCESSING;Spracúvam obrázok... +PROGRESSBAR_READY;Pripravený. +PROGRESSBAR_SAVEJPEG;Ukladám JPEG súbor... +PROGRESSBAR_SAVEPNG;Ukladám PNG súbor... +PROGRESSBAR_SAVETIFF;Ukladám TIFF súbor... +PROGRESSDLG_LOADING;NaÄítava sa súbor... +PROGRESSDLG_PROCESSING;Spracúva sa obrázok... +PROGRESSDLG_SAVING;Ukladá sa súbor... +QINFO_FOCALLENGTH;Ohnisková vzdialenosÅ¥ +QINFO_ISO;ISO +QINFO_LENS;Objektív +QINFO_NOEXIF;Exif údaje sú nedostupné. +SAVEDLG_FILEFORMAT;Formát súboru +SAVEDLG_JPEGQUAL;JPEG Kvalita +SAVEDLG_JPGFILTER;JPEG súbory +SAVEDLG_PNGCOMPR;PNG Kompresia +SAVEDLG_PNGFILTER;PNG súbory +SAVEDLG_PUTTOQUEUEHEAD;Presunúť na Äelo radu na spracovanie +SAVEDLG_PUTTOQUEUETAIL;Presunúť na koniec radu na spracovanie +SAVEDLG_PUTTOQUEUE;VložiÅ¥ do radu na spracovanie +SAVEDLG_SAVEIMMEDIATELY;UložiÅ¥ okamžite +SAVEDLG_SAVESPP;UložiÅ¥ parametre spracovania s obrázkom +SAVEDLG_TIFFFILTER;TIFF súbory +TOOLBAR_TOOLTIP_CROP;Orezanie výberu (shortcut key: C) +TOOLBAR_TOOLTIP_HAND;Nástroj ruka (shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Výber rovnej Äiary (shortcut key: S) +TOOLBAR_TOOLTIP_WB;Bodové vyváženie bielej (shortcut key: W) +TP_CACORRECTION_BLUE;Modrá +TP_CACORRECTION_LABEL;Korekcia chromatickej aberácie +TP_CACORRECTION_RED;ÄŒervená +TP_CHMIXER_BLUE;Modrá +TP_CHMIXER_GREEN;Zelená +TP_CHMIXER_LABEL;Mixér kanálov +TP_CHMIXER_RED;ÄŒervená +TP_COARSETRAF_DEGREE;stupeň: +TP_COARSETRAF_TOOLTIP_HFLIP;PrevrátiÅ¥ horizontálne +TP_COARSETRAF_TOOLTIP_ROTLEFT;OtoÄiÅ¥ doľava +TP_COARSETRAF_TOOLTIP_ROTRIGHT;OtoÄiÅ¥ doprava +TP_COARSETRAF_TOOLTIP_VFLIP;PrevrátiÅ¥ vertikálne +TP_COLORBOOST_ACHANNEL;kanál "a" +TP_COLORBOOST_AMOUNT;Množstvo +TP_COLORBOOST_AVOIDCOLORCLIP;Vyhnúť sa orezaniu farieb +TP_COLORBOOST_BCHANNEL;kanál "b" +TP_COLORBOOST_CHAB;a & b +TP_COLORBOOST_CHANNEL;Kanál +TP_COLORBOOST_CHSEPARATE;oddelené +TP_COLORBOOST_ENABLESATLIMITER;PovoliÅ¥ obmedzovaÅ¥ sýtosti +TP_COLORBOOST_LABEL;Zosilnenie farieb +TP_COLORBOOST_SATLIMIT;Hranica sýtosti +TP_COLORDENOISE_EDGESENSITIVE;Citlivá na okraje +TP_COLORDENOISE_EDGETOLERANCE;Tolerancia okrajov +TP_COLORDENOISE_LABEL;Redukcia farebného Å¡umu +TP_COLORDENOISE_RADIUS;Polomer +TP_COLORSHIFT_BLUEYELLOW;Modrá-žltá +TP_COLORSHIFT_GREENMAGENTA;Zelená-fialová +TP_COLORSHIFT_LABEL;Farebný posun +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Pevný pomer: +TP_CROP_GTDIAGONALS;Pravidlo diagonál +TP_CROP_GTHARMMEANS1;Harmonický priemer 1 +TP_CROP_GTHARMMEANS2;Harmonický priemer 2 +TP_CROP_GTHARMMEANS3;Harmonický priemer 3 +TP_CROP_GTHARMMEANS4;Harmonický priemer 4 +TP_CROP_GTNONE;Žiadne +TP_CROP_GTRULETHIRDS;Pravidlo tretín +TP_CROP_GUIDETYPE;Type vodidiel: +TP_CROP_H;V +TP_CROP_LABEL;Orezanie +TP_CROP_SELECTCROP; Vyberte Orez +TP_CROP_W;Å  +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Množstvo +TP_DISTORTION_LABEL;Zakrivenie +TP_EXPOSURE_AUTOLEVELS;Auto úrovne +TP_EXPOSURE_BLACKLEVEL;ÄŒierna +TP_EXPOSURE_BRIGHTNESS;Jas +TP_EXPOSURE_CLIP;OrezaÅ¥ +TP_EXPOSURE_COMPRHIGHLIGHTS;Kompresia najvyšších svetiel +TP_EXPOSURE_COMPRSHADOWS;Kompresia tieňov +TP_EXPOSURE_CONTRAST;Kontrast +TP_EXPOSURE_CURVEEDITOR;Krivka tónov +TP_EXPOSURE_EXPCOMP;Kompenzácia expozície +TP_EXPOSURE_LABEL;Expozícia +TP_HLREC_CIELAB;CIELab Blending +TP_HLREC_COLOR;Šírenie farieb +TP_HLREC_LABEL;Obnova najvyšších svetiel +TP_HLREC_LUMINANCE;Obnova svietivosti +TP_HLREC_METHOD;Metóda: +TP_ICM_FILEDLGFILTERANY;VÅ¡etky súbory +TP_ICM_FILEDLGFILTERICM;Súbory ICC profilu +TP_ICM_GAMMABEFOREINPUT;Profil aplikuje Gamu +TP_ICM_INPUTCAMERA;Predvolený aparátu +TP_ICM_INPUTCUSTOM;Vlastný +TP_ICM_INPUTDLGLABEL;VybraÅ¥ vstupný ICC profil... +TP_ICM_INPUTEMBEDDED;PoužiÅ¥ vstavaný, ak je to možné +TP_ICM_INPUTPROFILE;Vstupný profil +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Bez správy farieb: sRGB výstup +TP_ICM_OUTPUTDLGLABEL;VybraÅ¥ výstupný ICC profil... +TP_ICM_OUTPUTPROFILE;Výstupný profil +TP_ICM_SAVEREFERENCE;UložiÅ¥ referenÄný obrázok pre tvorbu profilu +TP_ICM_WORKINGPROFILE;Pracovný profil +TP_LUMACURVE_BLACKLEVEL;ÄŒierna +TP_LUMACURVE_BRIGHTNESS;Jas +TP_LUMACURVE_COMPRHIGHLIGHTS;Kompresia najvyšších svetiel +TP_LUMACURVE_COMPRSHADOWS;Kompresia tieňov +TP_LUMACURVE_CONTRAST;Kontrast +TP_LUMACURVE_CURVEEDITOR;Krivka svietivosti +TP_LUMACURVE_LABEL;Krivka svietivosti +TP_LUMADENOISE_EDGETOLERANCE;Tolerancia okrajov +TP_LUMADENOISE_LABEL;Redukcia Å¡umu v oblasti svietivosti +TP_LUMADENOISE_RADIUS;Polomer +TP_RESIZE_BICUBIC;Bikubická +TP_RESIZE_BICUBICSF;Bikubická (MäkÅ¡ia) +TP_RESIZE_BICUBICSH;Bikubická (OstrejÅ¡ia) +TP_RESIZE_BILINEAR;Bilineárna +TP_RESIZE_FULLSIZE;Celá veľkosÅ¥ obrázka: +TP_RESIZE_H;V: +TP_RESIZE_LABEL;ZmeniÅ¥ veľkosÅ¥ +TP_RESIZE_METHOD;Metóda: +TP_RESIZE_NEAREST;Najbližšie +TP_RESIZE_SCALE;Rozmer +TP_RESIZE_W;Å : +TP_ROTATE_AUTOCROP;Automatické orezanie +TP_ROTATE_DEGREE;Stupeň +TP_ROTATE_FILL;Výplň +TP_ROTATE_LABEL;OtoÄiÅ¥ +TP_ROTATE_SELECTLINE;VybraÅ¥ rovnú Äiaru +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Najvyššie svetlá +TP_SHADOWSHLIGHTS_HLTONALW;Tonálna šírka +TP_SHADOWSHLIGHTS_LABEL;Tiene/Najvyššie svetlá +TP_SHADOWSHLIGHTS_LOCALCONTR;Miestny kontrast +TP_SHADOWSHLIGHTS_RADIUS;Polomer +TP_SHADOWSHLIGHTS_SHADOWS;Tiene +TP_SHADOWSHLIGHTS_SHTONALW;Tonálna šírka +TP_SHARPENING_AMOUNT;Množstvo +TP_SHARPENING_EDRADIUS;Polomer +TP_SHARPENING_EDTOLERANCE;Tolerancia okrajov +TP_SHARPENING_HALOCONTROL;Kontrola svätožiary +TP_SHARPENING_HCAMOUNT;Množstvo +TP_SHARPENING_LABEL;Doostrenie +TP_SHARPENING_METHOD;Metóda +TP_SHARPENING_ONLYEDGES;DoostriÅ¥ len okraje +TP_SHARPENING_RADIUS;Polomer +TP_SHARPENING_RLD_AMOUNT;Množstvo +TP_SHARPENING_RLD_DAMPING;Tlmenie +TP_SHARPENING_RLD_ITERATIONS;Iterácie +TP_SHARPENING_RLD;RL Dekonvolúcia +TP_SHARPENING_THRESHOLD;Prah +TP_SHARPENING_USM;Unsharp Mask +TP_VIGNETTING_AMOUNT;Množstvo +TP_VIGNETTING_LABEL;Korekcia vignetácie +TP_VIGNETTING_RADIUS;Polomer +TP_WBALANCE_AUTO;Automatické +TP_WBALANCE_CAMERA;Fotoaparát +TP_WBALANCE_CUSTOM;Vlastné +TP_WBALANCE_GREEN;Nádych +TP_WBALANCE_LABEL;Vyváženie bielej +TP_WBALANCE_METHOD;Metóda +TP_WBALANCE_SIZE;VeľkosÅ¥: +TP_WBALANCE_SPOTWB;Bodové VB +TP_WBALANCE_TEMPERATURE;Teplota +ZOOMBAR_DETAIL;Detail +ZOOMBAR_HUGE;Obrovský +ZOOMBAR_LARGE;Veľký +ZOOMBAR_NORMAL;Normálny +ZOOMBAR_PREVIEW;Náhľad +ZOOMBAR_SCALE;Rozmer +ZOOMBAR_SMALL;Malý + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Suomi b/rtdata/languages/Suomi new file mode 100644 index 000000000..cac51e327 --- /dev/null +++ b/rtdata/languages/Suomi @@ -0,0 +1,703 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# +# Finnish language file for Raw Therapee v2.4RC2 (www.rawtherapee.com) +# Compiled by T.Kauppinen 3.5.2009 +ADJUSTER_RESET_TO_DEFAULT;Palauta oletusasetukset +CURVEEDITOR_FILEDLGFILTERANY;Kaikki tiedostot +CURVEEDITOR_FILEDLGFILTERCURVE;Käyrätiedostot +CURVEEDITOR_LINEAR;Suora +CURVEEDITOR_LOADDLGLABEL;Lataa käyrä... +CURVEEDITOR_SAVEDLGLABEL;Tallenna käyrä... +CURVEEDITOR_TOOLTIPLINEAR;Palauta suoraksi +CURVEEDITOR_TOOLTIPLOAD;Lataa käyrä tiedostosta +CURVEEDITOR_TOOLTIPSAVE;Tallenna käyrä +EXIFFILTER_APERTURE;Aukko +EXIFFILTER_CAMERA;Kamera +EXIFFILTER_DIALOGLABEL;EXIF suodatus +EXIFFILTER_FOCALLEN;Polttoväli +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objektiivi +EXIFFILTER_SHUTTER;Suljinaika +EXIFPANEL_ADDEDITHINT;Lisää uusi EXIF-tieto tai muokkaa olemassaolevaa +EXIFPANEL_ADDEDIT;Lisää/Muokkaa +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Uusi arvo +EXIFPANEL_ADDTAGDLG_SELECTTAG;Valitse +EXIFPANEL_ADDTAGDLG_TITLE;Lisää/Muokkaa +EXIFPANEL_KEEPHINT;Pidä valitut tallennettaessa +EXIFPANEL_KEEP;Pidä +EXIFPANEL_REMOVEHINT;Poista valitut tallennettaessa +EXIFPANEL_REMOVE;Poista +EXIFPANEL_RESETALLHINT;Palauta kaikki alkuperäisiksi +EXIFPANEL_RESETALL;Palauta kaikki +EXIFPANEL_RESETHINT;Palauta valitut alkuperäisiksi +EXIFPANEL_RESET;Palauta +EXIFPANEL_SUBDIRECTORY;Alihakemisto +FILEBROWSER_APPLYPROFILE;Käytä profiilia +FILEBROWSER_ARRANGEMENTHINT;Vaihda esikatselukuvien ryhmittely vaaka/pysty suunnassa +FILEBROWSER_CLEARPROFILE;Tyhjennä profiili +FILEBROWSER_COPYPROFILE;Kopioi profiili +FILEBROWSER_DELETEDLGLABEL;Tiedostojen poisto +FILEBROWSER_DELETEDLGMSG;Haluatko varmasti poistaa valitut %1 tiedostoa? +FILEBROWSER_EMPTYTRASHHINT;Poistaa pysyvästi tiedostot roskakorista +FILEBROWSER_EMPTYTRASH;Tyhjennä roskakori +FILEBROWSER_EXIFFILTERAPPLYHINT;EXIF suodatus päälle/pois +FILEBROWSER_EXIFFILTERAPPLY;Päällä +FILEBROWSER_EXIFFILTERLABEL;EXIF suodatus +FILEBROWSER_EXIFFILTERSETTINGS;Asetukset +FILEBROWSER_EXIFFILTERSETTINGSHINT;Määritä exit suodatuksen asetukset +FILEBROWSER_PARTIALPASTEPROFILE;Liitä valiten.. +FILEBROWSER_PASTEPROFILE;Liitä profiili +FILEBROWSER_POPUPCANCELJOB;Peruuta työ +FILEBROWSER_POPUPMOVEEND;Siirrä jonon viimeiseksi +FILEBROWSER_POPUPMOVEHEAD;Siirrä jonon ensimmäiseksi +FILEBROWSER_POPUPOPEN;Avaa +FILEBROWSER_POPUPPROCESS;Laita käsittelyjonoon +FILEBROWSER_POPUPRANK1;1 tähti +FILEBROWSER_POPUPRANK2;2 tähteä +FILEBROWSER_POPUPRANK3;3 tähteä +FILEBROWSER_POPUPRANK4;4 tähteä +FILEBROWSER_POPUPRANK5;5 tähteä +FILEBROWSER_POPUPREMOVE;Poista kokonaan +FILEBROWSER_POPUPRENAME;Nimeä uudelleen.. +FILEBROWSER_POPUPSELECTALL;Valitse kaikki +FILEBROWSER_POPUPTRASH;Siirrä roskakoriin +FILEBROWSER_POPUPUNRANK;Poista arvostelu +FILEBROWSER_POPUPUNTRASH;Pelasta roskakorista +FILEBROWSER_PROCESSINGSETTINGS;Asetukset +FILEBROWSER_PROCESSINGSETTINGSHINT;Tallennusasetukset +FILEBROWSER_RENAMEDLGLABEL;Nimeä uudelleen +FILEBROWSER_RENAMEDLGMSG;Tiedoston "%1" uusi nimi: +FILEBROWSER_SHOWDIRHINT;Näytä hakemiston kaikki kuvat +FILEBROWSER_SHOWQUEUEHINT;Näytä käsittelyjono +FILEBROWSER_SHOWRANK1HINT;Näytä 1 tähden kuvat +FILEBROWSER_SHOWRANK2HINT;Näytä 2 tähden kuvat +FILEBROWSER_SHOWRANK3HINT;Näytä 3 tähden kuvat +FILEBROWSER_SHOWRANK4HINT;Näytä 4 tähden kuvat +FILEBROWSER_SHOWRANK5HINT;Näytä 5 tähden kuvat +FILEBROWSER_SHOWTRASHHINT;Näytä roskakorin sisältö +FILEBROWSER_SHOWUNRANKHINT;Näytä arvostelemattomat kuvat +FILEBROWSER_STARTPROCESSING;Aloita käsittely +FILEBROWSER_STARTPROCESSINGHINT;Aloita jonossa olevien kuvien käsittely +FILEBROWSER_STOPPROCESSINGHINT;Lopeta jonossa olevien kuvien käsittely +FILEBROWSER_STOPPROCESSING;Lopeta käsittely +FILEBROWSER_THUMBSIZE;Esikatselun koko +FILEBROWSER_ZOOMINHINT;Kasvata esikatselukuvien kokoa +FILEBROWSER_ZOOMOUTHINT;Pienennä esikatselukuvien kokoa +GENERAL_ABOUT;Tietoja +GENERAL_CANCEL;Peruuta +GENERAL_DISABLED;Pois +GENERAL_DISABLE;Pois +GENERAL_ENABLED;Päällä +GENERAL_ENABLE;Päälle +GENERAL_LANDSCAPE;Vaaka +GENERAL_LOAD;Lataa +GENERAL_NA;- +GENERAL_NO;Ei +GENERAL_OK;OK +GENERAL_PORTRAIT;Pysty +GENERAL_SAVE;Tallenna +GENERAL_YES;Kyllä +HISTOGRAM_LABEL;Histogrammi +HISTOGRAM_TOOLTIP_B;Näytä/piilota SININEN +HISTOGRAM_TOOLTIP_G;Näytä/piilota VIHREÄ +HISTOGRAM_TOOLTIP_L;Näytä/piilota CIELAB luminanssi +HISTOGRAM_TOOLTIP_R;Näytä/piilota PUNAINEN +HISTORY_CHANGED;Muutettu +HISTORY_CUSTOMCURVE;Oma käyrä +HISTORY_DELSNAPSHOT;Poista pikakuva +HISTORY_FROMCLIPBOARD;Leikepöydältä +HISTORY_LABEL;Historia +HISTORY_MSG_10;Valotuksen säätö\nTummien alueiden vaimennus +HISTORY_MSG_11;Valotuksen säätö\nSävykäyrä +HISTORY_MSG_12;Valotuksen säätö\nAutomaattinen +HISTORY_MSG_13;Valotuksen säätö\nAutomaattisen valotuksen raja +HISTORY_MSG_14;Luminanssi\nKirkkaus +HISTORY_MSG_15;Luminanssi\nKontrasti +HISTORY_MSG_16;Luminanssi\nTummuus +HISTORY_MSG_17;Luminanssi\nVaaleiden alueiden vaimennus +HISTORY_MSG_18;Luminanssi\nTummien alueiden vaimennus +HISTORY_MSG_19;Luminanssi\nKäyrä +HISTORY_MSG_1;Kuva ladattu +HISTORY_MSG_20;Terävöinti +HISTORY_MSG_21;Terävöinti\nEpäterävä maski: Säde +HISTORY_MSG_22;Terävöinti\nEpäterävä maski: Määrä +HISTORY_MSG_23;Terävöinti\nEpäterävä maski: Kynnys +HISTORY_MSG_24;Terävöinti\nEpäterävä maski: Vain reunat +HISTORY_MSG_25;Terävöinti\nEpäterävä maski: Reunatunnistuksen säde +HISTORY_MSG_26;Terävöinti\nEpäterävä maski: Reunatunnistuksen herkkyys +HISTORY_MSG_27;Terävöinti\nEpäterävä maski: Halo-ilmiön esto +HISTORY_MSG_28;Terävöinti\nEpäterävä maski: Halo-ilmiön eston määrä +HISTORY_MSG_29;Terävöinti\nMenetelmä +HISTORY_MSG_2;Profiili ladattu +HISTORY_MSG_30;Terävöinti\nDekonvoluutio: Säde +HISTORY_MSG_31;Terävöinti\nDekonvoluutio: Määrä +HISTORY_MSG_32;Terävöinti\nDekonvoluutio: Vaimennus +HISTORY_MSG_33;Terävöinti\nDekonvoluutio: Iteraatiot +HISTORY_MSG_34;Värikylläisyys\nVältä leikkautuminen +HISTORY_MSG_35;Värikylläisyys\nEstä kyllästyminen +HISTORY_MSG_36;Värikylläisyys\nKyllästymisraja +HISTORY_MSG_37;Värikylläisyys +HISTORY_MSG_38;Valkotasapaino\nMenetelmä +HISTORY_MSG_39;Valkotasapaino\nLämpötila [K] +HISTORY_MSG_3;Profiili vaihdettu +HISTORY_MSG_40;Valkotasapaino\nValkoisen sävy +HISTORY_MSG_41;Värisävy\nvihreä-punainen +HISTORY_MSG_42;Värisävy\nsininen-keltainen +HISTORY_MSG_43;Luminanssin kohinanvaimennus +HISTORY_MSG_44;Luminanssin kohinanvaimennus\nSäde +HISTORY_MSG_45;Luminanssin kohinanvaimennus\nReunan tunnistusherkkyys +HISTORY_MSG_46;Värin kohinanvaimennus +HISTORY_MSG_47;Värin kohinanvaimennus\nSäde +HISTORY_MSG_48;Värin kohinanvaimennus\nReunan tunnistusherkkyys +HISTORY_MSG_49;Värin kohinanvaimennus\nReunaherkkä +HISTORY_MSG_4;Historian selaus +HISTORY_MSG_50;Tummat/vaaleat alueet +HISTORY_MSG_51;Tummat/vaaleat alueet\nVaaleiden alueiden vaimennus +HISTORY_MSG_52;Tummat/vaaleat alueet\nTummien alueiden vaimennus +HISTORY_MSG_53;Tummat/vaaleat alueet\nVaalean sävyalueen laajuus +HISTORY_MSG_54;Tummat/vaaleat alueet\nTumman sävyalueen laajuus +HISTORY_MSG_55;Tummat/vaaleat alueet\nPaikallinen kontrasti +HISTORY_MSG_56;Tummat/vaaleat alueet\nSäde +HISTORY_MSG_57;Kääntö +HISTORY_MSG_58;Peilaa vaakasuunnassa +HISTORY_MSG_59;Peilaa pystysuunnassa +HISTORY_MSG_5;Valotus\nKirkkaus +HISTORY_MSG_60;Oikaisu +HISTORY_MSG_61;Kääntö +HISTORY_MSG_62;Linssivääristymän korjaus +HISTORY_MSG_63;Pikakuva valittu +HISTORY_MSG_64;Rajaus +HISTORY_MSG_65;Värivääristymän korjaus +HISTORY_MSG_66;Huippuvaloalueiden palautus +HISTORY_MSG_67;Huippuvaloalueiden palautus\nMäärä +HISTORY_MSG_68;Huippuvaloalueiden palautus\nMenetelmä +HISTORY_MSG_69;Työväriprofiili +HISTORY_MSG_6;Valotus\nKontrasti +HISTORY_MSG_70;Tulosväriprofiili +HISTORY_MSG_71;Lähdeväriprofiili +HISTORY_MSG_72;Vinjetoinnin korjaus +HISTORY_MSG_73;Kanavat +HISTORY_MSG_74;Koko +HISTORY_MSG_75;Koko\nMenetelmä +HISTORY_MSG_76;EXIF-tiedot +HISTORY_MSG_77;IPTC-tiedot +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;Valotus\nTummuus +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;Valotus\nKompensointi +HISTORY_MSG_9;Valotus\nVaaleiden alueiden vaimennus +HISTORY_NEWSNAPSHOTAS;... +HISTORY_NEWSNAPSHOT;Uusi pikakuva +HISTORY_NEWSSDIALOGLABEL;Pikakuvan nimi: +HISTORY_NEWSSDIALOGTITLE;Lisää uusi pikakuva +HISTORY_SETTO;Aseta +HISTORY_SNAPSHOT;Pikakuva +HISTORY_SNAPSHOTS;Pikakuvat +ICMPANEL_FILEDLGFILTERANY;kaikki tiedostot +ICMPANEL_FILEDLGFILTERICM;ICC-profiilitiedostot +ICMPANEL_GAMMABEFOREINPUT;Käytä profiilin gammaa +ICMPANEL_INPUTCAMERA;Kameran oletus +ICMPANEL_INPUTCUSTOM;Oma +ICMPANEL_INPUTDLGLABEL;Valitse lähteen ICC-profiili... +ICMPANEL_INPUTEMBEDDED;Käytä kuvan omaa, jos mahdollista +ICMPANEL_INPUTPROFILE;Lähdeväriprofiili +ICMPANEL_NOICM;Ei ICM-profiilia: sRGB +ICMPANEL_OUTPUTDLGLABEL;Valitse tuloksen ICC-profiili... +ICMPANEL_OUTPUTPROFILE;Tulosväriprofiili +ICMPANEL_SAVEREFERENCE;Tallenna mallikuva\nprofilointia varten +ICMPANEL_WORKINGPROFILE;Työväriprofiili +IMAGEAREA_DETAILVIEW; +IPTCPANEL_AUTHORHINT;(Author) Kuvaajan nimi. +IPTCPANEL_AUTHOR;Kuvaaja +IPTCPANEL_AUTHORSPOSITIONHINT;(Author position) Kuvaajan titteli. +IPTCPANEL_AUTHORSPOSITION;Kuvaajan titteli +IPTCPANEL_CAPTION;Aihe +IPTCPANEL_CAPTIONHINT;(Caption) Kuvaus kohteesta. +IPTCPANEL_CAPTIONWRITERHINT;(Caption Writer) Kuvauksen kirjoittajan nimi. +IPTCPANEL_CAPTIONWRITER;Kuvauksen kirjoittaja +IPTCPANEL_CATEGORY;Aiheryhmä +IPTCPANEL_CATEGORYHINT;(Category) Aiheryhmän 3-kirjaiminen koodi. +IPTCPANEL_CITYHINT;(City) Kaupunki jossa kuva on otettu. +IPTCPANEL_CITY;Kaupunki +IPTCPANEL_COPYHINT;Kopioi IPTC tiedot leikepöydälle +IPTCPANEL_COPYRIGHTHINT;(Copyright) Tekijänoikeustiedot. +IPTCPANEL_COPYRIGHT;Tekijänoikeudet +IPTCPANEL_COUNTRYHINT;(Country) Maa jossa kuva on otettu. +IPTCPANEL_COUNTRY;Maa +IPTCPANEL_CREDITHINT;(Credit) Välittäjän tiedot. +IPTCPANEL_CREDIT;Välittäjä +IPTCPANEL_DATECREATEDHINT;(Date Created) Päivämäärä jolloin kuva on otettu. +IPTCPANEL_DATECREATED;Päivämäärä +IPTCPANEL_EMBEDDEDHINT;Palauta kuvan IPTC tiedot +IPTCPANEL_EMBEDDED;Kuvan oma +IPTCPANEL_HEADLINEHINT;(Headline) Julkaistava otsikko. +IPTCPANEL_HEADLINE;Julkaistava otsikko +IPTCPANEL_INSTRUCTIONSHINT;(Instructions) Ohjeet ja rajoitukset. +IPTCPANEL_INSTRUCTIONS;Ohjeet +IPTCPANEL_KEYWORDS;Avainsanat +IPTCPANEL_KEYWORDSHINT;(Keywords) Kohdetta kuvaavia avainsanoja. +IPTCPANEL_PASTEHINT;Liitä IPTC tiedot leikepöydältä +IPTCPANEL_PROVINCEHINT;(Province) Maakunta jossa kuva on otettu. +IPTCPANEL_PROVINCE;Maakunta +IPTCPANEL_RESETHINT;Palauta profiilin oletukseen +IPTCPANEL_RESET;Palauta +IPTCPANEL_SOURCEHINT;(Source) Kuvan lähde. +IPTCPANEL_SOURCE;Lähde +IPTCPANEL_SUPPCATEGORIESHINT;(Supplemental Categories) Tarkempi aiheryhmä. +IPTCPANEL_SUPPCATEGORIES;Tarkempi aiheryhmä +IPTCPANEL_TITLEHINT;(Title) Otsikko. +IPTCPANEL_TITLE;Otsikko +IPTCPANEL_TRANSREFERENCE;Alkuperäviite +IPTCPANEL_TRANSREFERENCEHINT;(Original Transmission Reference) Alkuperäviite. +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Asetukset +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;... +MAIN_BUTTON_SAVE;Tallenna kuva +MAIN_BUTTON_SENDTOEDITOR;Avaa ulkoisessa ohjelmassa +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Tiedosto on jo olemassa. +MAIN_MSG_CANNOTLOAD;Kuvaa ei voi avata +MAIN_MSG_CANNOTSAVE;Tiedoston tallennusongelma +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Tarkista ohjelman polku asetuksissa! +MAIN_MSG_CANNOTSTARTEDITOR;Ulkoista ohjelmaa ei voi käynnistää +MAIN_MSG_EXITJOBSINQUEUEINFO;Käsittelemättömät kuvat jonossa menetetään poistuttaessa. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Haluatko varmasti lopettaa? Jonossa on käsittelemättömiä kuvia. +MAIN_MSG_JOBSINQUEUE;työtä jonossa +MAIN_MSG_QOVERWRITE;Haluatko tallentaa päälle? +MAIN_TAB_BASIC;Säädöt +MAIN_TAB_COLOR;Väri +MAIN_TAB_DETAIL;Yksityiskohdat +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;EXIF +MAIN_TAB_EXPOSURE;Valotus +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metatiedot +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Muunnokset +MAIN_TOOLTIP_HIDEFP;Näytä/piilota alaikkuna (pikanäppäin: F) +MAIN_TOOLTIP_HIDEHP;Näytä/piilota vasen ikkuna (pikanäppäin: H) +MAIN_TOOLTIP_INDCLIPPEDH;Näytä leikkautuvat\nvaaleat alueet +MAIN_TOOLTIP_INDCLIPPEDS;Näytä leikkautuvat\ntummat alueet +MAIN_TOOLTIP_PREFERENCES;Muuta asetuksia +MAIN_TOOLTIP_QINFO;Kuvan tiedot +MAIN_TOOLTIP_SAVEAS;Tallenna kuva\nvalittuun hakemistoon +MAIN_TOOLTIP_SAVE;Tallenna kuva\noletushakemistoon +PARTIALPASTE_BASICGROUP;Perusasetukset +PARTIALPASTE_CACORRECTION;Väripoikkeaman korjaus +PARTIALPASTE_COARSETRANS;Vasen/oikea kääntö ja peilaus +PARTIALPASTE_COLORBOOST;Värikylläisyys +PARTIALPASTE_COLORDENOISE;Värin kohinanvaimennus +PARTIALPASTE_COLORGROUP;Väriasetukset +PARTIALPASTE_COLORMIXER;Kanavat +PARTIALPASTE_COLORSHIFT;Värisävy +PARTIALPASTE_COMPOSITIONGROUP;Muunnokset +PARTIALPASTE_CROP;Rajaus +PARTIALPASTE_DIALOGLABEL;Liitä valiten.. +PARTIALPASTE_DISTORTION;Linssivääristymän korjaus +PARTIALPASTE_EXIFCHANGES;EXIF-tiedot +PARTIALPASTE_EXPOSURE;Valotus +PARTIALPASTE_HLRECOVERY;Huippuvaloalueiden palautus +PARTIALPASTE_ICMSETTINGS;ICM-profiili +PARTIALPASTE_IPTCINFO;IPTC-tiedot +PARTIALPASTE_LENSGROUP;Objektiiviin liittyvät asetukset +PARTIALPASTE_LUMACURVE;Luminanssikäyrä +PARTIALPASTE_LUMADENOISE;Luminanssin kohinanpoisto +PARTIALPASTE_LUMINANCEGROUP;Lisäasetukset +PARTIALPASTE_METAICMGROUP;Metatiedot ja ICM-profiili +PARTIALPASTE_RESIZE;Koko +PARTIALPASTE_ROTATION;Oikaisu +PARTIALPASTE_SHADOWSHIGHLIGHTS;Tummat/vaaleat alueet +PARTIALPASTE_SHARPENING;Terävöinti +PARTIALPASTE_VIGNETTING;Vinjetoinnin korjaus +PARTIALPASTE_WHITEBALANCE;Valkotasapaino +PREFERENCES_APPLNEXTSTARTUP;käytössä käynnistyksen jälkeen +PREFERENCES_BLINKCLIPPED;Välkytä leikkautuvia alueita +PREFERENCES_CACHECLEARALL;Tyhjennä kaikki +PREFERENCES_CACHECLEARPROFILES;Tyhjennä profiilit +PREFERENCES_CACHECLEARTHUMBS;Tyhjennä esikatselukuvat +PREFERENCES_CACHEFORMAT1;RawTherapee (nopeampi ja parempilaatuinen) +PREFERENCES_CACHEFORMAT2;JPEG (pienempi koko) +PREFERENCES_CACHEMAXENTRIES;Välimuistin koko +PREFERENCES_CACHEOPTS;Välimuistin asetukset +PREFERENCES_CACHESTRAT1;Suosi nopeutta muistin kustannuksella +PREFERENCES_CACHESTRAT2;Suosi muistia nopeuden kustannuksella +PREFERENCES_CACHESTRAT;Välimuistin optimointitapa +PREFERENCES_CACHETHUMBFORM;Välimuistin esikatselukuvien muoto +PREFERENCES_CACHETHUMBHEIGHT;Suurin esikatselukuvan korkeus +PREFERENCES_CLEARDLG_LINE1;Välimuistiä tyhjennetään +PREFERENCES_CLEARDLG_LINE2;Tämä voi kestää joitain sekunteja. +PREFERENCES_CLEARDLG_TITLE;Odota. +PREFERENCES_CLIPPINGIND;Leikkautuminen +PREFERENCES_CMETRICINTENT;Näköistystapa +PREFERENCES_DATEFORMATHINT;Voit käyttää seuraavia komentoja:\n%y : vuosi\n%m : kuukausi\n%d : päivä\n\nEsimerkiksi, pp.kk.vvvv:\n%d.%m.%y +PREFERENCES_DATEFORMAT;Päivämäärän muoto +PREFERENCES_DEFAULTLANG;Oletuskieli +PREFERENCES_DEFAULTTHEME;Oletusteema +PREFERENCES_DEMOSAICINGALGO;Väri-interpolointi +PREFERENCES_DIRHOME;Kotihakemisto +PREFERENCES_DIRLAST;Viimeksi käytetty hakemisto +PREFERENCES_DIROTHER;Muu +PREFERENCES_DIRSELECTDLG;Valitse kuvahakemisto käynnistettäessä... +PREFERENCES_DIRSOFTWARE;Asennushakemisto +PREFERENCES_DMETHOD;Menetelmä +PREFERENCES_EDITORCMDLINE;Muu komentorivi +PREFERENCES_EXTERNALEDITOR;Ulkoinen ohjelma +PREFERENCES_FALSECOLOR;Värivääristymien eston määrä +PREFERENCES_FBROWSEROPTS;Näytettävät tiedot +PREFERENCES_FILEFORMAT;Tallennuksen asetukset +PREFERENCES_FORIMAGE;Kuvatiedostoille +PREFERENCES_FORRAW;RAW-tiedostoille +PREFERENCES_GIMPPATH;GIMP:n asennushakemisto +PREFERENCES_GTKTHEME;GTK oletus +PREFERENCES_HINT;Neuvo +PREFERENCES_HLTHRESHOLD;Kynnysarvo vaaleille alueille +PREFERENCES_ICCDIR;ICC-profiilien hakemisto +PREFERENCES_IMPROCPARAMS;Oletuskäsittelyprofiilit +PREFERENCES_INTENT_ABSOLUTE;Absoluuttinen kolorimetrinen +PREFERENCES_INTENT_PERCEPTUAL;Havainnollinen +PREFERENCES_INTENT_RELATIVE;Suhteellinen kolorimetrinen +PREFERENCES_INTENT_SATURATION;Kylläisyyden säilyttävä +PREFERENCES_LIVETHUMBNAILS;Jatkuvasti päivittyvä esikatselu (hidas) +PREFERENCES_MONITORICC;Näytön profiili +PREFERENCES_OUTDIRFOLDERHINT;Tallenna kuvat valittuun kansioon +PREFERENCES_OUTDIRFOLDER;Valitse hakemisto +PREFERENCES_OUTDIRHINT;Voit käyttää seuraavia komentoja:\n%f tiedosto\n%p1, %p2, ... polku\n%d1, %d2, ..., hakemisto\nNämä komennot viittaavat RAW-tiedoston hakemistoihin ja polkuihin.\n\nEsimerkiksi: jos /home/tom/image/02-09-2006/dsc0012.nefon avattu, komennot tarkoittavat seuraavaa:\n%f=dsc0012\n%d1=02-09-2006, %d2=image,...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nJos haluat tallentaa alkuperäisen kuvan hakemistoon:\n%p1/%f\n\nJos haluat tallentaa hakemistoon nimeltä 'converted' joka sijaitsee alkuperäisen kuvan hakemistossa:\n%p1/converted/%f\n\nJos haluat tallentaa hakemistoon '/home/tom/image/converted' ja pitää päivämäärähakemistot:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIR;Tallennushakemisto +PREFERENCES_OUTDIRTEMPLATEHINT;Voit käyttää seuraavia komentoja:\n%f tiedosto\n%p1, %p2, ... polku\n%d1, %d2, ..., hakemisto\nNämä komennot viittaavat RAW-tiedoston hakemistoihin ja polkuihin.\n\nEsimerkiksi: jos /home/tom/image/02-09-2006/dsc0012.nefon avattu, komennot tarkoittavat seuraavaa:\n%f=dsc0012\n%d1=02-09-2006, %d2=image,...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nJos haluat tallentaa alkuperäisen kuvan hakemistoon:\n%p1/%f\n\nJos haluat tallentaa hakemistoon nimeltä 'converted' joka sijaitsee alkuperäisen kuvan hakemistossa:\n%p1/converted/%f\n\nJos haluat tallentaa hakemistoon '/home/tom/image/converted' ja pitää päivämäärähakemistot:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Ohjelmoi hakemisto +PREFERENCES_PARSEDEXTADDHINT;Lisää tunniste +PREFERENCES_PARSEDEXTADD;Lisää tunniste +PREFERENCES_PARSEDEXTDELHINT;Poista valitut tunnisteet listasta +PREFERENCES_PARSEDEXT;Käytössä olevat tunnisteet +PREFERENCES_PROFILEHANDLING;Käsittelyprofiilit +PREFERENCES_PROFILELOADPR;Ensisijainen profiili +PREFERENCES_PROFILEPRCACHE;välimuisti +PREFERENCES_PROFILEPRFILE;oheistiedosto +PREFERENCES_PROFILESAVECACHE;Tallenna käsittelyparametrit välimuistiin +PREFERENCES_PROFILESAVEINPUT;Tallenna käsittelyparametrit oheistiedostoon +PREFERENCES_PSPATH;Adobe Photoshop:n asennushakemisto +PREFERENCES_SELECTICCDIRDLG;Valitse ICC-profiilin hakemisto... +PREFERENCES_SELECTLANG;Valitse kieli +PREFERENCES_SELECTMONITORPROFDLG;Valitse näytön ICC-profiili... +PREFERENCES_SELECTTHEME;Valitse teema +PREFERENCES_SHOWBASICEXIF;Perus EXIF-tiedot +PREFERENCES_SHOWDATETIME;Päivämäärä ja aika +PREFERENCES_SHOWONLYRAW;Näytä vain RAW-tiedostot +PREFERENCES_SHTHRESHOLD;Kynnysarvo tummille alueille +PREFERENCES_STARTUPIMDIR;Kuvahakemisto käynnistettäessä +PREFERENCES_TAB_BROWSER;Tiedostot +PREFERENCES_TAB_COLORMGR;Värit +PREFERENCES_TAB_GENERAL;Yleiset +PREFERENCES_TAB_IMPROC;Kuvankäsittely +PREFERENCES_TAB_OUTPUT;Tallennus +PREFERENCES_THUMBSIZE;Esikatselukuvien koko +PROFILEPANEL_FILEDLGFILTERANY;Kaikki tiedostot +PROFILEPANEL_FILEDLGFILTERPP;Profiilitiedostot +PROFILEPANEL_LABEL;Käsittelyprofiili +PROFILEPANEL_LOADDLGLABEL;Lataa käsittelyprofiili... +PROFILEPANEL_PCUSTOM;Oma +PROFILEPANEL_PFILE;Tiedostosta +PROFILEPANEL_PLASTPHOTO;Viimeisimmästä kuvasta +PROFILEPANEL_PLASTSAVED;Viimeisin tallennettu +PROFILEPANEL_PROFILE;Profiili +PROFILEPANEL_SAVEDLGLABEL;Tallenna käsittelyprofiili... +PROFILEPANEL_TOOLTIPCOPY;Kopioi nykyinen profiili leikepöydälle +PROFILEPANEL_TOOLTIPLOAD;Lataa profiili tiedostosta +PROFILEPANEL_TOOLTIPPASTE;Liitä profiili leikepöydältä +PROFILEPANEL_TOOLTIPSAVE;Tallenna profiili +PROGRESSBAR_DECODING;RAW-tiedostoa puretaan... +PROGRESSBAR_DEMOSAICING;Kuvaa koostetaan... +PROGRESSBAR_LOADING;Kuvaa ladataan... +PROGRESSBAR_LOADJPEG;JPEG-tiedostoa ladataan... +PROGRESSBAR_LOADPNG;PNG-tiedostoa ladataan... +PROGRESSBAR_LOADTIFF;TIFF-tiedostoa ladataan... +PROGRESSBAR_PROCESSING;Kuvaa käsitellään... +PROGRESSBAR_READY;Valmis. +PROGRESSBAR_SAVEJPEG;JPEG-tiedostoa tallennetaan... +PROGRESSBAR_SAVEPNG;PNG-tiedostoa tallennetaan... +PROGRESSBAR_SAVETIFF;TIFF-tiedostoa tallennetaan... +PROGRESSDLG_LOADING;Kuvaa ladataan... +PROGRESSDLG_PROCESSING;Kuvaa käsitellään... +PROGRESSDLG_SAVING;Tiedostoa tallennetaan... +QINFO_FOCALLENGTH;Polttoväli +QINFO_ISO;ISO +QINFO_LENS;Objektiivi +QINFO_NOEXIF;EXIF-tietoja ei saatavilla. +SAVEDLG_FILEFORMAT;Tiedostomuoto +SAVEDLG_JPEGQUAL;JPEG laatu (suurempi luku, parempi laatu) +SAVEDLG_JPGFILTER;JPEG tiedostot +SAVEDLG_PNGCOMPR;PNG pakkaus (suurempi luku, enemmän pakkausta) +SAVEDLG_PNGFILTER;PNG tiedostot +SAVEDLG_PUTTOQUEUEHEAD;Laita käsittelyjonon ensimmäiseksi +SAVEDLG_PUTTOQUEUE;Laita käsittelyjonoon +SAVEDLG_PUTTOQUEUETAIL;Laita käsittelyjonon viimeiseksi +SAVEDLG_SAVEIMMEDIATELY;Tallenna heti +SAVEDLG_SAVESPP;Tallenna kuvankäsittelytiedot kuvan mukana +SAVEDLG_TIFFFILTER;TIFF tiedostot +TOOLBAR_TOOLTIP_CROP;Valitse rajattava alue (pikanäppäin: C) +TOOLBAR_TOOLTIP_HAND;Kuvan siirtotyökalu (pikanäppäin: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Valitse suora linja (pikanäppäin: S) +TOOLBAR_TOOLTIP_WB;Valitse valkotasapainon\nvalkea piste kuvasta (pikanäppäin: W) +TP_CACORRECTION_BLUE;Sininen +TP_CACORRECTION_LABEL;Väripoikkeaman korjaus +TP_CACORRECTION_RED;Punainen +TP_CHMIXER_BLUE;Sininen +TP_CHMIXER_GREEN;Vihreä +TP_CHMIXER_LABEL;Kanavat +TP_CHMIXER_RED;Punainen +TP_COARSETRAF_DEGREE;astetta +TP_COARSETRAF_TOOLTIP_HFLIP;Peilaa vaakasuunnassa +TP_COARSETRAF_TOOLTIP_ROTLEFT;Käännä vasemmalle +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Käännä oikealle +TP_COARSETRAF_TOOLTIP_VFLIP;Peilaa pystysuunnassa +TP_COLORBOOST_ACHANNEL;a* +TP_COLORBOOST_AMOUNT;Määrä +TP_COLORBOOST_AVOIDCOLORCLIP;Vältä leikkautuminen +TP_COLORBOOST_BCHANNEL;b* +TP_COLORBOOST_CHAB;a* ja b* +TP_COLORBOOST_CHANNEL;Kanava +TP_COLORBOOST_CHSEPARATE;säädä erikseen +TP_COLORBOOST_ENABLESATLIMITER;Estä kyllästyminen +TP_COLORBOOST_LABEL;Värikylläisyys +TP_COLORBOOST_SATLIMIT;Kyllästymisraja +TP_COLORDENOISE_EDGESENSITIVE;Reunaherkkä +TP_COLORDENOISE_EDGETOLERANCE;Reunan tunnistusherkkyys +TP_COLORDENOISE_LABEL;Värin kohinanvaimennus +TP_COLORDENOISE_RADIUS;Säde +TP_COLORSHIFT_BLUEYELLOW;sininen-keltainen +TP_COLORSHIFT_GREENMAGENTA;vihreä-punainen +TP_COLORSHIFT_LABEL;Värisävy +TP_CROP_DPI;Erottelutarkkuus (DPI): +TP_CROP_FIXRATIO;Pidä kuvasuhde: +TP_CROP_GTDIAGONALS;Kulmien puolittajat +TP_CROP_GTHARMMEANS1;Kultainen leikkaus 1 +TP_CROP_GTHARMMEANS2;Kultainen leikkaus 2 +TP_CROP_GTHARMMEANS3;Kultainen leikkaus 3 +TP_CROP_GTHARMMEANS4;Kultainen leikkaus 4 +TP_CROP_GTNONE;Ei mikään +TP_CROP_GTRULETHIRDS;Kolmijako +TP_CROP_GUIDETYPE;Sommittelumalli: +TP_CROP_H;Kork. +TP_CROP_LABEL;Rajaus +TP_CROP_SELECTCROP;Valitse alue +TP_CROP_W;Lev. +TP_CROP_X; x +TP_CROP_Y; y +TP_DISTORTION_AMOUNT;Määrä +TP_DISTORTION_LABEL;Linssivääristymän korjaus +TP_EXPOSURE_AUTOLEVELS;Automaattinen +TP_EXPOSURE_BLACKLEVEL;Tummuus +TP_EXPOSURE_BRIGHTNESS;Kirkkaus +TP_EXPOSURE_CLIP;Raja +TP_EXPOSURE_COMPRHIGHLIGHTS;Vaaleiden alueiden vaimennus +TP_EXPOSURE_COMPRSHADOWS;Tummien alueiden vaimennus +TP_EXPOSURE_CONTRAST;Kontrasti +TP_EXPOSURE_CURVEEDITOR;Sävykäyrä +TP_EXPOSURE_EXPCOMP;Kompensointi +TP_EXPOSURE_LABEL;Valotuksen säätö +TP_HLREC_CIELAB;CIELAB värisekoitus +TP_HLREC_COLOR;Värin palautus +TP_HLREC_LABEL;Huippuvaloalueiden palautus +TP_HLREC_LUMINANCE;Luminanssin palautus +TP_HLREC_METHOD;Menetelmä: +TP_ICM_FILEDLGFILTERANY;kaikki tiedostot +TP_ICM_FILEDLGFILTERICM;ICC-profiilitiedostot +TP_ICM_GAMMABEFOREINPUT;Käytä profiilin gammaa +TP_ICM_INPUTCAMERA;Kameran oletus +TP_ICM_INPUTCUSTOM;Oma +TP_ICM_INPUTDLGLABEL;Valitse lähteen ICC-profiili... +TP_ICM_INPUTEMBEDDED;Käytä kuvan omaa, jos mahdollista +TP_ICM_INPUTPROFILE;Lähdeväriprofiili +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Ei ICM-profiilia: sRGB +TP_ICM_OUTPUTDLGLABEL;Valitse tuloksen ICC-profiili... +TP_ICM_OUTPUTPROFILE;Tulosväriprofiili +TP_ICM_SAVEREFERENCE;Tallenna mallikuva\nprofilointia varten +TP_ICM_WORKINGPROFILE;Työväriprofiili +TP_LUMACURVE_BLACKLEVEL;Tummuus +TP_LUMACURVE_BRIGHTNESS;Kirkkaus +TP_LUMACURVE_COMPRHIGHLIGHTS;Vaaleiden alueiden vaimennus +TP_LUMACURVE_COMPRSHADOWS;Tummien alueiden vaimennus +TP_LUMACURVE_CONTRAST;Kontrasti +TP_LUMACURVE_CURVEEDITOR;Luminanssin käyrä +TP_LUMACURVE_LABEL;Luminanssi +TP_LUMADENOISE_EDGETOLERANCE;Reunan tunnistusherkkyys +TP_LUMADENOISE_LABEL;Luminanssin kohinanvaimennus +TP_LUMADENOISE_RADIUS;Säde +TP_RESIZE_BICUBIC;Bikuutiollinen +TP_RESIZE_BICUBICSF;Bikuutiollinen (Pehmeämpi) +TP_RESIZE_BICUBICSH;Bikuutiollinen (Terävämpi) +TP_RESIZE_BILINEAR;Bilineaarinen +TP_RESIZE_FULLSIZE;Kuvan koko: +TP_RESIZE_H;Kork.: +TP_RESIZE_LABEL;Koko +TP_RESIZE_METHOD;Menetelmä: +TP_RESIZE_NEAREST;Lähin +TP_RESIZE_SCALE;Mittakaava +TP_RESIZE_W;Lev.: +TP_ROTATE_AUTOCROP;Aseta rajaus +TP_ROTATE_DEGREE;Astetta +TP_ROTATE_FILL;Suurenna/pienennä kuva automaattisesti +TP_ROTATE_LABEL;Oikaisu +TP_ROTATE_SELECTLINE;Valitse suora linja +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Vaaleiden alueiden vaimennus +TP_SHADOWSHLIGHTS_HLTONALW;Vaalean sävyalueen laajuus +TP_SHADOWSHLIGHTS_LABEL;Tummat/vaaleat alueet +TP_SHADOWSHLIGHTS_LOCALCONTR;Paikallinen kontrasti +TP_SHADOWSHLIGHTS_RADIUS;Säde +TP_SHADOWSHLIGHTS_SHADOWS;Tummien alueiden vaimennus +TP_SHADOWSHLIGHTS_SHTONALW;Tumman sävyalueen laajuus +TP_SHARPENING_AMOUNT;Määrä +TP_SHARPENING_EDRADIUS;Säde +TP_SHARPENING_EDTOLERANCE;Reunan tunnistusherkkyys +TP_SHARPENING_HALOCONTROL;Halo-ilmiön esto +TP_SHARPENING_HCAMOUNT;Määrä +TP_SHARPENING_LABEL;Terävöinti +TP_SHARPENING_METHOD;Menetelmä +TP_SHARPENING_ONLYEDGES;Terävöi vain reunat +TP_SHARPENING_RADIUS;Säde +TP_SHARPENING_RLD_AMOUNT;Määrä +TP_SHARPENING_RLD_DAMPING;Vaimennus +TP_SHARPENING_RLD_ITERATIONS;Iteraatiot +TP_SHARPENING_RLD;RL dekonvoluutio +TP_SHARPENING_THRESHOLD;Kynnys +TP_SHARPENING_USM;Epäterävä maski +TP_VIGNETTING_AMOUNT;Määrä +TP_VIGNETTING_LABEL;Vinjetoinnin korjaus +TP_VIGNETTING_RADIUS;Säde +TP_WBALANCE_AUTO;Automaattinen +TP_WBALANCE_CAMERA;Kamera +TP_WBALANCE_CUSTOM;Oma +TP_WBALANCE_GREEN;Valkoisen sävy +TP_WBALANCE_LABEL;Valkotasapaino +TP_WBALANCE_METHOD;Menetelmä +TP_WBALANCE_SIZE;Koko: +TP_WBALANCE_SPOTWB;Valitse valkoinen kuvasta +TP_WBALANCE_TEMPERATURE;Lämpötila [K] +ZOOMBAR_DETAIL; +ZOOMBAR_HUGE;Suurin +ZOOMBAR_LARGE;Suuri +ZOOMBAR_NORMAL;Normaali +ZOOMBAR_PREVIEW; +ZOOMBAR_SCALE; +ZOOMBAR_SMALL;Pieni + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Swedish b/rtdata/languages/Swedish new file mode 100644 index 000000000..2265209b7 --- /dev/null +++ b/rtdata/languages/Swedish @@ -0,0 +1,703 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# Swedish translation of RawTherapee +# Translated by Emil Ericsson +# 2008-01-22 +ADJUSTER_RESET_TO_DEFAULT;Ã…terställ till standard +CURVEEDITOR_FILEDLGFILTERANY;Vilka filer som helst +CURVEEDITOR_FILEDLGFILTERCURVE;Kurvfiler +CURVEEDITOR_LINEAR;Linjär +CURVEEDITOR_LOADDLGLABEL;Ladda kurva... +CURVEEDITOR_SAVEDLGLABEL;Spara kurva... +CURVEEDITOR_TOOLTIPLINEAR;Ã…terställ kurva till linjär +CURVEEDITOR_TOOLTIPLOAD;Ladda kurva frÃ¥n fil +CURVEEDITOR_TOOLTIPSAVE;Spara nuvarande kurva +EXIFFILTER_APERTURE;Aperture +EXIFFILTER_CAMERA;Camera +EXIFFILTER_DIALOGLABEL;Exif Filter +EXIFFILTER_FOCALLEN;Focal Length +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Lens +EXIFFILTER_SHUTTER;Shutter +EXIFPANEL_ADDEDIT;Add/Edit +EXIFPANEL_ADDEDITHINT;Add new tag or edit tag +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Enter value +EXIFPANEL_ADDTAGDLG_SELECTTAG;Select tag +EXIFPANEL_ADDTAGDLG_TITLE;Add/Edit Tag +EXIFPANEL_KEEPHINT;Keep the selected tags when writing output file +EXIFPANEL_KEEP;Keep +EXIFPANEL_REMOVEHINT;Remove the selected tags when writing output file +EXIFPANEL_REMOVE;Remove +EXIFPANEL_RESETALLHINT;Reset all tags to their original values +EXIFPANEL_RESETALL;Reset All +EXIFPANEL_RESETHINT;Reset the selected tags to their original values +EXIFPANEL_RESET;Reset +EXIFPANEL_SUBDIRECTORY;Subdirectory +FILEBROWSER_APPLYPROFILE;Apply profile +FILEBROWSER_ARRANGEMENTHINT;Change between vertical/horizontal alignment of thumbnails +FILEBROWSER_CLEARPROFILE;Clear profile +FILEBROWSER_COPYPROFILE;Copy profile +FILEBROWSER_DELETEDLGLABEL;File delete confirmation +FILEBROWSER_DELETEDLGMSG;Are you sure you want to delete the selected %1 files? +FILEBROWSER_EMPTYTRASH;Empty Trash +FILEBROWSER_EMPTYTRASHHINT;Permanently delete the files of the trash +FILEBROWSER_EXIFFILTERAPPLY;Apply +FILEBROWSER_EXIFFILTERAPPLYHINT;Switch on/off exif filter of the file browser +FILEBROWSER_EXIFFILTERLABEL;Exif Filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Change settings of the exif filter +FILEBROWSER_EXIFFILTERSETTINGS;Setup +FILEBROWSER_PARTIALPASTEPROFILE;Partial paste +FILEBROWSER_PASTEPROFILE;Paste profile +FILEBROWSER_POPUPCANCELJOB;Cancel job +FILEBROWSER_POPUPMOVEEND;Move to end of queue +FILEBROWSER_POPUPMOVEHEAD;Move to head of queue +FILEBROWSER_POPUPOPEN;Open +FILEBROWSER_POPUPPROCESS;Put to processing queue +FILEBROWSER_POPUPRANK1;Rank 1 +FILEBROWSER_POPUPRANK2;Rank 2 +FILEBROWSER_POPUPRANK3;Rank 3 +FILEBROWSER_POPUPRANK4;Rank 4 +FILEBROWSER_POPUPRANK5;Rank 5 +FILEBROWSER_POPUPREMOVE;Remove from filesystem +FILEBROWSER_POPUPRENAME;Rename +FILEBROWSER_POPUPSELECTALL;Select all +FILEBROWSER_POPUPTRASH;Move to trash +FILEBROWSER_POPUPUNRANK;Unrank +FILEBROWSER_POPUPUNTRASH;Remove from trash +FILEBROWSER_PROCESSINGSETTINGSHINT;Set the file format and output directory +FILEBROWSER_PROCESSINGSETTINGS;Settings +FILEBROWSER_RENAMEDLGLABEL;Rename file +FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +FILEBROWSER_SHOWDIRHINT;Show all images of the directory +FILEBROWSER_SHOWQUEUEHINT;Show content of the processing queue +FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1 star +FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2 star +FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3 star +FILEBROWSER_SHOWRANK4HINT;Show images ranked as 4 star +FILEBROWSER_SHOWRANK5HINT;Show images ranked as 5 star +FILEBROWSER_SHOWTRASHHINT;Show content of the trash +FILEBROWSER_SHOWUNRANKHINT;Show unranked images +FILEBROWSER_STARTPROCESSINGHINT;Start processing/saving of images in the queue +FILEBROWSER_STARTPROCESSING;Start Processing +FILEBROWSER_STOPPROCESSINGHINT;Stop processing of images +FILEBROWSER_STOPPROCESSING;Stop processing +FILEBROWSER_THUMBSIZE;Thumb. size +FILEBROWSER_ZOOMINHINT;Increase thumbnail size +FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size +GENERAL_ABOUT;Om +GENERAL_CANCEL;Avbryt +GENERAL_DISABLE;Avaktivera +GENERAL_DISABLED;Avaktivera +GENERAL_ENABLED;Verkställ +GENERAL_ENABLE;Verkställ +GENERAL_LANDSCAPE;Landskap +GENERAL_LOAD;Ladda +GENERAL_NA;n/a +GENERAL_NO;Nej +GENERAL_OK;Ok +GENERAL_PORTRAIT;Porträtt +GENERAL_SAVE;Spara +GENERAL_YES;Ja +HISTOGRAM_LABEL;Histogram +HISTOGRAM_TOOLTIP_B;Visa/göm blÃ¥tt histogram +HISTOGRAM_TOOLTIP_G;Visa/göm grönt histogram +HISTOGRAM_TOOLTIP_L;Visa/göm CIELAB Luminans histogram +HISTOGRAM_TOOLTIP_R;Visa/göm rött histogram +HISTORY_CHANGED;Changed +HISTORY_CUSTOMCURVE;Egen kurva +HISTORY_DELSNAPSHOT;Ta bort bokmärke +HISTORY_FROMCLIPBOARD;From clipboard +HISTORY_LABEL;Historia +HISTORY_MSG_10;Skuggkomprimering +HISTORY_MSG_11;Tonkurva +HISTORY_MSG_12;Autoexponering +HISTORY_MSG_13;Exponeringsmarkering +HISTORY_MSG_14;Luminansljusstyrka +HISTORY_MSG_15;Luminanskontrast +HISTORY_MSG_16;Svart luminans +HISTORY_MSG_17;Luminans högdager kompr. +HISTORY_MSG_18;Luminans skugg kompr. +HISTORY_MSG_19;Luminanskurva +HISTORY_MSG_1;Foto laddat +HISTORY_MSG_20;Skärpning +HISTORY_MSG_21;Skärpningsradie +HISTORY_MSG_22;Skärpningsmängd +HISTORY_MSG_23;Skärpningströskelvärde +HISTORY_MSG_24;Skärp bara kanter +HISTORY_MSG_25;Kantupptäckningsradie-skärpning +HISTORY_MSG_26;Kantskärpningstolerans +HISTORY_MSG_27;Halo-skärpningskontroll +HISTORY_MSG_28;Halo-kontrollstorlek +HISTORY_MSG_29;Skärpningsmetod +HISTORY_MSG_2;Profil laddad +HISTORY_MSG_30;Deconvolution-radie +HISTORY_MSG_31;Deconvolution-storlek +HISTORY_MSG_32;Deconvolution-dämpning +HISTORY_MSG_33;Deconvolution-upprepning +HISTORY_MSG_34;Undvik färgmarkeringar +HISTORY_MSG_35;Mättnadsbegränsning +HISTORY_MSG_36;Mättnadsgräns +HISTORY_MSG_37;Färgförstärkning +HISTORY_MSG_38;Vitbalansmetod +HISTORY_MSG_39;Färgtemperatur +HISTORY_MSG_3;Profil ändrad +HISTORY_MSG_40;Vitbalansnyans +HISTORY_MSG_41;Färgskiftning "A" +HISTORY_MSG_42;Färgskiftning "B" +HISTORY_MSG_43;Luminans brusborttagning +HISTORY_MSG_44;Lum. brusborttagnings-radie +HISTORY_MSG_45;Lum. brusborttagnings kanttolerans +HISTORY_MSG_46;Färgbrusborttagning +HISTORY_MSG_47;Färgbrusborttagnings-radie +HISTORY_MSG_48;Färgbrusborttagnings-kanttolerans +HISTORY_MSG_49;Kantkänslig färgbrusborttagning +HISTORY_MSG_4;Historia-bläddrande +HISTORY_MSG_50;Skugg/högdager verktyg +HISTORY_MSG_51;Högdager-förstärkning +HISTORY_MSG_52;Skuggförstärkning +HISTORY_MSG_53;Högdager-tonvidd +HISTORY_MSG_54;Skugg-tonvidd +HISTORY_MSG_55;Lokal kontrast +HISTORY_MSG_56;Skugg/högdager -radie +HISTORY_MSG_57;Enkel rotation +HISTORY_MSG_58;Vänd horisontellt +HISTORY_MSG_59;Vänd vertikalt +HISTORY_MSG_5;Ljusstyrka +HISTORY_MSG_60;Rotation +HISTORY_MSG_61;Rotation +HISTORY_MSG_62;Objektivdistorsions-korrigering +HISTORY_MSG_63;Valt bokmärke +HISTORY_MSG_64;Beskär foto +HISTORY_MSG_65;C/A korrigering +HISTORY_MSG_66;Högdager-förbättring +HISTORY_MSG_67;Högdager-förbättringsstorlek +HISTORY_MSG_68;Högdager-förbättringsmetod +HISTORY_MSG_69;Arbetsfärgrymd +HISTORY_MSG_6;Kontrast +HISTORY_MSG_70;Utmatningsfärgrymd +HISTORY_MSG_71;Inmatningsfärgrymd +HISTORY_MSG_72;Vinjettering-korrigering +HISTORY_MSG_73;Kanalmixer +HISTORY_MSG_74;Ändra storleksskala +HISTORY_MSG_75;Ändra storleks metod +HISTORY_MSG_76;Exif Metadata +HISTORY_MSG_77;IPTC Metadata +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;Svart +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;Exponerings-komprimering +HISTORY_MSG_9;Högdager-komprimering +HISTORY_NEWSNAPSHOTAS;Som... +HISTORY_NEWSNAPSHOT;Nytt bokmärke +HISTORY_NEWSSDIALOGLABEL;Namn pÃ¥ bokmärket: +HISTORY_NEWSSDIALOGTITLE;Lägg till nytt bokmärke +HISTORY_SETTO;Ställ in till +HISTORY_SNAPSHOT;Bokmärke +HISTORY_SNAPSHOTS;Bokmärken +ICMPANEL_FILEDLGFILTERANY;Vilka filer som helst +ICMPANEL_FILEDLGFILTERICM;ICC profilfiler +ICMPANEL_GAMMABEFOREINPUT;Profile applies Gamma +ICMPANEL_INPUTCAMERA;Kameraval +ICMPANEL_INPUTCUSTOM;Egen +ICMPANEL_INPUTDLGLABEL;Välj inmatnings ICC-profil... +ICMPANEL_INPUTEMBEDDED;Använd inbäddad, om möjligt +ICMPANEL_INPUTPROFILE;Inmatningsprofil +ICMPANEL_NOICM;Ingen ICM: sRGB-utmatning +ICMPANEL_OUTPUTDLGLABEL;Välj utmatnings ICC-profil... +ICMPANEL_OUTPUTPROFILE;Utmatningsprofil +ICMPANEL_SAVEREFERENCE;Save reference image for profiling +ICMPANEL_WORKINGPROFILE;Arbetsprofil +IMAGEAREA_DETAILVIEW;Detalj +IPTCPANEL_AUTHOR;Author +IPTCPANEL_AUTHORHINT;Name of the creator of the object, e.g. writer, photographer or graphic artist (By-line). +IPTCPANEL_AUTHORSPOSITION;Author's position +IPTCPANEL_AUTHORSPOSITIONHINT;Title of the creator or creators of the object (By-line Title). +IPTCPANEL_CAPTION;Caption +IPTCPANEL_CAPTIONHINT;A textual description of the data (Caption - Abstract). +IPTCPANEL_CAPTIONWRITER;Caption Writer +IPTCPANEL_CAPTIONWRITERHINT;The name of the person involved in the writing, editing or correcting the image or caption/abstract (Writer - Editor). +IPTCPANEL_CATEGORY;Category +IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider (Category). +IPTCPANEL_CITY;City +IPTCPANEL_CITYHINT;City of image origin (City). +IPTCPANEL_COPYHINT;Copy IPTC settings to clipboard +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COPYRIGHTHINT;Any necessary copyright notice (Copyright Notice). +IPTCPANEL_COUNTRY;Country +IPTCPANEL_COUNTRYHINT;The name of the country/primary location where the image was created (Country - Primary Location Name). +IPTCPANEL_CREDIT;Credit +IPTCPANEL_CREDITHINT;Identifies the provider of the image, not necessarily the owner/creator (Credit). +IPTCPANEL_DATECREATED;Date Created +IPTCPANEL_DATECREATEDHINT;The date the intellectual content of the image was created; Format: JJJJMMTT (Date Created). +IPTCPANEL_EMBEDDED;Embedded +IPTCPANEL_EMBEDDEDHINT;Reset to IPTC data embedded in the image file +IPTCPANEL_HEADLINE;Headline +IPTCPANEL_HEADLINEHINT;A publishable entry providing a synopsis of the contents of the image (Headline). +IPTCPANEL_INSTRUCTIONSHINT;Other editorial instructions concerning the use of the image (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Instructions +IPTCPANEL_KEYWORDSHINT;Used to indicate specific information retrieval words (Keywords). +IPTCPANEL_KEYWORDS;Keywords +IPTCPANEL_PASTEHINT;Paste IPTC settings from clipboard +IPTCPANEL_PROVINCEHINT;The Province/State where the image originates (Province-State). +IPTCPANEL_PROVINCE;Province +IPTCPANEL_RESETHINT;Reset to profile default +IPTCPANEL_RESET;Reset +IPTCPANEL_SOURCEHINT;The original owner of the intellectual content of the image (Source). +IPTCPANEL_SOURCE;Source +IPTCPANEL_SUPPCATEGORIESHINT;Further refines the subject of the image (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Suppl. Categories +IPTCPANEL_TITLEHINT;A shorthand reference for the image (Object Name). +IPTCPANEL_TITLE;Title +IPTCPANEL_TRANSREFERENCEHINT;A code representing the location of original transmission (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Trans. Reference +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Inställningar +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;Som... +MAIN_BUTTON_SAVE;Spara bild +MAIN_BUTTON_SENDTOEDITOR;Send to editor +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Filen existerar redan. +MAIN_MSG_CANNOTLOAD;Kan inte ladda bilden +MAIN_MSG_CANNOTSAVE;Filsparningsfel +MAIN_MSG_CANNOTSTARTEDITOR;Can not start editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Please set the correct path in the "Preferences" dialog. +MAIN_MSG_EXITJOBSINQUEUEINFO;Unprocessed images in the queue will be lost on exit. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Are you sure you want to exit? There are unprocessed images waiting in the queue. +MAIN_MSG_JOBSINQUEUE;Arbete(n) i kö +MAIN_MSG_QOVERWRITE;Vill du skriva över den? +MAIN_TAB_BASIC;Grund +MAIN_TAB_COLOR;Color +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Exposure +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;ICM +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Omvandla +MAIN_TOOLTIP_HIDEFP;Visa/göm den nedre panelen (katalog och filbläddrare, shortcut key: F) +MAIN_TOOLTIP_HIDEHP;Visa/göm den vänstra panelen (innehÃ¥ller historiken, shortcut key: H) +MAIN_TOOLTIP_INDCLIPPEDH;Markerad högdager-indikation +MAIN_TOOLTIP_INDCLIPPEDS;Markerad skugg-indikation +MAIN_TOOLTIP_PREFERENCES;Ställ in inställningar +MAIN_TOOLTIP_QINFO;Snabb info om bilden +MAIN_TOOLTIP_SAVEAS;Spara bilden till en vald mapp +MAIN_TOOLTIP_SAVE;Spara bilden till standardmappen +PARTIALPASTE_BASICGROUP;Basic settings +PARTIALPASTE_CACORRECTION;C/A correction +PARTIALPASTE_COARSETRANS;90 deg rotation / flipping +PARTIALPASTE_COLORBOOST;Color boost +PARTIALPASTE_COLORDENOISE;Color denoise +PARTIALPASTE_COLORGROUP;Color related settings +PARTIALPASTE_COLORMIXER;Color mixer +PARTIALPASTE_COLORSHIFT;Color shift +PARTIALPASTE_COMPOSITIONGROUP;Composition settings +PARTIALPASTE_CROP;Crop +PARTIALPASTE_DIALOGLABEL;Partial paste processing profile +PARTIALPASTE_DISTORTION;Distortion correction +PARTIALPASTE_EXIFCHANGES;Changes to exif data +PARTIALPASTE_EXPOSURE;Exposure +PARTIALPASTE_HLRECOVERY;Highlight recovery +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Lens related settings +PARTIALPASTE_LUMACURVE;Luminance curve +PARTIALPASTE_LUMADENOISE;Luminance noise reduction +PARTIALPASTE_LUMINANCEGROUP;Luminance related settings +PARTIALPASTE_METAICMGROUP;Metadata/ICM settings +PARTIALPASTE_RESIZE;Resize +PARTIALPASTE_ROTATION;Rotation +PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights +PARTIALPASTE_SHARPENING;Sharpening +PARTIALPASTE_VIGNETTING;Vignetting correction +PARTIALPASTE_WHITEBALANCE;White balance +PREFERENCES_APPLNEXTSTARTUP;ändras vid nästa uppstart +PREFERENCES_BLINKCLIPPED;Blinka markerade omrÃ¥den +PREFERENCES_CACHECLEARALL;Clear All +PREFERENCES_CACHECLEARPROFILES;Clear Profiles +PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +PREFERENCES_CACHEFORMAT1;Proprietary (faster and better quality) +PREFERENCES_CACHEFORMAT2;JPEG (smaller disk footprint) +PREFERENCES_CACHEMAXENTRIES;Maximal Number of Cache Entries +PREFERENCES_CACHEOPTS;Cache Options +PREFERENCES_CACHESTRAT1;Prefer Speed to Low Memory Consumption +PREFERENCES_CACHESTRAT2;Prefer Low Memory Consumption to Speed +PREFERENCES_CACHESTRAT;Cache Strategy +PREFERENCES_CACHETHUMBFORM;Cache Thumbnail Format +PREFERENCES_CACHETHUMBHEIGHT;Maximal Thumbnail Height +PREFERENCES_CLEARDLG_LINE1;Clearing cache +PREFERENCES_CLEARDLG_LINE2;This may take a few seconds. +PREFERENCES_CLEARDLG_TITLE;Please wait +PREFERENCES_CLIPPINGIND;Markerings-indikation +PREFERENCES_CMETRICINTENT;Colorimetric Intent +PREFERENCES_DATEFORMAT;Datumformat +PREFERENCES_DATEFORMATHINT;You can use the following formatting strings:\n%y : year\n%m : month\n%d : day\n\nFor example, the hungarian date format is:\n%y/%m/%d +PREFERENCES_DEFAULTLANG;Förvalt sprÃ¥k +PREFERENCES_DEFAULTTHEME;Default theme +PREFERENCES_DEMOSAICINGALGO;Demosaicing Algorithm +PREFERENCES_DIRHOME;Hemkatalog +PREFERENCES_DIRLAST;Senaste besökta katalog +PREFERENCES_DIROTHER;Annan +PREFERENCES_DIRSELECTDLG;Välj Bildkatalog vid uppstart... +PREFERENCES_DIRSOFTWARE;Installations-katalog +PREFERENCES_DMETHOD;Metod +PREFERENCES_EDITORCMDLINE;Other command line +PREFERENCES_EXTERNALEDITOR;External editor +PREFERENCES_FALSECOLOR;Falskt färgbortträngningssteg +PREFERENCES_FBROWSEROPTS;Filbläddrar-inställningar +PREFERENCES_FILEFORMAT;Filformat +PREFERENCES_FORIMAGE;För bildfiler +PREFERENCES_FORRAW;För RAW-filer +PREFERENCES_GIMPPATH;GIMP installation directory +PREFERENCES_GTKTHEME;GTK default +PREFERENCES_HINT;Tips +PREFERENCES_HLTHRESHOLD;Tröskelvärde för markerade högdager +PREFERENCES_ICCDIR;Katalog för ICC-profiler +PREFERENCES_IMPROCPARAMS;Standard-bildbehandlingsparametrar +PREFERENCES_INTENT_ABSOLUTE;Total colorimetric +PREFERENCES_INTENT_PERCEPTUAL;Perceptual +PREFERENCES_INTENT_RELATIVE;Relativ colorimetric +PREFERENCES_INTENT_SATURATION;Mättnad +PREFERENCES_LIVETHUMBNAILS;Live Thumbnails (slower) +PREFERENCES_MONITORICC;Skärmprofil +PREFERENCES_OUTDIRFOLDERHINT;Put the saved images to the seledted folder +PREFERENCES_OUTDIRFOLDER;Save to folder +PREFERENCES_OUTDIRHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Use Template +PREFERENCES_OUTDIR;Utmatningskatalog +PREFERENCES_PARSEDEXTADD;Add Extension +PREFERENCES_PARSEDEXTADDHINT;Type an extension and press this button to append list +PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list +PREFERENCES_PARSEDEXT;Parsed Extensions +PREFERENCES_PROFILEHANDLING;Processing Profile Handling +PREFERENCES_PROFILELOADPR;Profile Loading Priority +PREFERENCES_PROFILEPRCACHE;Profile in Cache +PREFERENCES_PROFILEPRFILE;Profile Next to the Input File +PREFERENCES_PROFILESAVECACHE;Save Processing Parameters to the Cache +PREFERENCES_PROFILESAVEINPUT;Save Processing Parameters Next to the Input File +PREFERENCES_PSPATH;Adobe Photoshop installation directory +PREFERENCES_SELECTICCDIRDLG;Välj ICC-profil katalog... +PREFERENCES_SELECTLANG;Välj sprÃ¥k +PREFERENCES_SELECTMONITORPROFDLG;Välj ICC-profil för skärmen... +PREFERENCES_SELECTTHEME;Select theme +PREFERENCES_SHOWBASICEXIF;Visa grundlig Exif-information +PREFERENCES_SHOWDATETIME;Visa datum och tid +PREFERENCES_SHOWONLYRAW;Visa bara RAW-filer +PREFERENCES_SHTHRESHOLD;Tröskelvärde för markerade skuggor +PREFERENCES_STARTUPIMDIR;Bildkatalog som visas vid uppstart +PREFERENCES_TAB_BROWSER;Filbläddrare +PREFERENCES_TAB_COLORMGR;Färghantering +PREFERENCES_TAB_GENERAL;Allmän +PREFERENCES_TAB_IMPROC;Bildbehandling +PREFERENCES_TAB_OUTPUT;Utmatnings-inställningar +PREFERENCES_THUMBSIZE;Miniatyrbildstorlek +PROFILEPANEL_FILEDLGFILTERANY;Vilka filer som helst +PROFILEPANEL_FILEDLGFILTERPP;Postbehandlar profiler +PROFILEPANEL_LABEL;Postbehandlar profiler +PROFILEPANEL_LOADDLGLABEL;Ladda Postbehandlingsparametrar... +PROFILEPANEL_PCUSTOM;Egen +PROFILEPANEL_PFILE;FrÃ¥n fil +PROFILEPANEL_PLASTPHOTO;Senaste foto +PROFILEPANEL_PLASTSAVED;Senast sparad +PROFILEPANEL_PROFILE;Profil +PROFILEPANEL_SAVEDLGLABEL;Spara Postbehandlingsparametrar... +PROFILEPANEL_TOOLTIPCOPY;Copy current profile to clipboard +PROFILEPANEL_TOOLTIPLOAD;Ladda profil frÃ¥n fil +PROFILEPANEL_TOOLTIPPASTE; Paste profile from clipboard +PROFILEPANEL_TOOLTIPSAVE;Spara nuvarande profil +PROGRESSBAR_DECODING;Avkodar Raw-fil... +PROGRESSBAR_DEMOSAICING;Demosaicing... +PROGRESSBAR_LOADING;Laddar bild... +PROGRESSBAR_LOADJPEG;Laddar JPEG-fil... +PROGRESSBAR_LOADPNG;Laddar PNG-fil... +PROGRESSBAR_LOADTIFF;Laddar TIFF-fil... +PROGRESSBAR_PROCESSING;Bearbetar Bild... +PROGRESSBAR_READY;Klar. +PROGRESSBAR_SAVEJPEG;Sparar JPEG-fil... +PROGRESSBAR_SAVEPNG;Sparar PNG-fil... +PROGRESSBAR_SAVETIFF;Sparar TIFF-fil... +PROGRESSDLG_LOADING;Loading file... +PROGRESSDLG_PROCESSING;Processing image... +PROGRESSDLG_SAVING;Saving file... +QINFO_FOCALLENGTH;Brännvidd +QINFO_ISO;ISO +QINFO_LENS;Lens +QINFO_NOEXIF;Exifdata otillgänglig. +SAVEDLG_FILEFORMAT;Filformat +SAVEDLG_JPEGQUAL;JPEG-kvalitet +SAVEDLG_JPGFILTER;JPEG-filer +SAVEDLG_PNGCOMPR;PNG-komprimering +SAVEDLG_PNGFILTER;PNG-filer +SAVEDLG_PUTTOQUEUEHEAD;Put to the head of the processing queue +SAVEDLG_PUTTOQUEUE;Put into processing queue +SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue +SAVEDLG_SAVEIMMEDIATELY;Save immediately +SAVEDLG_SAVESPP;Spara behandlingsparametrarna med bilderna +SAVEDLG_TIFFFILTER;TIFF-filer +TOOLBAR_TOOLTIP_CROP;Välj beskärningsomrÃ¥de (shortcut key: C) +TOOLBAR_TOOLTIP_HAND;Handverktyg (shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Räta ut (shortcut key: S) +TOOLBAR_TOOLTIP_WB;Punkt-vitbalans (shortcut key: W) +TP_CACORRECTION_BLUE;BlÃ¥ +TP_CACORRECTION_LABEL;C/A justering +TP_CACORRECTION_RED;Röd +TP_CHMIXER_BLUE;BlÃ¥ +TP_CHMIXER_GREEN;Grön +TP_CHMIXER_LABEL;Kanalmixer +TP_CHMIXER_RED;Röd +TP_COARSETRAF_DEGREE;grad: +TP_COARSETRAF_TOOLTIP_HFLIP;Vänd horisontellt +TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotera Ã¥t vänster +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotera Ã¥t höger +TP_COARSETRAF_TOOLTIP_VFLIP;Vänd vertikalt +TP_COLORBOOST_ACHANNEL;kanal "a" +TP_COLORBOOST_AMOUNT;Mängd +TP_COLORBOOST_AVOIDCOLORCLIP;Undvik färgclipping +TP_COLORBOOST_BCHANNEL;kanal "b" +TP_COLORBOOST_CHAB;a & b +TP_COLORBOOST_CHANNEL;Kanal +TP_COLORBOOST_CHSEPARATE;separat +TP_COLORBOOST_ENABLESATLIMITER;Verkställ mättnadsgräns +TP_COLORBOOST_LABEL;Färgförstärkning +TP_COLORBOOST_SATLIMIT;Mättnadsgräns +TP_COLORDENOISE_EDGESENSITIVE;Kantkänslighet +TP_COLORDENOISE_EDGETOLERANCE;Kanttolerans +TP_COLORDENOISE_LABEL;Färgbrus-reducering +TP_COLORDENOISE_RADIUS;Radie +TP_COLORSHIFT_BLUEYELLOW;BlÃ¥-Gul +TP_COLORSHIFT_GREENMAGENTA;Grön-Magenta +TP_COLORSHIFT_LABEL;Färgskiftningar +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;Fixa proportion +TP_CROP_GTDIAGONALS;Diagonalregeln +TP_CROP_GTHARMMEANS1;Harmonic means 1 +TP_CROP_GTHARMMEANS2;Harmonic means 2 +TP_CROP_GTHARMMEANS3;Harmonic means 3 +TP_CROP_GTHARMMEANS4;Harmonic means 4 +TP_CROP_GTNONE;Ingen +TP_CROP_GTRULETHIRDS;Tredjedelsregeln +TP_CROP_GUIDETYPE;Guidetyp: +TP_CROP_H;H +TP_CROP_LABEL;Beskär +TP_CROP_SELECTCROP; Välj beskärningsomrÃ¥de +TP_CROP_W;B +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Mängd +TP_DISTORTION_LABEL;Distorsion +TP_EXPOSURE_AUTOLEVELS;AutonivÃ¥er +TP_EXPOSURE_BLACKLEVEL;Svart +TP_EXPOSURE_BRIGHTNESS;Ljusstyrka +TP_EXPOSURE_CLIP;Clip +TP_EXPOSURE_COMPRHIGHLIGHTS;Högdagerkomprimering +TP_EXPOSURE_COMPRSHADOWS;Skuggkomprimering +TP_EXPOSURE_CONTRAST;Kontrast +TP_EXPOSURE_CURVEEDITOR;Tonkurva +TP_EXPOSURE_EXPCOMP;Exp. Comp. +TP_EXPOSURE_LABEL;Exponering +TP_HLREC_CIELAB;CIELab Blending +TP_HLREC_COLOR;Färgspridning +TP_HLREC_LABEL;Högdager-förbättring +TP_HLREC_LUMINANCE;Bättring av luminans +TP_HLREC_METHOD;Metod: +TP_ICM_FILEDLGFILTERANY;Vilka filer som helst +TP_ICM_FILEDLGFILTERICM;ICC profilfiler +TP_ICM_GAMMABEFOREINPUT;Profile applies Gamma +TP_ICM_INPUTCAMERA;Kameraval +TP_ICM_INPUTCUSTOM;Egen +TP_ICM_INPUTDLGLABEL;Välj inmatnings ICC-profil... +TP_ICM_INPUTEMBEDDED;Använd inbäddad, om möjligt +TP_ICM_INPUTPROFILE;Inmatningsprofil +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Ingen ICM: sRGB-utmatning +TP_ICM_OUTPUTDLGLABEL;Välj utmatnings ICC-profil... +TP_ICM_OUTPUTPROFILE;Utmatningsprofil +TP_ICM_SAVEREFERENCE;Save reference image for profiling +TP_ICM_WORKINGPROFILE;Arbetsprofil +TP_LUMACURVE_BLACKLEVEL;Svart +TP_LUMACURVE_BRIGHTNESS;Ljusstyrka +TP_LUMACURVE_COMPRHIGHLIGHTS;Högdagerkomprimering +TP_LUMACURVE_COMPRSHADOWS;Skuggkomprimering +TP_LUMACURVE_CONTRAST;Kontrast +TP_LUMACURVE_CURVEEDITOR;Luminanskurva +TP_LUMACURVE_LABEL;Luminanskurva +TP_LUMADENOISE_EDGETOLERANCE;Kanttolerans +TP_LUMADENOISE_LABEL;Luminans-brusreducering +TP_LUMADENOISE_RADIUS;Radie +TP_RESIZE_BICUBIC;Bicubic +TP_RESIZE_BICUBICSF;Bicubic (Mjukare) +TP_RESIZE_BICUBICSH;Bicubic (Skarpare) +TP_RESIZE_BILINEAR;Bilinjär +TP_RESIZE_FULLSIZE;Full bildstorlek: +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Ändra storlek +TP_RESIZE_METHOD;Metod: +TP_RESIZE_NEAREST;Närmast +TP_RESIZE_SCALE;Skala +TP_RESIZE_W;B: +TP_ROTATE_AUTOCROP;Autobeskär +TP_ROTATE_DEGREE;Antal grader +TP_ROTATE_FILL;Fyll +TP_ROTATE_LABEL;Räta ut +TP_ROTATE_SELECTLINE; Välj rak linje +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Högdager +TP_SHADOWSHLIGHTS_HLTONALW;Tonvidd +TP_SHADOWSHLIGHTS_LABEL;Skuggor/högdager +TP_SHADOWSHLIGHTS_LOCALCONTR;Lokal konstrast +TP_SHADOWSHLIGHTS_RADIUS;Radie +TP_SHADOWSHLIGHTS_SHADOWS;Skuggor +TP_SHADOWSHLIGHTS_SHTONALW;Tonvidd +TP_SHARPENING_AMOUNT;Mängd +TP_SHARPENING_EDRADIUS;Radie +TP_SHARPENING_EDTOLERANCE;Kanttolerans +TP_SHARPENING_HALOCONTROL;Halo-kontrol +TP_SHARPENING_HCAMOUNT;Mängd +TP_SHARPENING_LABEL;Skärpa +TP_SHARPENING_METHOD;Metod +TP_SHARPENING_ONLYEDGES;Skärp bara kanter +TP_SHARPENING_RADIUS;Radie +TP_SHARPENING_RLD_AMOUNT;Mängd +TP_SHARPENING_RLD_DAMPING;Dämpning +TP_SHARPENING_RLD_ITERATIONS;Upprepningar +TP_SHARPENING_RLD;RL Deconvolution +TP_SHARPENING_THRESHOLD;Tröskelvärde +TP_SHARPENING_USM;Oskarp mask +TP_VIGNETTING_AMOUNT;Mängd +TP_VIGNETTING_LABEL;Vinjettering-korrigering +TP_VIGNETTING_RADIUS;Radie +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Kamera +TP_WBALANCE_CUSTOM;Egen +TP_WBALANCE_GREEN;Nyans +TP_WBALANCE_LABEL;Vitbalans +TP_WBALANCE_METHOD;Metod +TP_WBALANCE_SIZE;Storlek: +TP_WBALANCE_SPOTWB;Punkt VB +TP_WBALANCE_TEMPERATURE;Temperatur +ZOOMBAR_DETAIL;Lupp +ZOOMBAR_HUGE;Enorm +ZOOMBAR_LARGE;Stor +ZOOMBAR_NORMAL;Normal +ZOOMBAR_PREVIEW;Förhandsvisning +ZOOMBAR_SCALE;Skala +ZOOMBAR_SMALL;Liten + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/languages/Turkish b/rtdata/languages/Turkish new file mode 100644 index 000000000..55b5839fe --- /dev/null +++ b/rtdata/languages/Turkish @@ -0,0 +1,703 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# +# Turkish +# 2.3.2008 +# Oguz +ADJUSTER_RESET_TO_DEFAULT;Varsayılana dön +CURVEEDITOR_FILEDLGFILTERANY;Bütün dosyalar +CURVEEDITOR_FILEDLGFILTERCURVE;EÄŸri dosyaları +CURVEEDITOR_LINEAR;DoÄŸrusal +CURVEEDITOR_LOADDLGLABEL;EÄŸriyi yükle... +CURVEEDITOR_SAVEDLGLABEL;EÄŸriyi kaydet... +CURVEEDITOR_TOOLTIPLINEAR;EÄŸriyi düzelt +CURVEEDITOR_TOOLTIPLOAD;Kayıtlı bir eÄŸriyi yü +CURVEEDITOR_TOOLTIPSAVE;Kullanılan eÄŸriyi kaydet +EXIFFILTER_APERTURE;Aperture +EXIFFILTER_CAMERA;Camera +EXIFFILTER_DIALOGLABEL;Exif Filter +EXIFFILTER_FOCALLEN;Focal Length +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Lens +EXIFFILTER_SHUTTER;Shutter +EXIFPANEL_ADDEDIT;Add/Edit +EXIFPANEL_ADDEDITHINT;Add new tag or edit tag +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Enter value +EXIFPANEL_ADDTAGDLG_SELECTTAG;Select tag +EXIFPANEL_ADDTAGDLG_TITLE;Add/Edit Tag +EXIFPANEL_KEEPHINT;Keep the selected tags when writing output file +EXIFPANEL_KEEP;Keep +EXIFPANEL_REMOVEHINT;Remove the selected tags when writing output file +EXIFPANEL_REMOVE;Remove +EXIFPANEL_RESETALLHINT;Reset all tags to their original values +EXIFPANEL_RESETALL;Reset All +EXIFPANEL_RESETHINT;Reset the selected tags to their original values +EXIFPANEL_RESET;Reset +EXIFPANEL_SUBDIRECTORY;Subdirectory +FILEBROWSER_APPLYPROFILE;Apply profile +FILEBROWSER_ARRANGEMENTHINT;Change between vertical/horizontal alignment of thumbnails +FILEBROWSER_CLEARPROFILE;Clear profile +FILEBROWSER_COPYPROFILE;Copy profile +FILEBROWSER_DELETEDLGLABEL;File delete confirmation +FILEBROWSER_DELETEDLGMSG;Are you sure you want to delete the selected %1 files? +FILEBROWSER_EMPTYTRASH;Empty Trash +FILEBROWSER_EMPTYTRASHHINT;Permanently delete the files of the trash +FILEBROWSER_EXIFFILTERAPPLY;Apply +FILEBROWSER_EXIFFILTERAPPLYHINT;Switch on/off exif filter of the file browser +FILEBROWSER_EXIFFILTERLABEL;Exif Filter +FILEBROWSER_EXIFFILTERSETTINGSHINT;Change settings of the exif filter +FILEBROWSER_EXIFFILTERSETTINGS;Setup +FILEBROWSER_PARTIALPASTEPROFILE;Partial paste +FILEBROWSER_PASTEPROFILE;Paste profile +FILEBROWSER_POPUPCANCELJOB;Cancel job +FILEBROWSER_POPUPMOVEEND;Move to end of queue +FILEBROWSER_POPUPMOVEHEAD;Move to head of queue +FILEBROWSER_POPUPOPEN;Open +FILEBROWSER_POPUPPROCESS;Put to processing queue +FILEBROWSER_POPUPRANK1;Rank 1 +FILEBROWSER_POPUPRANK2;Rank 2 +FILEBROWSER_POPUPRANK3;Rank 3 +FILEBROWSER_POPUPRANK4;Rank 4 +FILEBROWSER_POPUPRANK5;Rank 5 +FILEBROWSER_POPUPREMOVE;Remove from filesystem +FILEBROWSER_POPUPRENAME;Rename +FILEBROWSER_POPUPSELECTALL;Select all +FILEBROWSER_POPUPTRASH;Move to trash +FILEBROWSER_POPUPUNRANK;Unrank +FILEBROWSER_POPUPUNTRASH;Remove from trash +FILEBROWSER_PROCESSINGSETTINGSHINT;Set the file format and output directory +FILEBROWSER_PROCESSINGSETTINGS;Settings +FILEBROWSER_RENAMEDLGLABEL;Rename file +FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +FILEBROWSER_SHOWDIRHINT;Show all images of the directory +FILEBROWSER_SHOWQUEUEHINT;Show content of the processing queue +FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1 star +FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2 star +FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3 star +FILEBROWSER_SHOWRANK4HINT;Show images ranked as 4 star +FILEBROWSER_SHOWRANK5HINT;Show images ranked as 5 star +FILEBROWSER_SHOWTRASHHINT;Show content of the trash +FILEBROWSER_SHOWUNRANKHINT;Show unranked images +FILEBROWSER_STARTPROCESSINGHINT;Start processing/saving of images in the queue +FILEBROWSER_STARTPROCESSING;Start Processing +FILEBROWSER_STOPPROCESSINGHINT;Stop processing of images +FILEBROWSER_STOPPROCESSING;Stop processing +FILEBROWSER_THUMBSIZE;Thumb. size +FILEBROWSER_ZOOMINHINT;Increase thumbnail size +FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size +GENERAL_ABOUT;Hakkında +GENERAL_CANCEL;İptal +GENERAL_DISABLED;Devre dışı +GENERAL_DISABLE;EtkisizleÅŸtir +GENERAL_ENABLED;Etkin +GENERAL_ENABLE;EtkinleÅŸtir +GENERAL_LANDSCAPE;Yatay +GENERAL_LOAD;Yükle +GENERAL_NA;Uygun deÄŸil +GENERAL_NO;Hayır +GENERAL_OK;Tamam +GENERAL_PORTRAIT;Dikey +GENERAL_SAVE;Kaydet +GENERAL_YES;Evet +HISTOGRAM_LABEL;Histogram +HISTOGRAM_TOOLTIP_B;Mavi histogramını göster/gizle +HISTOGRAM_TOOLTIP_G;YeÅŸil histogramını göster/gizle +HISTOGRAM_TOOLTIP_L;CIELAB aydınlık histogramını göster/gizle +HISTOGRAM_TOOLTIP_R;Kırmızı histogramını göster/gizle +HISTORY_CHANGED;Changed +HISTORY_CUSTOMCURVE;Özel eÄŸri +HISTORY_DELSNAPSHOT;ÅžipÅŸağı sil +HISTORY_FROMCLIPBOARD;From clipboard +HISTORY_LABEL;GeçmiÅŸ +HISTORY_MSG_10;Karaltı sıkıştırma +HISTORY_MSG_11;Ton eÄŸrisi +HISTORY_MSG_12;Otomatik pozlama +HISTORY_MSG_13;Pozlama kırpma +HISTORY_MSG_14;Aydınlık - parlaklık +HISTORY_MSG_15;Aydınlık - zıtlık +HISTORY_MSG_16;Aydınlık - siyah +HISTORY_MSG_17;Aydınlık - parıltı sıkıştırma +HISTORY_MSG_18;Aydınlık - karaltı sıkıştırma +HISTORY_MSG_19;Aydınlık eÄŸrisi +HISTORY_MSG_1;FotoÄŸraf yüklendi +HISTORY_MSG_20;KeskinleÅŸtirme +HISTORY_MSG_21;KeskinleÅŸtirme - çap +HISTORY_MSG_22;KeskinleÅŸtirme - miktar +HISTORY_MSG_23;KeskinleÅŸtirme - eÅŸik +HISTORY_MSG_24;Sadece kenarları keskinleÅŸtir +HISTORY_MSG_25;KeskinleÅŸtirme - kenar bulma kuralları +HISTORY_MSG_26;KeskinleÅŸtirme - kenar payı +HISTORY_MSG_27;KeskinleÅŸtirme - hale denetimi +HISTORY_MSG_28;Hale denetimi - miktar +HISTORY_MSG_29;KeskinleÅŸtirme - yöntem +HISTORY_MSG_2;Profil yüklendi +HISTORY_MSG_30;Ters evriÅŸim - çap +HISTORY_MSG_31;Ters evriÅŸim - miktar +HISTORY_MSG_32;Ters evriÅŸim - düşürme +HISTORY_MSG_33;Ters evriÅŸim - yineleme +HISTORY_MSG_34;Renk kırpmayı önle +HISTORY_MSG_35;Doygunluk kısıtlayıcı +HISTORY_MSG_36;Doygunluk sınırı +HISTORY_MSG_37;Renk iteleme +HISTORY_MSG_38;Beyaz ayarı - yöntem +HISTORY_MSG_39;Renk ısısı +HISTORY_MSG_3;Profil deÄŸiÅŸti +HISTORY_MSG_40;Beyaz ayarı - tint +HISTORY_MSG_41;"A" renk kayması +HISTORY_MSG_42;"B" kayması +HISTORY_MSG_43;Aydınlık gürültü giderme +HISTORY_MSG_44;Aydınlık gürültü giderme - çap +HISTORY_MSG_45;Aydınlık gürültü giderme - kenar payı +HISTORY_MSG_46;Renk gürültü giderme +HISTORY_MSG_47;Renk gürültü giderme - çap +HISTORY_MSG_48;Renk gürültü giderme - kenar payı +HISTORY_MSG_49;Kenar duyarlı renk gürültüsü giderme +HISTORY_MSG_4;GeçmiÅŸte gezinti +HISTORY_MSG_50;Karaltı/parıltı aracı +HISTORY_MSG_51;Parıltı iteleme +HISTORY_MSG_52;Karaltı iteleme +HISTORY_MSG_53;Parıltı - ton geniÅŸliÄŸi +HISTORY_MSG_54;Karaltı - ton geniÅŸliÄŸi +HISTORY_MSG_55;Bölgesel zıtlık +HISTORY_MSG_56;Karaltı/parıltı - zıtlık +HISTORY_MSG_57;Döndürme +HISTORY_MSG_58;Yatayda çevirme +HISTORY_MSG_59;Dikeyde çevirme +HISTORY_MSG_5;Parlaklık +HISTORY_MSG_60;Döndürme +HISTORY_MSG_61;Döndürme +HISTORY_MSG_62;Lens bükülmesi düzeltme +HISTORY_MSG_63;Yer imi seçildi +HISTORY_MSG_64;FotoÄŸrafı kırp +HISTORY_MSG_65;Renk kayması düzeltme +HISTORY_MSG_66;Parıltı kurtarma +HISTORY_MSG_67;Parıltı kurtarma - miktar +HISTORY_MSG_68;Parıltı kurtarma - yöntem +HISTORY_MSG_69;Çalışma renk uzayı +HISTORY_MSG_6;Zıtlık +HISTORY_MSG_70;Çıktı renk uzayı +HISTORY_MSG_71;Girdi renk uzayı +HISTORY_MSG_72;Çerçeve etkisi düzeltme +HISTORY_MSG_73;Kanal karıştırıcı +HISTORY_MSG_74;Yeniden boyutlandırma - ölçek +HISTORY_MSG_75;Yeniden boyutlandırma - yöntem +HISTORY_MSG_76;Exif Metadata +HISTORY_MSG_77;IPTC Metadata +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_7;Siyah +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_MSG_8;Pozlama telafisi +HISTORY_MSG_9;Parıltı sıkıştırma +HISTORY_NEWSNAPSHOTAS;... olarak +HISTORY_NEWSNAPSHOT;Yeni ÅŸipÅŸak +HISTORY_NEWSSDIALOGLABEL;ÅžipÅŸak etiketi: +HISTORY_NEWSSDIALOGTITLE;Yeni ÅŸipÅŸak ekle +HISTORY_SETTO;Belirle +HISTORY_SNAPSHOT;ÅžipÅŸak +HISTORY_SNAPSHOTS;ÅžipÅŸaklar +ICMPANEL_FILEDLGFILTERANY;Bütün dosyalar +ICMPANEL_FILEDLGFILTERICM;ICC profil dosyaları +ICMPANEL_GAMMABEFOREINPUT;Profile applies Gamma +ICMPANEL_INPUTCAMERA;Kamera varsayılanı +ICMPANEL_INPUTCUSTOM;Özel +ICMPANEL_INPUTDLGLABEL;Girdi ICC profilini seç... +ICMPANEL_INPUTEMBEDDED;Mümkün olduÄŸunda gömülü profili kullan +ICMPANEL_INPUTPROFILE;Girdi Profili +ICMPANEL_NOICM;No ICM: sRGB çıktı +ICMPANEL_OUTPUTDLGLABEL;Çıktı ICC profilini seç... +ICMPANEL_OUTPUTPROFILE;Çıktı profili +ICMPANEL_SAVEREFERENCE;Save reference image for profiling +ICMPANEL_WORKINGPROFILE;Çalışma profili +IMAGEAREA_DETAILVIEW;Detay görünümü +IPTCPANEL_AUTHOR;Author +IPTCPANEL_AUTHORHINT;Name of the creator of the object, e.g. writer, photographer or graphic artist (By-line). +IPTCPANEL_AUTHORSPOSITION;Author's position +IPTCPANEL_AUTHORSPOSITIONHINT;Title of the creator or creators of the object (By-line Title). +IPTCPANEL_CAPTION;Caption +IPTCPANEL_CAPTIONHINT;A textual description of the data (Caption - Abstract). +IPTCPANEL_CAPTIONWRITER;Caption Writer +IPTCPANEL_CAPTIONWRITERHINT;The name of the person involved in the writing, editing or correcting the image or caption/abstract (Writer - Editor). +IPTCPANEL_CATEGORY;Category +IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider (Category). +IPTCPANEL_CITY;City +IPTCPANEL_CITYHINT;City of image origin (City). +IPTCPANEL_COPYHINT;Copy IPTC settings to clipboard +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COPYRIGHTHINT;Any necessary copyright notice (Copyright Notice). +IPTCPANEL_COUNTRY;Country +IPTCPANEL_COUNTRYHINT;The name of the country/primary location where the image was created (Country - Primary Location Name). +IPTCPANEL_CREDIT;Credit +IPTCPANEL_CREDITHINT;Identifies the provider of the image, not necessarily the owner/creator (Credit). +IPTCPANEL_DATECREATED;Date Created +IPTCPANEL_DATECREATEDHINT;The date the intellectual content of the image was created; Format: JJJJMMTT (Date Created). +IPTCPANEL_EMBEDDED;Embedded +IPTCPANEL_EMBEDDEDHINT;Reset to IPTC data embedded in the image file +IPTCPANEL_HEADLINE;Headline +IPTCPANEL_HEADLINEHINT;A publishable entry providing a synopsis of the contents of the image (Headline). +IPTCPANEL_INSTRUCTIONSHINT;Other editorial instructions concerning the use of the image (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Instructions +IPTCPANEL_KEYWORDSHINT;Used to indicate specific information retrieval words (Keywords). +IPTCPANEL_KEYWORDS;Keywords +IPTCPANEL_PASTEHINT;Paste IPTC settings from clipboard +IPTCPANEL_PROVINCEHINT;The Province/State where the image originates (Province-State). +IPTCPANEL_PROVINCE;Province +IPTCPANEL_RESETHINT;Reset to profile default +IPTCPANEL_RESET;Reset +IPTCPANEL_SOURCEHINT;The original owner of the intellectual content of the image (Source). +IPTCPANEL_SOURCE;Source +IPTCPANEL_SUPPCATEGORIESHINT;Further refines the subject of the image (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Suppl. Categories +IPTCPANEL_TITLEHINT;A shorthand reference for the image (Object Name). +IPTCPANEL_TITLE;Title +IPTCPANEL_TRANSREFERENCEHINT;A code representing the location of original transmission (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Trans. Reference +MAIN_BUTTON_EXIT;Exit +MAIN_BUTTON_PREFERENCES;Seçenekler +MAIN_BUTTON_QUEUE;Put to queue +MAIN_BUTTON_SAVEAS;... olarak +MAIN_BUTTON_SAVE;Görüntüyü kaydet +MAIN_BUTTON_SENDTOEDITOR;Send to editor +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_PLACES;Places +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Dosya zaten var. +MAIN_MSG_CANNOTLOAD;Görüntü yüklenemiyor +MAIN_MSG_CANNOTSAVE;Dosya kaydetmede hata +MAIN_MSG_CANNOTSTARTEDITOR;Can not start editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Please set the correct path in the "Preferences" dialog. +MAIN_MSG_EXITJOBSINQUEUEINFO;Unprocessed images in the queue will be lost on exit. +MAIN_MSG_EXITJOBSINQUEUEQUEST;Are you sure you want to exit? There are unprocessed images waiting in the queue. +MAIN_MSG_JOBSINQUEUE;iÅŸ sırada +MAIN_MSG_QOVERWRITE;Üzerine yazmak ister misiniz? +MAIN_TAB_BASIC;Temel +MAIN_TAB_COLOR;Color +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Exposure +MAIN_TAB_FILTER;Filter +MAIN_TAB_ICM;Renk yönetimi +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TAGGING;Tagging +MAIN_TAB_TRANSFORM;Dönüşüm +MAIN_TOOLTIP_HIDEFP;Alt tablayı göster/gizle (dizin ve dosya gezgni, shortcut key: F) +MAIN_TOOLTIP_HIDEHP;Sol tablayı göster/gizle (geçmiÅŸ ile birlikte, shortcut key: H) +MAIN_TOOLTIP_INDCLIPPEDH;Kırpılmış parıltı gösterme +MAIN_TOOLTIP_INDCLIPPEDS;Kırpılmış karaltı gösterme +MAIN_TOOLTIP_PREFERENCES;Seçenekleri belirle +MAIN_TOOLTIP_QINFO;Görüntü hakkında kısa bilgi +MAIN_TOOLTIP_SAVEAS;Görüntüyü seçili klasöre kaydet +MAIN_TOOLTIP_SAVE;Görüntüyü varsayılan klasöre kaydet +PARTIALPASTE_BASICGROUP;Basic settings +PARTIALPASTE_CACORRECTION;C/A correction +PARTIALPASTE_COARSETRANS;90 deg rotation / flipping +PARTIALPASTE_COLORBOOST;Color boost +PARTIALPASTE_COLORDENOISE;Color denoise +PARTIALPASTE_COLORGROUP;Color related settings +PARTIALPASTE_COLORMIXER;Color mixer +PARTIALPASTE_COLORSHIFT;Color shift +PARTIALPASTE_COMPOSITIONGROUP;Composition settings +PARTIALPASTE_CROP;Crop +PARTIALPASTE_DIALOGLABEL;Partial paste processing profile +PARTIALPASTE_DISTORTION;Distortion correction +PARTIALPASTE_EXIFCHANGES;Changes to exif data +PARTIALPASTE_EXPOSURE;Exposure +PARTIALPASTE_HLRECOVERY;Highlight recovery +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Lens related settings +PARTIALPASTE_LUMACURVE;Luminance curve +PARTIALPASTE_LUMADENOISE;Luminance noise reduction +PARTIALPASTE_LUMINANCEGROUP;Luminance related settings +PARTIALPASTE_METAICMGROUP;Metadata/ICM settings +PARTIALPASTE_RESIZE;Resize +PARTIALPASTE_ROTATION;Rotation +PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights +PARTIALPASTE_SHARPENING;Sharpening +PARTIALPASTE_VIGNETTING;Vignetting correction +PARTIALPASTE_WHITEBALANCE;White balance +PREFERENCES_APPLNEXTSTARTUP;Bir sonraki baÅŸlamada uygulacacak. +PREFERENCES_BLINKCLIPPED;Kırpılan alanlar yanıp-sönsün +PREFERENCES_CACHECLEARALL;Clear All +PREFERENCES_CACHECLEARPROFILES;Clear Profiles +PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +PREFERENCES_CACHEFORMAT1;Proprietary (faster and better quality) +PREFERENCES_CACHEFORMAT2;JPEG (smaller disk footprint) +PREFERENCES_CACHEMAXENTRIES;Maximal Number of Cache Entries +PREFERENCES_CACHEOPTS;Cache Options +PREFERENCES_CACHESTRAT1;Prefer Speed to Low Memory Consumption +PREFERENCES_CACHESTRAT2;Prefer Low Memory Consumption to Speed +PREFERENCES_CACHESTRAT;Cache Strategy +PREFERENCES_CACHETHUMBFORM;Cache Thumbnail Format +PREFERENCES_CACHETHUMBHEIGHT;Maximal Thumbnail Height +PREFERENCES_CLEARDLG_LINE1;Clearing cache +PREFERENCES_CLEARDLG_LINE2;This may take a few seconds. +PREFERENCES_CLEARDLG_TITLE;Please wait +PREFERENCES_CLIPPINGIND;Kırpma gösterme +PREFERENCES_CMETRICINTENT;Renkölçer +PREFERENCES_DATEFORMATHINT;You can use the following formatting strings:\n%y : year\n%m : month\n%d : day\n\nFor example, the hungarian date format is:\n%y/%m/%d +PREFERENCES_DATEFORMAT;Tarih biçimi +PREFERENCES_DEFAULTLANG;Varsayılan dil +PREFERENCES_DEFAULTTHEME;Default theme +PREFERENCES_DEMOSAICINGALGO;Demozaikleme algoritması +PREFERENCES_DIRHOME;Kullanıcı dizini +PREFERENCES_DIRLAST;Son gidilen dizin +PREFERENCES_DIROTHER;DiÄŸer +PREFERENCES_DIRSELECTDLG;BaÅŸlangıç görüntü dizinini seç... +PREFERENCES_DIRSOFTWARE;Kurulum dizini +PREFERENCES_DMETHOD;Yöntem +PREFERENCES_EDITORCMDLINE;Other command line +PREFERENCES_EXTERNALEDITOR;External editor +PREFERENCES_FALSECOLOR;Hatalı-renk bastırma deÄŸerleri +PREFERENCES_FBROWSEROPTS;Dosya gezgini seçenekleri +PREFERENCES_FILEFORMAT;Dosya biçimi +PREFERENCES_FORIMAGE;Gürüntü dosyaları için +PREFERENCES_FORRAW;RAW dosyaları için +PREFERENCES_GIMPPATH;GIMP installation directory +PREFERENCES_GTKTHEME;GTK default +PREFERENCES_HINT;İpucu +PREFERENCES_HLTHRESHOLD;Kırpılmış parıltılar için eÅŸik +PREFERENCES_ICCDIR;ICC profilleri dizini +PREFERENCES_IMPROCPARAMS;Varsayılan görüntü iÅŸleme deÄŸiÅŸkenleri +PREFERENCES_INTENT_ABSOLUTE;Mutlak +PREFERENCES_INTENT_PERCEPTUAL;Algısal +PREFERENCES_INTENT_RELATIVE;Bağıl +PREFERENCES_INTENT_SATURATION;Doyum +PREFERENCES_LIVETHUMBNAILS;Live Thumbnails (slower) +PREFERENCES_MONITORICC;Ekran profili +PREFERENCES_OUTDIR;Çıktı dizini +PREFERENCES_OUTDIRFOLDERHINT;Put the saved images to the seledted folder +PREFERENCES_OUTDIRFOLDER;Save to folder +PREFERENCES_OUTDIRHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Use Template +PREFERENCES_PARSEDEXTADD;Add Extension +PREFERENCES_PARSEDEXTADDHINT;Type an extension and press this button to append list +PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list +PREFERENCES_PARSEDEXT;Parsed Extensions +PREFERENCES_PROFILEHANDLING;Processing Profile Handling +PREFERENCES_PROFILELOADPR;Profile Loading Priority +PREFERENCES_PROFILEPRCACHE;Profile in Cache +PREFERENCES_PROFILEPRFILE;Profile Next to the Input File +PREFERENCES_PROFILESAVECACHE;Save Processing Parameters to the Cache +PREFERENCES_PROFILESAVEINPUT;Save Processing Parameters Next to the Input File +PREFERENCES_PSPATH;Adobe Photoshop installation directory +PREFERENCES_SELECTICCDIRDLG;ICC profil dizinini seç... +PREFERENCES_SELECTLANG;Dil seç +PREFERENCES_SELECTMONITORPROFDLG;Ekrana ait ICC profilini seç... +PREFERENCES_SELECTTHEME;Select theme +PREFERENCES_SHOWBASICEXIF;Temel exif bilgisini göster +PREFERENCES_SHOWDATETIME;Tarih ve saati göster +PREFERENCES_SHOWONLYRAW;Sadece RAW dosyalarını göster +PREFERENCES_SHTHRESHOLD;Kırpılmış karaltılar için eÅŸik +PREFERENCES_STARTUPIMDIR;BaÅŸlangıç görüntü dizini +PREFERENCES_TAB_BROWSER;Dosya gezgini +PREFERENCES_TAB_COLORMGR;Renk yönetimi +PREFERENCES_TAB_GENERAL;Genel +PREFERENCES_TAB_IMPROC;Görüntü iÅŸleme +PREFERENCES_TAB_OUTPUT;Çıktı seçenekleri +PREFERENCES_THUMBSIZE;Küçük-resim boyutu +PROFILEPANEL_FILEDLGFILTERANY;Bütün dosyalar +PROFILEPANEL_FILEDLGFILTERPP;Art-iÅŸleme profilleri +PROFILEPANEL_LABEL;Art-iÅŸleme profilleri +PROFILEPANEL_LOADDLGLABEL;Art-iÅŸleme deÄŸiÅŸkenlerini yükle... +PROFILEPANEL_PCUSTOM;Özel +PROFILEPANEL_PFILE;Dosyadan +PROFILEPANEL_PLASTPHOTO;Son FotoÄŸraf +PROFILEPANEL_PLASTSAVED;Son kaydedilen +PROFILEPANEL_PROFILE;Profil +PROFILEPANEL_SAVEDLGLABEL;Art-iÅŸleme deÄŸiÅŸkenlerini kaydet... +PROFILEPANEL_TOOLTIPCOPY;Copy current profile to clipboard +PROFILEPANEL_TOOLTIPLOAD;Kayıtlı bir profil yükle +PROFILEPANEL_TOOLTIPPASTE; Paste profile from clipboard +PROFILEPANEL_TOOLTIPSAVE;Geçerli profili kaydet +PROGRESSBAR_DECODING;Raw dosyası açılıyor... +PROGRESSBAR_DEMOSAICING;Demozaikleniyor... +PROGRESSBAR_LOADING;Görüntü yükleniyor... +PROGRESSBAR_LOADJPEG;JPEG dosyası yükleniyor... +PROGRESSBAR_LOADPNG;PNG dosyası yükleniyor... +PROGRESSBAR_LOADTIFF;TIFF dosyası yükleniyor... +PROGRESSBAR_PROCESSING;Görüntü iÅŸleniyor... +PROGRESSBAR_READY;Hazır. +PROGRESSBAR_SAVEJPEG;JPEG dosyası kaydediliyor... +PROGRESSBAR_SAVEPNG;PNG dosyası kaydediliyor... +PROGRESSBAR_SAVETIFF;TIFF dosyası kaydediliyor... +PROGRESSDLG_LOADING;Loading file... +PROGRESSDLG_PROCESSING;Processing image... +PROGRESSDLG_SAVING;Saving file... +QINFO_FOCALLENGTH;Odak uzunluÄŸu +QINFO_ISO;ISO +QINFO_LENS;Lens +QINFO_NOEXIF;Exif bilgisi yok. +SAVEDLG_FILEFORMAT;Dosya biçimi +SAVEDLG_JPEGQUAL;JPEG kalitesi +SAVEDLG_JPGFILTER;JPEG dosyaları +SAVEDLG_PNGCOMPR;PNG sıkıştırma düzeyi +SAVEDLG_PNGFILTER;PNG dosyaları +SAVEDLG_PUTTOQUEUEHEAD;Put to the head of the processing queue +SAVEDLG_PUTTOQUEUE;Put into processing queue +SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue +SAVEDLG_SAVEIMMEDIATELY;Save immediately +SAVEDLG_SAVESPP;İşeme deÄŸiÅŸkenlerini görüntü ile birlikte kaydet +SAVEDLG_TIFFFILTER;TIFF dosyaları +TOOLBAR_TOOLTIP_CROP;Seçimi kırp (shorcut key: C) +TOOLBAR_TOOLTIP_HAND;El aracı (shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Düz çizgi seçimi (shortcut key: S) +TOOLBAR_TOOLTIP_WB;Nokta beyaz ayarı (shortcut key: W) +TP_CACORRECTION_BLUE;Mavi +TP_CACORRECTION_LABEL;Renk sapması düzeltme +TP_CACORRECTION_RED;Kırmızı +TP_CHMIXER_BLUE;Mavi +TP_CHMIXER_GREEN;YeÅŸil +TP_CHMIXER_LABEL;Kanal karıştırıcı +TP_CHMIXER_RED;Kırmızı +TP_COARSETRAF_DEGREE;açı: +TP_COARSETRAF_TOOLTIP_HFLIP;Yatayda çevir +TP_COARSETRAF_TOOLTIP_ROTLEFT;Sola döndür +TP_COARSETRAF_TOOLTIP_ROTRIGHT;SaÄŸa döndür +TP_COARSETRAF_TOOLTIP_VFLIP;Dikeyde çevir +TP_COLORBOOST_ACHANNEL;"a" kanalı +TP_COLORBOOST_AMOUNT;Miktar +TP_COLORBOOST_AVOIDCOLORCLIP;Renk kırpılasını önle +TP_COLORBOOST_BCHANNEL;"b" kanalı +TP_COLORBOOST_CHAB;a ve b +TP_COLORBOOST_CHANNEL;Kanal +TP_COLORBOOST_CHSEPARATE;ayrık +TP_COLORBOOST_ENABLESATLIMITER;Doygunluk sınırlamayı etkinleÅŸtir +TP_COLORBOOST_LABEL;Renk iteleme +TP_COLORBOOST_SATLIMIT;Doygunluk sınırı +TP_COLORDENOISE_EDGESENSITIVE;Kenar duyarlı +TP_COLORDENOISE_EDGETOLERANCE;Kenar payı +TP_COLORDENOISE_LABEL;Renk gürültüsü azaltma +TP_COLORDENOISE_RADIUS;Çap +TP_COLORSHIFT_BLUEYELLOW;Mavi-sarı +TP_COLORSHIFT_GREENMAGENTA;YeÅŸil-macenta +TP_COLORSHIFT_LABEL;Renk kayması +TP_CROP_DPI;DPI= +TP_CROP_FIXRATIO;En-boy oranını düzelt: +TP_CROP_GTDIAGONALS;Çaprazlar kuralı +TP_CROP_GTHARMMEANS1;Harmonik ortalamalar 1 +TP_CROP_GTHARMMEANS2;Harmonik ortalamalar 2 +TP_CROP_GTHARMMEANS3;Harmonik ortalamalar 3 +TP_CROP_GTHARMMEANS4;Harmonik ortalamalar 4 +TP_CROP_GTNONE;Yok +TP_CROP_GTRULETHIRDS;Üçler kuralı +TP_CROP_GUIDETYPE;Kılavuz türü: +TP_CROP_H;Y +TP_CROP_LABEL;Kırp +TP_CROP_SELECTCROP; Kırpma alanı seç +TP_CROP_W;G +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Miktar +TP_DISTORTION_LABEL;Bükme +TP_EXPOSURE_AUTOLEVELS;Otomatik seviyeler +TP_EXPOSURE_BLACKLEVEL;Siyah +TP_EXPOSURE_BRIGHTNESS;Parlaklık +TP_EXPOSURE_CLIP;Kırpma +TP_EXPOSURE_COMPRHIGHLIGHTS;Parıltı sıkıştırma +TP_EXPOSURE_COMPRSHADOWS;Karaltı sıkıştırma +TP_EXPOSURE_CONTRAST;Zıtlık +TP_EXPOSURE_CURVEEDITOR;Ton eÄŸrisi +TP_EXPOSURE_EXPCOMP;Poz. telafisi +TP_EXPOSURE_LABEL;Pozlama +TP_HLREC_CIELAB;CIELab Blending +TP_HLREC_COLOR;Renk yayılımı +TP_HLREC_LABEL;Parıltı kurtarma +TP_HLREC_LUMINANCE;Aydınlık kurtarma +TP_HLREC_METHOD;Yöntem: +TP_ICM_FILEDLGFILTERANY;Bütün dosyalar +TP_ICM_FILEDLGFILTERICM;ICC profil dosyaları +TP_ICM_GAMMABEFOREINPUT;Profile applies Gamma +TP_ICM_INPUTCAMERA;Kamera varsayılanı +TP_ICM_INPUTCUSTOM;Özel +TP_ICM_INPUTDLGLABEL;Girdi ICC profilini seç... +TP_ICM_INPUTEMBEDDED;Mümkün olduÄŸunda gömülü profili kullan +TP_ICM_INPUTPROFILE;Girdi Profili +TP_ICM_LABEL;ICM +TP_ICM_NOICM;No ICM: sRGB çıktı +TP_ICM_OUTPUTDLGLABEL;Çıktı ICC profilini seç... +TP_ICM_OUTPUTPROFILE;Çıktı profili +TP_ICM_SAVEREFERENCE;Save reference image for profiling +TP_ICM_WORKINGPROFILE;Çalışma profili +TP_LUMACURVE_BLACKLEVEL;Siyah +TP_LUMACURVE_BRIGHTNESS;Parlaklık +TP_LUMACURVE_COMPRHIGHLIGHTS;Parıltı sıkıştırma +TP_LUMACURVE_COMPRSHADOWS;Karaltı sıkıştırma +TP_LUMACURVE_CONTRAST;Zıtlık +TP_LUMACURVE_CURVEEDITOR;Aydınlık eÄŸrisi +TP_LUMACURVE_LABEL;Aydınlık eÄŸrisi +TP_LUMADENOISE_EDGETOLERANCE;Kenar payı +TP_LUMADENOISE_LABEL;Aydınlık gürültüsü azaltma +TP_LUMADENOISE_RADIUS;Çap +TP_RESIZE_BICUBIC;Bikübik +TP_RESIZE_BICUBICSF;Bikübik (yumuÅŸak) +TP_RESIZE_BICUBICSH;Bikübik (keskin) +TP_RESIZE_BILINEAR;Çift-doÄŸrusal +TP_RESIZE_FULLSIZE;Tam gürüntü boyutu: +TP_RESIZE_H;Y: +TP_RESIZE_LABEL;Boyutları deÄŸiÅŸtir +TP_RESIZE_METHOD;Yöntem: +TP_RESIZE_NEAREST;En yakın +TP_RESIZE_SCALE;Ölçekle +TP_RESIZE_W;G: +TP_ROTATE_AUTOCROP;Otomatik kırpma +TP_ROTATE_DEGREE;Açı +TP_ROTATE_FILL;Doldur +TP_ROTATE_LABEL;Döndür +TP_ROTATE_SELECTLINE; Düz çizgi seç +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Parıltılar +TP_SHADOWSHLIGHTS_HLTONALW;Tonsal geniÅŸlik +TP_SHADOWSHLIGHTS_LABEL;Karaltılar/parıltılar +TP_SHADOWSHLIGHTS_LOCALCONTR;Bölgesel zıtlık +TP_SHADOWSHLIGHTS_RADIUS;Çap +TP_SHADOWSHLIGHTS_SHADOWS;Karaltılar +TP_SHADOWSHLIGHTS_SHTONALW;Tonsal geniÅŸlik +TP_SHARPENING_AMOUNT;Miktar +TP_SHARPENING_EDRADIUS;Çap +TP_SHARPENING_EDTOLERANCE;Kenar payı +TP_SHARPENING_HALOCONTROL;Hale denetimi +TP_SHARPENING_HCAMOUNT;Miktar +TP_SHARPENING_LABEL;KeskinleÅŸtirme +TP_SHARPENING_METHOD;Yöntem +TP_SHARPENING_ONLYEDGES;Sadece kenarları keskinleÅŸtir +TP_SHARPENING_RADIUS;Çap +TP_SHARPENING_RLD_AMOUNT;Miktar +TP_SHARPENING_RLD_DAMPING;Düşürme +TP_SHARPENING_RLD_ITERATIONS;Yineleme +TP_SHARPENING_RLD;R-L Ters evriÅŸimi +TP_SHARPENING_THRESHOLD;EÅŸik +TP_SHARPENING_USM;Bulanıklık Maskesi +TP_VIGNETTING_AMOUNT;Miktar +TP_VIGNETTING_LABEL;Çerçeve etkisi giderme +TP_VIGNETTING_RADIUS;Çap +TP_WBALANCE_AUTO;Otomatik +TP_WBALANCE_CAMERA;Kamera +TP_WBALANCE_CUSTOM;Özel +TP_WBALANCE_GREEN;Tint +TP_WBALANCE_LABEL;Beyaz ayarı +TP_WBALANCE_METHOD;Yöntem +TP_WBALANCE_SIZE;Boyut: +TP_WBALANCE_SPOTWB;Spot BA +TP_WBALANCE_TEMPERATURE;Isı +ZOOMBAR_DETAIL;Detay +ZOOMBAR_HUGE;Devasa +ZOOMBAR_LARGE;Büyük +ZOOMBAR_NORMAL;Normal +ZOOMBAR_PREVIEW;Önizleme +ZOOMBAR_SCALE;Ölçek +ZOOMBAR_SMALL;Küçük + +GENERAL_HIGH_QUALITY;High Quality +GENERAL_UNCHANGED;(Unchanged) +MAIN_MSG_PLACES;Places +GENERAL_BEFORE;Before +GENERAL_AFTER;After +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_MSG_NAVIGATOR;Navigator +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +BATCHQUEUE_AUTOSTART;Auto start +TP_DETAIL_AMOUNT;Amount +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SCALE;Scale +TP_RESIZE_WIDTH;Width +TP_RESIZE_HEIGHT;Height +MAIN_TOGGLE_BEFORE_AFTER;B|A + + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +EXIFFILTER_METADATAFILTER;Enable Metadata Filters +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_TYPE;Type: +CURVEEDITOR_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_DARKS;Darks +CURVEEDITOR_SHADOWS;Shadows +BATCH_PROCESSING;batch processing +PREFERENCES_BATCH_PROCESSING;batch processing +PREFERENCES_BEHAVIOR;Behavior +PREFERENCES_PROPERTY;Property +PREFERENCES_ADD;ADD +PREFERENCES_SET;SET +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser +MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_USETEMPLATE;Use template: +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +ZOOMPANEL_ZOOMIN;Zoom In +ZOOMPANEL_ZOOMOUT;Zoom Out +ZOOMPANEL_ZOOM100;Zoom to 100% +ZOOMPANEL_ZOOMFITSCREEN;Fit to screen +ZOOMPANEL_NEWCROPWINDOW;Add new crop window +ZOOMPANEL_100;(100%) + +### + +MAIN_BUTTON_FULLSCREEN;Fullscreen +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails + +NAVIGATOR_R_NA;R = n/a +NAVIGATOR_G_NA;G = n/a +NAVIGATOR_B_NA;B = n/a +NAVIGATOR_H_NA;H = n/a +NAVIGATOR_S_NA;S = n/a +NAVIGATOR_V_NA;V = n/a +NAVIGATOR_R_VALUE;R = %1 +NAVIGATOR_G_VALUE;G = %1 +NAVIGATOR_B_VALUE;B = %1 +NAVIGATOR_H_VALUE;H = %1 +NAVIGATOR_S_VALUE;S = %1 +NAVIGATOR_V_VALUE;V = %1 diff --git a/rtdata/options/options.lin b/rtdata/options/options.lin new file mode 100644 index 000000000..738f60d47 --- /dev/null +++ b/rtdata/options/options.lin @@ -0,0 +1,94 @@ + +[General] +StoreLastProfile=true +StartupDirectory=last +StartupPath= +DateFormat=%y/%m/%d +AdjusterDelay=0 +DualProcSupport=true +MultiUser=true +Language=English (US) +Theme=Gray +Version=300 +FirstRun=false + +[External Editor] +EditorKind=1 +GimpDir= +PhotoshopDir= +CustomEditor= + +[File Browser] +BrowseOnlyRaw=false +BrowserShowsDate=true +BrowserShowsExif=true +BrowserShowsHidden=false +ThumbnailSize=240 +MaxPreviewHeight=400 +MaxCacheEntries=20000 +ThumbnailFormat=5 +CacheMemPolicy=0 +ParseExtensions=jpg;tif;tiff;png;crw;cr2;crf;nef;raf;pef;dng;arw;sr2;mrw;raw;orf;kdc;rwz;rw2;mef; +ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; +ThumbnailArrangement=2 +ThumbnailInterpolation=1 +LiveThumbnails=true +FavoriteDirs= +RenameTemplates= +RenameUseTemplates=false +ThumbnailZoomRatios=0.2;0.3;0.45;0.6;0.8;1; +OverlayedFileNames=true + +[Clipping Indication] +HighlightThreshold=253 +ShadowThreshold=8 +BlinkClipped=false + +[Output] +Format=jpg +JpegQuality=100 +PngCompression=6 +PngBps=8 +TiffBps=8 +SaveProcParams=false +PathTemplate=%p1/converted/%f +PathFolder= +UsePathTemplate=true +LastSaveAsPath= + +[Profiles] +Directory=profiles +RawDefault=default +ImgDefault=neutral +SaveParamsWithFile=false +SaveParamsToCache=true +LoadParamsFromLocation=0 + +[GUI] +FileBrowserHeight=250 +ToolPanelWidth=270 +HistoryPanelWidth=230 +LastPreviewScale=5 +LastCropSize=1 +ShowHistory=true +ShowFilePanelState=2 +ShowInfo=true +ShowClippedHighlights=false +ShowClippedShadows=false +FrameColor=0 +ProcessingQueueEnbled=false +ToolPanelsExpanded=1;1;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0; + +[Algorithms] +DemosaicMethod=hphd +ColorCorrection=1 + +[Crop Settings] +Ratio=3:2 +FixRatio=true +DPI=600 + +[Color Management] +ICCDirectory= +MonitorProfile= +Intent=1 diff --git a/rtdata/options/options.osx b/rtdata/options/options.osx new file mode 100644 index 000000000..c0307c50e --- /dev/null +++ b/rtdata/options/options.osx @@ -0,0 +1,96 @@ + +[General] +StoreLastProfile=true +StartupDirectory=last +StartupPath= +DateFormat=%y/%m/%d +AdjusterDelay=0 +DualProcSupport=true +MultiUser=true +Language=English (US) +Theme=Gray Textured +Version=300 +FirstRun=true + +[External Editor] +EditorKind=1 +GimpDir= +PhotoshopDir= +CustomEditor= + +[File Browser] +BrowseOnlyRaw=false +BrowserShowsDate=true +BrowserShowsExif=true +BrowserShowsHidden=false +ThumbnailSize=240 +MaxPreviewHeight=400 +MaxCacheEntries=20000 +ThumbnailFormat=5 +CacheMemPolicy=0 +ParseExtensions=jpg;tif;tiff;png;crw;cr2;crf;nef;raf;pef;dng;arw;sr2;mrw;raw;orf;kdc;rwz;rw2;mef; +ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; +ThumbnailArrangement=2 +ThumbnailInterpolation=1 +LiveThumbnails=true +FavoriteDirs= +RenameTemplates= +RenameUseTemplates=false +ThumbnailZoomRatios=0.2;0.3;0.45;0.6;0.8;1; +OverlayedFileNames=true + +[Clipping Indication] +HighlightThreshold=253 +ShadowThreshold=8 +BlinkClipped=false + +[Output] +Format=jpg +JpegQuality=100 +PngCompression=6 +PngBps=8 +TiffBps=8 +SaveProcParams=false +PathTemplate=%p1/converted/%f +PathFolder= +UsePathTemplate=true +LastSaveAsPath= + +[Profiles] +Directory=profiles +RawDefault=default +ImgDefault=neutral +SaveParamsWithFile=false +SaveParamsToCache=true +LoadParamsFromLocation=0 + +[GUI] +WindowWidth=1024 +WindowHeight=700 +FileBrowserHeight=250 +ToolPanelWidth=270 +HistoryPanelWidth=230 +LastPreviewScale=5 +LastCropSize=1 +ShowHistory=true +ShowFilePanelState=2 +ShowInfo=true +ShowClippedHighlights=false +ShowClippedShadows=false +FrameColor=0 +ProcessingQueueEnbled=false +ToolPanelsExpanded=1;1;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0; + +[Algorithms] +DemosaicMethod=hphd +ColorCorrection=1 + +[Crop Settings] +Ratio=3:2 +FixRatio=true +DPI=600 + +[Color Management] +ICCDirectory= +MonitorProfile= +Intent=1 diff --git a/rtdata/options/options.win b/rtdata/options/options.win new file mode 100644 index 000000000..8fcedce86 --- /dev/null +++ b/rtdata/options/options.win @@ -0,0 +1,94 @@ + +[General] +StoreLastProfile=true +StartupDirectory=last +StartupPath= +DateFormat=%y/%m/%d +AdjusterDelay=0 +DualProcSupport=true +MultiUser=true +Language=English (US) +Theme=Gray +Version=300 +FirstRun=false + +[External Editor] +EditorKind=1 +GimpDir=C:\\Program Files\\GIMP-2.0 +PhotoshopDir=C:\\Program Files\\Adobe\\Adobe Photoshop CS3 +CustomEditor=start + +[File Browser] +BrowseOnlyRaw=false +BrowserShowsDate=true +BrowserShowsExif=true +BrowserShowsHidden=false +ThumbnailSize=240 +MaxPreviewHeight=400 +MaxCacheEntries=20000 +ThumbnailFormat=5 +CacheMemPolicy=0 +ParseExtensions=jpg;tif;tiff;png;crw;cr2;crf;nef;raf;pef;dng;arw;sr2;mrw;raw;orf;kdc;rwz;rw2;mef; +ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; +ThumbnailArrangement=2 +ThumbnailInterpolation=1 +LiveThumbnails=true +FavoriteDirs= +RenameTemplates= +RenameUseTemplates=false +ThumbnailZoomRatios=0.2;0.3;0.45;0.6;0.8;1; +OverlayedFileNames=true + +[Clipping Indication] +HighlightThreshold=253 +ShadowThreshold=8 +BlinkClipped=false + +[Output] +Format=jpg +JpegQuality=100 +PngCompression=6 +PngBps=8 +TiffBps=8 +SaveProcParams=false +PathTemplate=%p1/converted/%f +PathFolder= +UsePathTemplate=true +LastSaveAsPath= + +[Profiles] +Directory=profiles +RawDefault=default +ImgDefault=neutral +SaveParamsWithFile=false +SaveParamsToCache=true +LoadParamsFromLocation=0 + +[GUI] +FileBrowserHeight=250 +ToolPanelWidth=270 +HistoryPanelWidth=230 +LastPreviewScale=5 +LastCropSize=1 +ShowHistory=true +ShowFilePanelState=2 +ShowInfo=true +ShowClippedHighlights=false +ShowClippedShadows=false +FrameColor=0 +ProcessingQueueEnbled=false +ToolPanelsExpanded=1;1;0;0;0;1;1;0;0;0;0;1;1;0;0;0;0;0; + +[Algorithms] +DemosaicMethod=hphd +ColorCorrection=1 + +[Crop Settings] +Ratio=3:2 +FixRatio=true +DPI=600 + +[Color Management] +ICCDirectory= +MonitorProfile= +Intent=1 diff --git a/rtdata/profiles/crisp.pp2 b/rtdata/profiles/crisp.pp2 new file mode 100644 index 000000000..b49fe52b4 --- /dev/null +++ b/rtdata/profiles/crisp.pp2 @@ -0,0 +1,124 @@ + +[Version] +Version=231 + +[Exposure] +Auto=true +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=12 +Black=0 +HighlightCompr=100 +ShadowCompr=100 +Curve=1;0;0;1;1; + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Black=0 +HighlightCompr=0 +ShadowCompr=0 +Curve=1;0;0;1;1; + +[Sharpening] +Enabled=true +Method=usm +Radius=0.9 +Amount=135 +Threshold=768 +OnlyEdges=false +EdgedetectionRadius=1.9 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Color Boost] +ChannelA=12 +ChannelB=12 +AvoidColorClipping=false +SaturationLimiter=false +SaturationLimit=75 + +[White Balance] +Setting=Camera +Temperature=6504 +Green=1.0 + +[Color Shift] +ChannelA=0 +ChannelB=0 + +[Luminance Denoising] +Enabled=false +Radius=2.5 +EdgeTolerance=1500 + +[Chrominance Denoising] +Enabled=false +EdgeSensitive=false +Radius=2 +EdgeTolerance=3500 + +[Shadows & Highlights] +Enabled=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Crop] +Enabled=false +X=0 +Y=0 +W=10000 +H=10000 +FixedRatio=true +Ratio=3:2 +Orientation=Landscape +Guide=None + +[Coarse Transformation] +Rotate=0 +HorizontalFlip=false +VerticalFlip=false + +[Rotation] +Degree=0 +Fill=1 + +[Distortion] +Amount=0 + +[CACorrection] +Red=0 +Blue=0 + +[Vignetting Correction] +Amount=0 +Radius=50 + +[HLRecovery] +Enabled=true +Method=Luminance + +[Resize] +Scale=1 +Method=Bicubic + +[Color Management] +InputProfile=(camera) +ApplyGammaBeforeInputProfile=false +WorkingProfile=sRGB +OutputProfile=No ICM: sRGB output diff --git a/rtdata/profiles/default.pp2 b/rtdata/profiles/default.pp2 new file mode 100644 index 000000000..a76f8d10c --- /dev/null +++ b/rtdata/profiles/default.pp2 @@ -0,0 +1,125 @@ + +[Version] +Version=231 + +[Exposure] +Auto=true +Clip=0.01 +Compensation=0 +Brightness=0 +Contrast=0 +Black=0 +HighlightCompr=100 +ShadowCompr=100 +Curve=1;0;0;1;1; + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Black=0 +HighlightCompr=0 +ShadowCompr=0 +Curve=1;0;0;1;1; + +[Sharpening] +Enabled=true +Method=usm +Radius=0.8 +Amount=120 +Threshold=512 +OnlyEdges=false +EdgedetectionRadius=1.9 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Color Boost] +ChannelA=0 +ChannelB=0 +AvoidColorClipping=false +SaturationLimiter=false +SaturationLimit=75 + +[White Balance] +Setting=Camera +Temperature=6504 +Green=1.0 + +[Color Shift] +ChannelA=0 +ChannelB=0 + +[Luminance Denoising] +Enabled=false +Radius=2.5 +EdgeTolerance=1500 + +[Chrominance Denoising] +Enabled=false +EdgeSensitive=false +Radius=2 +EdgeTolerance=3500 + +[Shadows & Highlights] +Enabled=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Crop] +Enabled=false +X=0 +Y=0 +W=10000 +H=10000 +FixedRatio=true +Ratio=3:2 +Orientation=Landscape +Guide=None + +[Coarse Transformation] +Rotate=0 +HorizontalFlip=false +VerticalFlip=false + +[Rotation] +Degree=0 +Fill=1 + +[Distortion] +Amount=0 + +[CACorrection] +Red=0 +Blue=0 + +[Vignetting Correction] +Amount=0 +Radius=50 + +[HLRecovery] +Enabled=true +Method=Luminance + +[Resize] +Scale=1 +Method=Bicubic + +[Color Management] +InputProfile=(camera) +ApplyGammaBeforeInputProfile=false +WorkingProfile=sRGB +OutputProfile=No ICM: sRGB output + diff --git a/rtdata/profiles/neutral.pp2 b/rtdata/profiles/neutral.pp2 new file mode 100644 index 000000000..7d9000170 --- /dev/null +++ b/rtdata/profiles/neutral.pp2 @@ -0,0 +1,124 @@ + +[Version] +Version=231 + +[Exposure] +Auto=false +Clip=0.01 +Compensation=0 +Brightness=0 +Contrast=0 +Black=0 +HighlightCompr=100 +ShadowCompr=100 +Curve=1;0;0;1;1; + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Black=0 +HighlightCompr=0 +ShadowCompr=0 +Curve=1;0;0;1;1; + +[Sharpening] +Enabled=false +Method=usm +Radius=0.8 +Amount=120 +Threshold=512 +OnlyEdges=false +EdgedetectionRadius=1.9 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Color Boost] +ChannelA=0 +ChannelB=0 +AvoidColorClipping=false +SaturationLimiter=false +SaturationLimit=75 + +[White Balance] +Setting=Camera +Temperature=6504 +Green=1.0 + +[Color Shift] +ChannelA=0 +ChannelB=0 + +[Luminance Denoising] +Enabled=false +Radius=2.5 +EdgeTolerance=1500 + +[Chrominance Denoising] +Enabled=false +EdgeSensitive=false +Radius=2 +EdgeTolerance=3500 + +[Shadows & Highlights] +Enabled=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Crop] +Enabled=false +X=0 +Y=0 +W=10000 +H=10000 +FixedRatio=true +Ratio=3:2 +Orientation=Landscape +Guide=None + +[Coarse Transformation] +Rotate=0 +HorizontalFlip=false +VerticalFlip=false + +[Rotation] +Degree=0 +Fill=1 + +[Distortion] +Amount=0 + +[CACorrection] +Red=0 +Blue=0 + +[Vignetting Correction] +Amount=0 +Radius=50 + +[HLRecovery] +Enabled=true +Method=Luminance + +[Resize] +Scale=1 +Method=Bicubic + +[Color Management] +InputProfile=(camera) +ApplyGammaBeforeInputProfile=false +WorkingProfile=sRGB +OutputProfile=No ICM: sRGB output diff --git a/rtdata/themes/ClearLooks (Dark Orange) b/rtdata/themes/ClearLooks (Dark Orange) new file mode 100644 index 000000000..74f839aed --- /dev/null +++ b/rtdata/themes/ClearLooks (Dark Orange) @@ -0,0 +1,217 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# + + +# Color scheme contributed by Franco Gotusso based on Clearlooks-DarkCoffee by Chibi +# and edited by bvc as Clearlooks-DarkCoffee2. Downloaded from http://art.gnome.org/themes/gtk2/1065 + +style "clearlooks-default" +{ + GtkMenuItem::selected_shadow_type = none + GtkWidget::interior_focus = 1 + GtkButton::default_border = { 3, 3, 3, 3 } + GtkButton::default_outside_border = { 3, 3, 3, 3 } + GtkRange::trough_border = 2 + + GtkWidget::focus_padding = 1 + + GtkPaned::handle_size = 6 + + GtkRange::slider_width = 15 + GtkRange::stepper_size = 15 + GtkScrollbar::min_slider_length = 30 + GtkCheckButton::indicator_size = 12 + GtkMenuBar::internal-padding = 0 + + GtkTreeView::expander_size = 14 + GtkExpander::expander_size = 16 + + GtkTreeView::odd_row_color = "#343434" + + GtkWidget::cursor_color = "#E3DFDC" + GtkWidget::secondary_cursor_color = "#E3DFDC" + + xthickness = 1 + ythickness = 1 + + fg[NORMAL] = "#d2cfcc" #Main window text + fg[PRELIGHT] = "#E9E9E9" #Highlighted widget text + fg[ACTIVE] = "#ADA59D" #Inactive widget text + fg[SELECTED] = "#E9E9E9" #?#E9E9E9 + fg[INSENSITIVE] = "#202020" #CAN'T TOUCH DIS -[EDIT] I did (bvc) - [EDIT] Me too :) + + bg[NORMAL] = "#181818" #Backround + bg[PRELIGHT] = "#dd6003" #Highlight Widget + bg[ACTIVE] = "#343434" #Selected Widget + bg[SELECTED] = "#dd6003" #The box words are usually in @_@! + bg[INSENSITIVE] = "#202020" #Not active buttons + base[NORMAL] = "#000000" #Text area widgets. + base[PRELIGHT] = "#313131" #Check and radio button background + base[ACTIVE] = "#a64a07" #Unfocused Select + base[SELECTED] = "#e26000" #Selected Text area item, and that bar over the tabs. + base[INSENSITIVE] = "#f5f2ee" #Haven't got a clue + + text[NORMAL] = "#d2cfcc" # Text area widget text. + text[PRELIGHT] = "#E9E9E9" #? + text[ACTIVE] = "#ADA59D" #? + text[SELECTED] = "#E9E9E9" #Selected Text area widget text. + text[INSENSITIVE] = "#757575" #CAN'T TOUCH DIS -[EDIT] I did (bvc) + +engine "clearlooks" + { + sunkenmenubar = 1 # 0 = disable, 1 = enable + menuitemstyle = 1 # 0 = flat, 1 = 3d-ish (button) + listviewitemstyle = 1 # 0 = flat, 1 = 3d-ish (gradient) + progressbarstyle = 0 # 0 = candy bar, 1 = flat + } +} + +style "clearlooks-wide" = "clearlooks-default" +{ + xthickness = 2 + ythickness = 2 + bg[NORMAL] = "#313131" + bg[PRELIGHT] = "#393939" +} + +style "clearlooks-button" = "clearlooks-wide" +{ + bg[NORMAL] = "#313131" + bg[PRELIGHT] = "#393939" +} + +style "clearlooks-notebook" = "clearlooks-wide" +{ + bg[NORMAL] = "#202020" + bg[ACTIVE] = "#101010" +} + +style "clearlooks-tasklist" = "clearlooks-default" +{ + xthickness = 5 + ythickness = 3 +} + +style "clearlooks-menu" = "clearlooks-default" +{ + xthickness = 2 + ythickness = 1 + bg[NORMAL] = "#202020" +} + +style "clearlooks-menu-item" = "clearlooks-default" +{ + xthickness = 2 + ythickness = 3 + fg[PRELIGHT] = "#E9E9E9" + text[PRELIGHT] = "#E9E9E9" + base[PRELIGHT] = "#dd6003" + base[SELECTED] = "#dd6003" +} + +style "clearlooks-menu-itembar" = "clearlooks-default" +{ + xthickness = 3 + ythickness = 3 +} + +style "clearlooks-tree" = "clearlooks-default" +{ + xthickness = 2 + ythickness = 2 +} + +style "clearlooks-frame-title" = "clearlooks-default" +{ + fg[NORMAL] = "#d2cfcc" +} + +style "clearlooks-panel" = "clearlooks-default" +{ + xthickness = 3 + ythickness = 3 +} + +style "clearlooks-tooltips" = "clearlooks-default" +{ + xthickness = 4 + ythickness = 4 + bg[NORMAL] = "#dd6003" +} + +style "clearlooks-progressbar" = "clearlooks-default" +{ + xthickness = 1 + ythickness = 1 + fg[PRELIGHT] = "#d2cfcc" + bg[NORMAL] = "#1d0d01" +} + +style "clearlooks-combo" = "clearlooks-default" +{ + xthickness = 1 + ythickness = 2 + fg[NORMAL] = "#040404" + fg[PRELIGHT] = "#dd6003" + fg[ACTIVE] = "#d2cfcc" + bg[NORMAL] = "#313131" + bg[PRELIGHT] = "#393939" +} + +style "clearlooks-scrollbar" = "clearlooks-default" +{ + fg[NORMAL] = "#040404" + fg[PRELIGHT] = "#d2cfcc" + fg[ACTIVE] = "#d2cfcc" + bg[NORMAL] = "#313131" + bg[PRELIGHT] = "#393939" +} + +style "clearlooks-spin" = "clearlooks-wide" +{ + fg[NORMAL] = "#040404" + fg[PRELIGHT] = "#d2cfcc" + fg[ACTIVE] = "#d2cfcc" + bg[PRELIGHT] = "#313131" + bg[ACTIVE] = "#393939" +} + +class "GtkWidget" style "clearlooks-default" +class "GtkRange" style "clearlooks-wide" +class "GtkFrame" style "clearlooks-wide" +class "GtkSpinButton" style "clearlooks-spin" +class "GtkStatusbar" style "clearlooks-wide" +class "GtkMenu" style "clearlooks-menu" +class "GtkMenuItem" style "clearlooks-menu-item" +widget_class "*MenuItem.*" style "clearlooks-menu-item" +class "GtkEntry" style "clearlooks-wide" +widget_class "*.tooltips.*.GtkToggleButton" style "clearlooks-tasklist" +widget_class "*.GtkTreeView.GtkButton" style "clearlooks-tree" +widget_class "*.GtkCTree.GtkButton" style "clearlooks-tree" +widget_class "*.GtkList.GtkButton" style "clearlooks-tree" +widget_class "*.GtkCList.GtkButton" style "clearlooks-tree" +widget_class "*.GtkFrame.GtkLabel" style "clearlooks-frame-title" +widget_class "BasePWidget.GtkEventBox.GtkTable.GtkFrame" style "clearlooks-panel" +widget "gtk-tooltips" style "clearlooks-tooltips" +class "GtkNotebook" style "clearlooks-notebook" +class "GtkProgressBar" style "clearlooks-progressbar" +widget_class "*.GtkComboBox.GtkButton" style "clearlooks-combo" +widget_class "*.GtkCombo.GtkButton" style "clearlooks-combo" +class "GtkButton" style "clearlooks-button" +class "GtkScrollbar" style "clearlooks-scrollbar" diff --git a/rtdata/themes/Dark b/rtdata/themes/Dark new file mode 100644 index 000000000..11e332b29 --- /dev/null +++ b/rtdata/themes/Dark @@ -0,0 +1,213 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# + +# colour scheme (RT Dark) by Bytec ( http://bytec.vitanet.lv ) +# based on the default gtkrc for +# rawtherapee ( http://www.rawtherapee.com ) +# which is based on Bluecurve +# Created by Richard Stellingwerff, Emil Jacobs and Daniel Borgmann. + + +style "clearlooks-default" +{ + font_name = "tahoma 8" + GtkButton ::default_border = { 0, 0, 0, 0 } + GtkComboBox ::default_border = { 0, 0, 0, 0 } + GtkRange ::trough_border = 0 + GtkPaned ::handle_size = 6 + GtkRange ::slider_width = 12 + GtkRange ::stepper_size = 12 + GtkScrollbar ::min_slider_length = 30 + GtkCheckButton ::indicator_size = 12 + GtkMenuBar ::internal-padding = 2 + GtkTreeView ::expander_size = 11 + GtkExpander ::expander_size = 11 + + xthickness = 1 + ythickness = 1 + + fg[NORMAL] = "#808080" + fg[PRELIGHT] = "#d0d0d0" + fg[ACTIVE] = "#808080" + fg[SELECTED] = "#404040" + fg[INSENSITIVE] = "#2d2d2d" + + bg[NORMAL] = "#2d2d2d" + bg[PRELIGHT] = "#404040" + bg[ACTIVE] = "#2d2d2d" + bg[SELECTED] = "#606060" + bg[INSENSITIVE] = "#2d2d2d" + + base[NORMAL] = "#404040" + base[PRELIGHT] = "#404040" + base[ACTIVE] = "#404040" + base[SELECTED] = "#606060" + base[INSENSITIVE] = "#2d2d2d" + + text[NORMAL] = "#a0a0a0" + text[PRELIGHT] = "#d0d0d0" + text[ACTIVE] = "#a0a0a0" + text[SELECTED] = "#101010" + text[INSENSITIVE] = "#101010" + + engine "clearlooks" { + sunkenmenubar = 0 # 0 = disable, 1 = enable + menuitemstyle = 0 # 0 = flat, 1 = 3d-ish (button) + listviewitemstyle = 0 # 0 = flat, 1 = 3d-ish (gradient) + progressbarstyle = 1 # 0 = candy bar, 1 = flat + radius = 10.0 + } +} + +style "clearlooks-wide" = "clearlooks-default" +{ + xthickness = 1 + ythickness = 1 +} + +style "clearlooks-toggle" = "clearlooks-default" +{ + xthickness = 1 + ythickness = 1 + + bg[ACTIVE] = "#606060" + text[ACTIVE] = "#000000" + bg[SELECTED] = "#606060" + text[SELECTED] = "#000000" +} + +style "clearlooks-combo" = "clearlooks-default" +{ + xthickness = 0 + ythickness = 0 +} + +style "clearlooks-notebook" = "clearlooks-wide" +{ + bg[NORMAL] = "#2d2d2d" +} + +style "clearlooks-tasklist" = "clearlooks-default" +{ + xthickness = 5 + ythickness = 3 +} + +style "clearlooks-menu" = "clearlooks-default" +{ + xthickness = 2 + ythickness = 1 + bg[NORMAL] = "#2d2d2d" +} + +style "clearlooks-menu-item" = "clearlooks-default" +{ + xthickness = 1 + ythickness = 1 + fg[PRELIGHT] = "#404040" + text[PRELIGHT] = "#000000" +} + +style "clearlooks-menu-itembar" = "clearlooks-default" +{ + xthickness = 1 + ythickness = 1 +} + +style "clearlooks-tree" = "clearlooks-default" +{ + xthickness = 1 + ythickness = 1 +} + +style "clearlooks-frame-title" = "clearlooks-default" +{ + fg[NORMAL] = "#404040" +} + +style "clearlooks-panel" = "clearlooks-default" +{ + xthickness = 3 + ythickness = 3 +} + +style "clearlooks-tooltips" = "clearlooks-default" +{ + xthickness = 4 + ythickness = 4 + bg[NORMAL] = {1.0, 1.0, 1.0} + fg[NORMAL] = {0.0, 0.0, 0.0} + + fg[NORMAL] = "#000000" + fg[PRELIGHT] = "#000000" + fg[ACTIVE] = "#000000" + fg[SELECTED] = "#000000" + fg[INSENSITIVE] = "#000000" + + bg[NORMAL] = "#ffffff" + bg[PRELIGHT] = "#ffffff" + bg[ACTIVE] = "#ffffff" + bg[SELECTED] = "#ffffff" + bg[INSENSITIVE] = "#ffffff" + + base[NORMAL] = "#000000" + base[PRELIGHT] = "#000000" + base[ACTIVE] = "#000000" + base[SELECTED] = "#000000" + base[INSENSITIVE] = "#000000" + + text[NORMAL] = "#000000" + text[PRELIGHT] = "#000000" + text[ACTIVE] = "#000000" + text[SELECTED] = "#000000" + text[INSENSITIVE] = "#000000" + + +} + +style "clearlooks-progressbar" = "clearlooks-default" +{ + xthickness = 1 + ythickness = 1 + fg[PRELIGHT] = "#000000" +} + +class "GtkWidget" style "clearlooks-default" +class "GtkTreeView" style "clearlooks-default" +class "GtkButton" style "clearlooks-wide" +class "GtkToggleButton" style "clearlooks-toggle" +class "GtkRange" style "clearlooks-wide" +class "GtkFrame" style "clearlooks-wide" +class "GtkStatusbar" style "clearlooks-wide" +class "GtkMenu" style "clearlooks-menu" +class "GtkMenuItem" style "clearlooks-menu-item" +widget_class "*MenuItem.*" style "clearlooks-menu-item" +class "GtkEntry" style "clearlooks-wide" +widget_class "*.tooltip.*.GtkToggleButton" style "clearlooks-tasklist" +widget "gtk-tooltip" style "clearlooks-tooltips" +widget_class "*.GtkTreeView.GtkButton" style "clearlooks-tree" +widget_class "*.GtkCTree.GtkButton" style "clearlooks-tree" +widget_class "*.GtkList.GtkButton" style "clearlooks-tree" +widget_class "*.GtkCList.GtkButton" style "clearlooks-tree" +widget_class "*.GtkFrame.GtkLabel" style "clearlooks-frame-title" +widget_class "BasePWidget.GtkEventBox.GtkTable.GtkFrame" style "clearlooks-panel" +class "GtkNotebook" style "clearlooks-notebook" +class "GtkProgressBar" style "clearlooks-progressbar" +widget_class "*.GtkComboBox.GtkButton" style "clearlooks-combo" +widget_class "*.GtkCombo.GtkButton" style "clearlooks-combo" diff --git a/rtdata/themes/Default b/rtdata/themes/Default new file mode 100644 index 000000000..9693e0ba5 --- /dev/null +++ b/rtdata/themes/Default @@ -0,0 +1,170 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# + +# colour scheme by Bytec ( http://bytec.vitanet.lv ) +# based on the default gtkrc for +# rawtherapee ( http://www.rawtherapee.com ) +# which is based on Bluecurve +# Created by Richard Stellingwerff, Emil Jacobs and Daniel Borgmann. + + +style "clearlooks-default" +{ +font_name = "tahoma 8" + GtkButton ::default_border = { 0, 0, 0, 0 } + GtkRange ::trough_border = 0 + GtkPaned ::handle_size = 6 + GtkRange ::slider_width = 12 + GtkRange ::stepper_size = 12 + GtkScrollbar ::min_slider_length = 30 + GtkCheckButton ::indicator_size = 12 + GtkMenuBar ::internal-padding = 0 + GtkTreeView ::expander_size = 11 + GtkExpander ::expander_size = 11 + + xthickness = 1 + ythickness = 1 + + fg[NORMAL] = "#101010" + fg[PRELIGHT] = "#101010" + fg[ACTIVE] = "#000000" + fg[SELECTED] = "#999999" + fg[INSENSITIVE] = "#808080" + + bg[NORMAL] = "#808080" + bg[PRELIGHT] = "#999999" + bg[ACTIVE] = "#808080" + bg[SELECTED] = "#999999" + bg[INSENSITIVE] = "#808080" + + base[NORMAL] = "#999999" + base[PRELIGHT] = "#999999" + base[ACTIVE] = "#999999" + base[SELECTED] = "#606060" + base[INSENSITIVE] = "#808080" + + text[NORMAL] = "#000000" + text[PRELIGHT] = "#000000" + text[ACTIVE] = "#000000" + text[SELECTED] = "#000000" + text[INSENSITIVE] = "#000000" + + engine "clearlooks" { + sunkenmenubar = 1 # 0 = disable, 1 = enable + menuitemstyle = 0 # 0 = flat, 1 = 3d-ish (button) + listviewitemstyle = 0 # 0 = flat, 1 = 3d-ish (gradient) + progressbarstyle = 0 # 0 = candy bar, 1 = flat + } +} + +style "clearlooks-wide" = "clearlooks-default" +{ + xthickness = 1 + ythickness = 1 +} + +style "clearlooks-notebook" = "clearlooks-wide" +{ + bg[NORMAL] = "#808080" +} + +style "clearlooks-tasklist" = "clearlooks-default" +{ + xthickness = 5 + ythickness = 3 +} + +style "clearlooks-menu" = "clearlooks-default" +{ + xthickness = 2 + ythickness = 1 + bg[NORMAL] = "#808080" +} + +style "clearlooks-menu-item" = "clearlooks-default" +{ + xthickness = 1 + ythickness = 1 +} + +style "clearlooks-menu-itembar" = "clearlooks-default" +{ + xthickness = 1 + ythickness = 1 +} + +style "clearlooks-tree" = "clearlooks-default" +{ + xthickness = 1 + ythickness = 1 +} + +style "clearlooks-frame-title" = "clearlooks-default" +{ + fg[NORMAL] = "#404040" +} + +style "clearlooks-panel" = "clearlooks-default" +{ + xthickness = 3 + ythickness = 3 +} + +style "clearlooks-tooltips" = "clearlooks-default" +{ + xthickness = 4 + ythickness = 4 + bg[NORMAL] = { 1.0,1.0,0.75 } +} + +style "clearlooks-progressbar" = "clearlooks-default" +{ + xthickness = 1 + ythickness = 0 + + fg[PRELIGHT] = "#000000" +} + +style "clearlooks-combo" = "clearlooks-default" +{ + xthickness = 0 + ythickness = 0 +} + +class "GtkWidget" style "clearlooks-default" +class "GtkButton" style "clearlooks-wide" +class "GtkRange" style "clearlooks-wide" +class "GtkFrame" style "clearlooks-wide" +class "GtkStatusbar" style "clearlooks-wide" +class "GtkMenu" style "clearlooks-menu" +class "GtkMenuItem" style "clearlooks-menu-item" +widget_class "*MenuItem.*" style "clearlooks-menu-item" +class "GtkEntry" style "clearlooks-wide" +widget_class "*.tooltips.*.GtkToggleButton" style "clearlooks-tasklist" +widget_class "*.GtkTreeView.GtkButton" style "clearlooks-tree" +widget_class "*.GtkCTree.GtkButton" style "clearlooks-tree" +widget_class "*.GtkList.GtkButton" style "clearlooks-tree" +widget_class "*.GtkCList.GtkButton" style "clearlooks-tree" +widget_class "*.GtkFrame.GtkLabel" style "clearlooks-frame-title" +widget_class "BasePWidget.GtkEventBox.GtkTable.GtkFrame" style "clearlooks-panel" +widget "gtk-tooltip" style "clearlooks-tooltips" +class "GtkNotebook" style "clearlooks-notebook" +class "GtkProgressBar" style "clearlooks-progressbar" +widget_class "*.GtkComboBox.GtkButton" style "clearlooks-combo" +widget_class "*.GtkCombo.GtkButton" style "clearlooks-combo" diff --git a/rtdata/themes/Gray b/rtdata/themes/Gray new file mode 100644 index 000000000..12e794db5 --- /dev/null +++ b/rtdata/themes/Gray @@ -0,0 +1,244 @@ +# DarknessReturns GTK+ Theme for Clearlooks GTK Engine +# +# Created for CrunchBang Linux by Philip Newborough +# http://crunchbang.org/projects/linux/ +# Copyright (C) 2008 Philip Newborough (aka corenominal) + +# 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 . + +style "theme-default" { + + font_name = "tahoma 12" + + GtkButton ::default_border = { 0, 0, 0, 0 } + GtkRange ::trough_border = 1 + GtkPaned ::handle_size = 6 + GtkRange ::slider_width = 12 + GtkRange ::stepper_size = 12 + GtkScrollbar ::min_slider_length = 30 + GtkCheckButton ::indicator_size = 13 + GtkMenuBar ::internal-padding = 0 + GtkTreeView ::expander_size = 12 + GtkExpander ::expander_size = 12 + + xthickness = 1 + ythickness = 1 + + fg[NORMAL] = "#101010" + fg[PRELIGHT] = "#101010" + fg[ACTIVE] = "#31353A" + fg[SELECTED] = "#B2B2B2" + fg[INSENSITIVE] = "#9E9C9E" + + bg[NORMAL] = "#A1A1A1" + bg[PRELIGHT] = "#B2B2B2" + bg[ACTIVE] = "#B2B2B2" + bg[SELECTED] = "#31353A" + bg[INSENSITIVE] = "#B2B2B2" + + base[NORMAL] = "#B2B2B2" + base[PRELIGHT] = "#31353A" + base[SELECTED] = "#31353A" + base[INSENSITIVE] = "#fbf8f1" + base[ACTIVE] = "#31353A" + base[PRELIGHT] = "#729fcf" + + text[NORMAL] = "#101010" + text[PRELIGHT] = "#d0d0d0" + text[ACTIVE] = "#E2E2E2" + text[SELECTED] = "#E2E2E2" + text[INSENSITIVE] = "#E2E2E2" + + engine "clearlooks" { + menubarstyle = 0 + } +} + +style "theme-wide" = "theme-default" { + xthickness = 3 + ythickness = 3 +} + +style "theme-text" = "theme-default" { + #base[SELECTED] = "#fc9747" # Outline? +} + +style "theme-toolbar" = "theme-default" { + bg[NORMAL] = "#A1A1A1" +} + +style "theme-tasklist" = "theme-default" { + xthickness = 5 + ythickness = 3 +} + +style "theme-menu" = "theme-default" { + xthickness = 2 + ythickness = 2 + bg[NORMAL] = "#A1A1A1" +} + +style "theme-menu-item" = "theme-default" { + xthickness = 1 + ythickness = 1 + fg[PRELIGHT] = "#ffffff" + text[PRELIGHT] = "#ffffff" + base[PRELIGHT] = "#A1A1A1" +} + +style "theme-menu-itembar" = "theme-default" { + xthickness = 0 + ythickness = 0 +} + +style "theme-tree" = "theme-default" { + xthickness = 2 + ythickness = 2 + GtkTreeView::odd_row_color = "#f7f7ff" + GtkTreeView::even_row_color = "#ffffff" +} + +style "theme-frame-title" = "theme-default" { + fg[NORMAL] = "#2a2a2a" +} + +style "theme-panel" = "theme-default" { + xthickness = 3 + ythickness = 3 +} + +style "theme-tooltips" = "theme-default" { + xthickness = 4 + ythickness = 4 + bg[NORMAL] = { 1.0,1.0,0.75 } +} + +style "theme-progressbar" = "theme-default" { + xthickness = 1 + ythickness = 1 + fg[PRELIGHT] = "#ffffff" +} + +style "theme-combo" = "theme-default" { + xthickness = 2 + ythickness = 0 +} + +style "theme-button" = "theme-wide" { + xthickness = 1 + ythickness = 1 + #bg[NORMAL] = "#31353A" + #bg[PRELIGHT] = "#555555" + #bg[NORMAL] = "#31353A" +} +style "theme-check" = "theme-button" { +} + +style "theme-panel" = "theme-default" { + xthickness = 3 + ythickness = 3 +} + +style "theme-notebook" = "theme-wide" { + base[SELECTED] = "#A1A1A1" + bg[ACTIVE] = "#A1A1A1" + base[PRELIGHT] = "#A1A1A1" + bg[PRELIGHT] = "#A1A1A1" +} + +style "metacity-frame" { + bg[SELECTED] = "#5c82b5" +} + +style "theme-slab" = "theme-default" { + bg[SELECTED] = "#84b0da" + bg[NORMAL] = "#fdfbf7" + bg[ACTIVE] = "#e9eef5" + fg[NORMAL] = "#6a97c5" + fg[INSENSITIVE] = "#5c8dbf" +} + +style "theme-slab-group" = "theme-default" { + #bg[SELECTED] = "#adc09b" # Slab group text +} + +style "theme-shell" = "theme-default" { + bg[ACTIVE] = "#e9eef5" # Left side bg color + fg[NORMAL] = "#5c8dbf" # Left side text color + fg[INSENSITIVE] = "#bdcce1" # Left side line + + base[NORMAL] = "#fdfbf7" # Base bg color + text[INSENSITIVE] = "#6a97c5" # Base text color +} + +style "evolution-hack" = "clearlooks-default" { + bg[ACTIVE] = "#96b9d5" + bg[SELECTED] = "#6798cb" + fg[ACTIVE] = "#000000" + fg[SELECTED] = "#ffffff" +} + +style "theme-shell-highlight" = "theme-default" { +} + +style "extra-view" { + bg[NORMAL] = "#729fcf" + font = "Sans 6" +} + +style "rox" = "theme-default" { + bg[NORMAL] = "#ffffff" + bg[ACTIVE] = "#ffffff" + fg[NORMAL] = "#000000" + fg[ACTIVE] = "#000000" +} + +class "GtkWidget" style "theme-default" +class "GtkButton" style "theme-button" +class "GtkCombo" style "theme-button" +class "GtkRange" style "theme-wide" +class "GtkFrame" style "theme-wide" +class "GtkMenu" style "theme-menu" +class "GtkEntry" style "theme-button" +class "GtkMenuItem" style "theme-menu-item" +class "GtkStatusbar" style "theme-wide" +class "GtkNotebook" style "theme-notebook" +class "GtkProgressBar" style "theme-progressbar" +class "GtkCheckButton" style "theme-check" +class "GtkRadioButton" style "theme-check" + +widget_class "*MenuItem.*" style "theme-menu-item" +widget_class "*.GtkComboBox.GtkButton" style "theme-combo" +widget_class "*.GtkCombo.GtkButton" style "theme-combo" +widget_class "*.tooltips.*.GtkToggleButton" style "theme-tasklist" +widget "gtk-tooltip" style "theme-tooltips" +widget_class "*.GtkTreeView.GtkButton" style "theme-tree" +widget_class "*.GtkCTree.GtkButton" style "theme-tree" +widget_class "*.GtkList.GtkButton" style "theme-tree" +widget_class "*.GtkCList.GtkButton" style "theme-tree" +widget_class "*.GtkFrame.GtkLabel" style "theme-frame-title" +widget_class "*.GtkNotebook.*.GtkEventBox" style "theme-notebook" +widget_class "*.GtkNotebook.*.GtkViewport" style "theme-notebook" +class "MetaFrames" style "metacity-frame" +widget_class "BasePWidget.GtkEventBox.GtkTable.GtkFrame" style "theme-panel" +widget "*.nautilus-extra-view-widget" style:highest "extra-view" +class "SlabWindow" style "theme-slab" +class "ShellWindow" style "theme-shell" +widget_class "ShellWindow.*.GtkEventBox" style "theme-shell-highlight" +widget_class "*GtkCTree*" style "evolution-hack" +widget_class "*GtkList*" style "evolution-hack" +widget_class "*GtkCList*" style "evolution-hack" +widget_class "*.ETree.*" style "evolution-hack" +widget_class "*Collection*" style "rox" + diff --git a/rtdata/themes/Gray Textured b/rtdata/themes/Gray Textured new file mode 100644 index 000000000..10b359855 --- /dev/null +++ b/rtdata/themes/Gray Textured @@ -0,0 +1,591 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# + +# Textured gray theme. Based off of GM Looks (http://art.gnome.org/themes/gtk2/1163) and +# Cillop Midnite (http://art.gnome.org/themes/gtk2/1317), both of which are released under the GPL. +# Modified by Wyatt Olson. + +# Sneaking through the code are we.? ;) +style "clearlooks-default" +{ + GtkRange::trough_border = 0 + GtkRange::slider_width = 14 + GtkRange::stepper_size = 10 + + + + GtkMenuItem::selected_shadow_type = out + GtkWidget::interior_focus = 1 + GtkButton::default_border = { 1, 1, 1, 1 } + GtkButton::default_outside_border = { 0, 0, 0, 0 } + GtkRange::trough_border = 0 + GtkWidget::focus_padding = 1 + GtkPaned::handle_size = 6 + GtkRange::slider_width = 15 + GtkRange::stepper_size = 15 + GtkScrollbar::min_slider_length = 30 + GtkCheckButton::indicator_size = 12 + GtkMenuBar::internal-padding = 0 + #GtkOptionMenu::indicator_size = { 11, 6 } + #GtkOptionMenu::indicator_spacing = { 4, 5, 2, 2 } + GtkTreeView::expander_size = 14 + GtkExpander::expander_size = 16 + xthickness = 1 + ythickness = 1 + + fg[NORMAL] = "#CACAC6" + fg[ACTIVE] = "#CACAC6" + fg[INSENSITIVE] = "#000000" + fg[PRELIGHT] = "#E2E2E2" + fg[SELECTED] = "#E2E2E2" + + bg[ACTIVE] = "#484949" + bg[NORMAL] = "#5f5f5f" + bg[INSENSITIVE] = "#505050" + bg[PRELIGHT] = "#6A6C6F" + bg[SELECTED] = "#797979" + + base[NORMAL] = "#646464" + base[ACTIVE] = "#797979" + base[INSENSITIVE] = "#5f5f5f" + base[PRELIGHT] = "#686868" + base[SELECTED] = "#797979" + + text[NORMAL] = "#000000" + text[ACTIVE] = "#000000" + text[PRELIGHT] = "#000000" + text[SELECTED] = "#d7d4c9" + text[INSENSITIVE] = "#777777" + + engine "clearlooks" + { + contrast = 1.1 + menubarstyle = 2 + animation = TRUE + #menuitemstyle = 2 + #progressbarstyle = 0 + style = CLASSIC + } +} + +style "clearlooks-wide" = "clearlooks-default" +{ + xthickness = 2 + ythickness = 2 +} + +style "clearlooks-notebook" = "clearlooks-wide" +{ + bg[NORMAL] = "#5f5f5f" +} +style "clearlooks-tasklist" = "clearlooks-default" +{ + xthickness = 5 + ythickness = 3 +} + +style "clearlooks-menu" = "clearlooks-default" +{ + xthickness = 2 + ythickness = 1 +} + +style "clearlooks-menu-item" = "clearlooks-default" +{ + xthickness = 2 + ythickness = 3 +} + +style "clearlooks-menu-itembar" = "clearlooks-default" +{ + xthickness = 3 + ythickness = 3 +} +style "clearlooks-tree" = "clearlooks-default" +{ + xthickness = 2 + ythickness = 2 +} + +style "clearlooks-frame-title" = "clearlooks-default" +{ + fg[NORMAL] = "#FFFFFF" +} + +style "clearlooks-panel" = "clearlooks-default" +{ + xthickness = 3 + ythickness = 3 +} + +style "clearlooks-tooltips" = "clearlooks-default" +{ + xthickness = 4 + ythickness = 4 + bg[NORMAL] = "#404040" +} +style "clearlooks-progressbar" = "clearlooks-default" +{ + xthickness = 0 + ythickness = 0 + fg[PRELIGHT] = "#000000" +} + +style "clearlooks-combo" = "clearlooks-default" +{ + xthickness = 1 + ythickness = 2 +} + +style "metacity-frame" +{ + # Normal base color + #bg[NORMAL] = "#bbbbbb" + + # Unfocused title background color + #bg[INSENSITIVE] = { 0.8, 0.8, 0.8 } + + # Unfocused title text color + #fg[INSENSITIVE] = { 1.55, 1.55, 1.55 } + + # Focused icon color + #fg[NORMAL] = { 0.2, 0.2, 0.2 } + + # Focused title background color + #bg[SELECTED] = { 0.5, 0.8, 0.5 } + + # Focused title text color + #fg[SELECTED] = "black" +} +style "clearlooks-scale" = "clearooks-button" +{ + GtkRange::trough-side-details = 1 +} + + + +style "scrollbar" = "clearlooks-default" +{ + + engine "pixmap" + { + image + { + function = BOX + detail = "trough" + file = "gray_textured/trough2.png" + border = { 6,6,6,6 } + stretch = TRUE + orientation = VERTICAL + } + image + { + function = BOX + detail = "trough" + file = "gray_textured/trough2-h.png" + border = { 6,6,6,6 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = SLIDER + state = NORMAL + file = "gray_textured/slider-h.png" + border = { 6,6,2,2 } + stretch = TRUE + orientation = HORIZONTAL + + + + } + image + { + function = SLIDER + state = PRELIGHT + file = "gray_textured/slider-h-pre.png" + border = { 6,6,2,2 } + stretch = TRUE + orientation = HORIZONTAL + + } + image + { + function = SLIDER + state = INSENSITIVE + file = "gray_textured/slider-h-ins.png" + border = { 6,6,2,2 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = SLIDER + state = NORMAL + file = "gray_textured/slider-v.png" + border = { 2, 2, 6, 6 } + stretch = TRUE + orientation = VERTICAL + + + + } + image + { + function = SLIDER + state = PRELIGHT + file = "gray_textured/slider-v-pre.png" + border = { 2, 2, 6, 6 } + stretch = TRUE + orientation = VERTICAL + + + } + image + { + function = SLIDER + state = INSENSITIVE + file = "gray_textured/slider-v-ins.png" + border = { 2,2,6,6 } + stretch = TRUE + orientation = VERTICAL + + } + image + { + function = STEPPER + state = NORMAL + file = "gray_textured/null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = UP + overlay_file = "gray_textured/arrow-up.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = PRELIGHT + file = "gray_textured/null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = UP + overlay_file = "gray_textured/arrow-up-pre.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = ACTIVE + file = "gray_textured/null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = UP + overlay_file = "gray_textured/arrow-up.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = INSENSITIVE + file = "gray_textured/null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = UP + overlay_file = "gray_textured/arrow-up-ins.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = NORMAL + file = "gray_textured/null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = DOWN + overlay_file = "gray_textured/arrow-down.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = PRELIGHT + file = "gray_textured/null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = DOWN + overlay_file = "gray_textured/arrow-down-pre.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = ACTIVE + file = "gray_textured/null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = DOWN + overlay_file = "gray_textured/arrow-down.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = INSENSITIVE + file = "gray_textured/null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = DOWN + overlay_file = "gray_textured/arrow-down-ins.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = NORMAL + file = "gray_textured/null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = RIGHT + overlay_file = "gray_textured/arrow-right.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = PRELIGHT + file = "gray_textured/null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = RIGHT + overlay_file = "gray_textured/arrow-right-pre.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = ACTIVE + file = "gray_textured/null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = RIGHT + overlay_file = "gray_textured/arrow-right.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = INSENSITIVE + file = "gray_textured/null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = RIGHT + overlay_file = "gray_textured/arrow-right-ins.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = NORMAL + file = "gray_textured/null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = LEFT + overlay_file = "gray_textured/arrow-left.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = PRELIGHT + file = "gray_textured/null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = LEFT + overlay_file = "gray_textured/arrow-left-pre.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = ACTIVE + file = "gray_textured/null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = LEFT + overlay_file = "gray_textured/arrow-left.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = INSENSITIVE + file = "gray_textured/null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = LEFT + overlay_file = "gray_textured/arrow-left-ins.png" + overlay_stretch = FALSE + } + } +} + + +style "range" = "clearlooks-default" +{ + engine "pixmap" + { +# image +# { +# function = FOCUS +# file = "gray_textured/null.png" +# stretch = TRUE +# } + image + { + function = BOX + detail = "trough" + file = "gray_textured/pbtroughh.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = BOX + detail = "trough" + file = "gray_textured/pbtroughv.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = VERTICAL + } + image + { + function = SLIDER + state = NORMAL + file = "gray_textured/rangeslider.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = HORIZONTAL + + } + image + { + function = SLIDER + state = PRELIGHT + file = "gray_textured/rangeslider-pre.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = HORIZONTAL + + } + image + { + function = SLIDER + state = ACTIVE + file = "gray_textured/rangeslider-pre.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = HORIZONTAL + + } + image + { + function = SLIDER + state = INSENSITIVE + file = "gray_textured/rangeslider-ins.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = HORIZONTAL + + } + image + { + function = SLIDER + state = NORMAL + file = "gray_textured/rangeslider.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = VERTICAL + + } + image + { + function = SLIDER + state = PRELIGHT + file = "gray_textured/rangeslider-pre.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = VERTICAL + + } + image + { + function = SLIDER + state = ACTIVE + file = "gray_textured/rangeslider-pre.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = VERTICAL + + } + image + { + function = SLIDER + state = INSENSITIVE + file = "gray_textured/rangeslider-ins.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = VERTICAL + + } + } +} + +class "GtkWidget" style "clearlooks-default" +class "GtkButton" style "clearlooks-wide" +class "GtkRange" style "clearlooks-wide" +class "GtkFrame" style "clearlooks-wide" +class "GtkStatusbar" style "clearlooks-wide" +class "GtkMenu" style "clearlooks-menu" +class "GtkMenuItem" style "clearlooks-menu-item" +widget_class "*.GtkMenuItem.*" style "clearlooks-menu-item" +widget_class "*.GtkAccelMenuItem.*" style "clearlooks-menu-item" +widget_class "*.GtkRadioMenuItem.*" style "clearlooks-menu-item" +widget_class "*.GtkCheckMenuItem.*" style "clearlooks-menu-item" +widget_class "*.GtkImageMenuItem.*" style "clearlooks-menu-item" +widget_class "*.GtkSeparatorMenuItem.*" style "clearlooks-menu-item" +class "GtkEntry" style "clearlooks-wide" +widget_class "*.tooltips.*.GtkToggleButton" style "clearlooks-tasklist" +widget_class "*.GtkTreeView.GtkButton" style "clearlooks-tree" +widget_class "*.GtkCTree.GtkButton" style "clearlooks-tree" +widget_class "*.GtkList.GtkButton" style "clearlooks-tree" +widget_class "*.GtkCList.GtkButton" style "clearlooks-tree" +widget_class "*.GtkFrame.GtkLabel" style "clearlooks-frame-title" +widget_class "BasePWidget.GtkEventBox.GtkTable.GtkFrame" style "clearlooks-panel" +widget "gtk-tooltips" style "clearlooks-tooltips" +class "GtkNotebook" style "clearlooks-notebook" +class "GtkProgressBar" style "clearlooks-progressbar" +widget_class "*.GtkComboBox.GtkButton" style "clearlooks-combo" +widget_class "*.GtkCombo.GtkButton" style "clearlooks-combo" +class "MetaFrames" style "metacity-frame" + + +class "GtkScrollbar" style "scrollbar" +class "GtkRange" style "range" diff --git a/rtdata/themes/Light b/rtdata/themes/Light new file mode 100644 index 000000000..92064a2a2 --- /dev/null +++ b/rtdata/themes/Light @@ -0,0 +1,169 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2010 Gabor Horvath +# +# RawTherapee 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. +# +# RawTherapee 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 RawTherapee. If not, see . +# + +# Based on Bluecurve +# Created by Richard Stellingwerff, Emil Jacobs and Daniel Borgmann. + + +style "clearlooks-default" +{ +font_name = "sans 8" + GtkButton ::default_border = { 0, 0, 0, 0 } + GtkRange ::trough_border = 0 + GtkPaned ::handle_size = 6 + GtkRange ::slider_width = 12 + GtkRange ::stepper_size = 12 + GtkScrollbar ::min_slider_length = 30 + GtkCheckButton ::indicator_size = 12 + GtkMenuBar ::internal-padding = 0 + GtkTreeView ::expander_size = 11 + GtkExpander ::expander_size = 11 + + xthickness = 1 + ythickness = 1 + + fg[NORMAL] = "#101010" # very dark gray #101010 + fg[PRELIGHT] = "#101010" # dark grey + fg[ACTIVE] = "#000000" # black + fg[SELECTED] = "#ffffff" # white + fg[INSENSITIVE] = "#b5b3ac" # dark beige / grey + + bg[NORMAL] = "#efebe7" # light beige / grey + bg[PRELIGHT] = "#f5f3f0" # very light beige + bg[ACTIVE] = "#d4cfca" # mid beige / grey + bg[SELECTED] = "#7c99ad" # blueish + bg[INSENSITIVE] = "#efebe7" # light beige / grey + + base[NORMAL] = "#ffffff" # white + base[PRELIGHT] = "#7c99ad" # blueish + base[ACTIVE] = "#a29e8e" # dark beige / grey + base[SELECTED] = "#7c99ad" # blueish + base[INSENSITIVE] = "#efebe7" #light beige / grey + + text[NORMAL] = "#000000" # black + text[PRELIGHT] = "#000000" # black + text[ACTIVE] = "#ffffff" # white + text[SELECTED] = "#ffffff" # white + text[INSENSITIVE] = "#b5b3ac" # dark beige / grey + + engine "clearlooks" { + sunkenmenubar = 1 # 0 = disable, 1 = enable + menuitemstyle = 0 # 0 = flat, 1 = 3d-ish (button) + listviewitemstyle = 0 # 0 = flat, 1 = 3d-ish (gradient) + progressbarstyle = 0 # 0 = candy bar, 1 = flat + } +} + +style "clearlooks-wide" = "clearlooks-default" +{ + xthickness = 1 + ythickness = 1 +} + +style "clearlooks-notebook" = "clearlooks-wide" +{ + bg[NORMAL] = "#eae4df" +} + +style "clearlooks-tasklist" = "clearlooks-default" +{ + xthickness = 5 + ythickness = 3 +} + +style "clearlooks-menu" = "clearlooks-default" +{ + xthickness = 2 + ythickness = 1 + bg[NORMAL] = "#f8f5f2" +} + +style "clearlooks-menu-item" = "clearlooks-default" +{ + xthickness = 1 + ythickness = 1 + fg[PRELIGHT] = "#ffffff" + text[PRELIGHT] = "#ffffff" +} + +style "clearlooks-menu-itembar" = "clearlooks-default" +{ + xthickness = 1 + ythickness = 1 +} + +style "clearlooks-tree" = "clearlooks-default" +{ + xthickness = 1 + ythickness = 1 +} + +style "clearlooks-frame-title" = "clearlooks-default" +{ + fg[NORMAL] = "#404040" +} + +style "clearlooks-panel" = "clearlooks-default" +{ + xthickness = 3 + ythickness = 3 +} + +style "clearlooks-tooltips" = "clearlooks-default" +{ + xthickness = 4 + ythickness = 4 + bg[NORMAL] = { 1.0,1.0,0.75 } +} + +style "clearlooks-progressbar" = "clearlooks-default" +{ + xthickness = 1 + ythickness = 0 + + fg[PRELIGHT] = "#ffffff" +} + +style "clearlooks-combo" = "clearlooks-default" +{ + xthickness = 1 + ythickness = 1 +} + +class "GtkWidget" style "clearlooks-default" +class "GtkButton" style "clearlooks-wide" +class "GtkRange" style "clearlooks-wide" +class "GtkFrame" style "clearlooks-wide" +class "GtkStatusbar" style "clearlooks-wide" +class "GtkMenu" style "clearlooks-menu" +class "GtkMenuItem" style "clearlooks-menu-item" +widget_class "*MenuItem.*" style "clearlooks-menu-item" +class "GtkEntry" style "clearlooks-wide" +widget_class "*.tooltips.*.GtkToggleButton" style "clearlooks-tasklist" +widget_class "*.GtkTreeView.GtkButton" style "clearlooks-tree" +widget_class "*.GtkCTree.GtkButton" style "clearlooks-tree" +widget_class "*.GtkList.GtkButton" style "clearlooks-tree" +widget_class "*.GtkCList.GtkButton" style "clearlooks-tree" +widget_class "*.GtkFrame.GtkLabel" style "clearlooks-frame-title" +widget_class "BasePWidget.GtkEventBox.GtkTable.GtkFrame" style "clearlooks-panel" +widget "gtk-tooltip" style "clearlooks-tooltips" +class "GtkNotebook" style "clearlooks-notebook" +class "GtkProgressBar" style "clearlooks-progressbar" +widget_class "*.GtkComboBox.GtkButton" style "clearlooks-combo" +widget_class "*.GtkCombo.GtkButton" style "clearlooks-combo" diff --git a/rtdata/themes/gray_textured/arrow-down-ins.png b/rtdata/themes/gray_textured/arrow-down-ins.png new file mode 100644 index 000000000..c1fc48af4 Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-down-ins.png differ diff --git a/rtdata/themes/gray_textured/arrow-down-pre.png b/rtdata/themes/gray_textured/arrow-down-pre.png new file mode 100644 index 000000000..16b653ca4 Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-down-pre.png differ diff --git a/rtdata/themes/gray_textured/arrow-down.png b/rtdata/themes/gray_textured/arrow-down.png new file mode 100644 index 000000000..607743404 Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-down.png differ diff --git a/rtdata/themes/gray_textured/arrow-left-ins.png b/rtdata/themes/gray_textured/arrow-left-ins.png new file mode 100644 index 000000000..3e9322bfd Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-left-ins.png differ diff --git a/rtdata/themes/gray_textured/arrow-left-pre.png b/rtdata/themes/gray_textured/arrow-left-pre.png new file mode 100644 index 000000000..9e8cbb8b3 Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-left-pre.png differ diff --git a/rtdata/themes/gray_textured/arrow-left.png b/rtdata/themes/gray_textured/arrow-left.png new file mode 100644 index 000000000..ae6343824 Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-left.png differ diff --git a/rtdata/themes/gray_textured/arrow-right-ins.png b/rtdata/themes/gray_textured/arrow-right-ins.png new file mode 100644 index 000000000..0b3fd93bc Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-right-ins.png differ diff --git a/rtdata/themes/gray_textured/arrow-right-pre.png b/rtdata/themes/gray_textured/arrow-right-pre.png new file mode 100644 index 000000000..5f766898a Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-right-pre.png differ diff --git a/rtdata/themes/gray_textured/arrow-right.png b/rtdata/themes/gray_textured/arrow-right.png new file mode 100644 index 000000000..71a7856b5 Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-right.png differ diff --git a/rtdata/themes/gray_textured/arrow-up-ins.png b/rtdata/themes/gray_textured/arrow-up-ins.png new file mode 100644 index 000000000..e518dea63 Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-up-ins.png differ diff --git a/rtdata/themes/gray_textured/arrow-up-pre.png b/rtdata/themes/gray_textured/arrow-up-pre.png new file mode 100644 index 000000000..6c669a3c7 Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-up-pre.png differ diff --git a/rtdata/themes/gray_textured/arrow-up.png b/rtdata/themes/gray_textured/arrow-up.png new file mode 100644 index 000000000..7444ff414 Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-up.png differ diff --git a/rtdata/themes/gray_textured/button-insensitive.png b/rtdata/themes/gray_textured/button-insensitive.png new file mode 100644 index 000000000..9acefb9a4 Binary files /dev/null and b/rtdata/themes/gray_textured/button-insensitive.png differ diff --git a/rtdata/themes/gray_textured/button-normal.png b/rtdata/themes/gray_textured/button-normal.png new file mode 100644 index 000000000..b5122eab5 Binary files /dev/null and b/rtdata/themes/gray_textured/button-normal.png differ diff --git a/rtdata/themes/gray_textured/button-normal.xcf b/rtdata/themes/gray_textured/button-normal.xcf new file mode 100644 index 000000000..6b2b2ddb0 Binary files /dev/null and b/rtdata/themes/gray_textured/button-normal.xcf differ diff --git a/rtdata/themes/gray_textured/button-prelight.png b/rtdata/themes/gray_textured/button-prelight.png new file mode 100644 index 000000000..2c51eccfe Binary files /dev/null and b/rtdata/themes/gray_textured/button-prelight.png differ diff --git a/rtdata/themes/gray_textured/button-pressed.png b/rtdata/themes/gray_textured/button-pressed.png new file mode 100644 index 000000000..553988888 Binary files /dev/null and b/rtdata/themes/gray_textured/button-pressed.png differ diff --git a/rtdata/themes/gray_textured/null.png b/rtdata/themes/gray_textured/null.png new file mode 100644 index 000000000..7b58b30ab Binary files /dev/null and b/rtdata/themes/gray_textured/null.png differ diff --git a/rtdata/themes/gray_textured/pbtroughh.png b/rtdata/themes/gray_textured/pbtroughh.png new file mode 100644 index 000000000..37cd0e3bf Binary files /dev/null and b/rtdata/themes/gray_textured/pbtroughh.png differ diff --git a/rtdata/themes/gray_textured/pbtroughv.png b/rtdata/themes/gray_textured/pbtroughv.png new file mode 100644 index 000000000..6a547b608 Binary files /dev/null and b/rtdata/themes/gray_textured/pbtroughv.png differ diff --git a/rtdata/themes/gray_textured/rangeslider-ins.png b/rtdata/themes/gray_textured/rangeslider-ins.png new file mode 100644 index 000000000..03384cdd7 Binary files /dev/null and b/rtdata/themes/gray_textured/rangeslider-ins.png differ diff --git a/rtdata/themes/gray_textured/rangeslider-pre.png b/rtdata/themes/gray_textured/rangeslider-pre.png new file mode 100644 index 000000000..cc920d387 Binary files /dev/null and b/rtdata/themes/gray_textured/rangeslider-pre.png differ diff --git a/rtdata/themes/gray_textured/rangeslider.png b/rtdata/themes/gray_textured/rangeslider.png new file mode 100644 index 000000000..5cdb73d5b Binary files /dev/null and b/rtdata/themes/gray_textured/rangeslider.png differ diff --git a/rtdata/themes/gray_textured/slider-h-ins.png b/rtdata/themes/gray_textured/slider-h-ins.png new file mode 100644 index 000000000..6776a75ea Binary files /dev/null and b/rtdata/themes/gray_textured/slider-h-ins.png differ diff --git a/rtdata/themes/gray_textured/slider-h-pre.png b/rtdata/themes/gray_textured/slider-h-pre.png new file mode 100644 index 000000000..fdead8b3a Binary files /dev/null and b/rtdata/themes/gray_textured/slider-h-pre.png differ diff --git a/rtdata/themes/gray_textured/slider-h.png b/rtdata/themes/gray_textured/slider-h.png new file mode 100644 index 000000000..000477c64 Binary files /dev/null and b/rtdata/themes/gray_textured/slider-h.png differ diff --git a/rtdata/themes/gray_textured/slider-v-ins.png b/rtdata/themes/gray_textured/slider-v-ins.png new file mode 100644 index 000000000..d4523da69 Binary files /dev/null and b/rtdata/themes/gray_textured/slider-v-ins.png differ diff --git a/rtdata/themes/gray_textured/slider-v-pre.png b/rtdata/themes/gray_textured/slider-v-pre.png new file mode 100644 index 000000000..3fc22aace Binary files /dev/null and b/rtdata/themes/gray_textured/slider-v-pre.png differ diff --git a/rtdata/themes/gray_textured/slider-v.png b/rtdata/themes/gray_textured/slider-v.png new file mode 100644 index 000000000..ecb505c7f Binary files /dev/null and b/rtdata/themes/gray_textured/slider-v.png differ diff --git a/rtdata/themes/gray_textured/trough2-h.png b/rtdata/themes/gray_textured/trough2-h.png new file mode 100644 index 000000000..b92e4c236 Binary files /dev/null and b/rtdata/themes/gray_textured/trough2-h.png differ diff --git a/rtdata/themes/gray_textured/trough2.png b/rtdata/themes/gray_textured/trough2.png new file mode 100644 index 000000000..309b487b4 Binary files /dev/null and b/rtdata/themes/gray_textured/trough2.png differ diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt new file mode 100644 index 000000000..f27265f7a --- /dev/null +++ b/rtengine/CMakeLists.txt @@ -0,0 +1,25 @@ + +include_directories (${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../rtexif + ${EXTRA_INCDIR} ${GTHREAD_INCLUDE_DIRS} ${GOBJECT_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIRS} + ${GLIBMM_INCLUDE_DIRS} ${IPTCDATA_INCLUDE_DIRS} ${LCMS_INCLUDE_DIRS}) +link_directories (${CMAKE_CURRENT_SOURCE_DIR}/../rtexif ${EXTRA_LIBDIR} ${GTHREAD_LIBRARY_DIRS} + ${GOBJECT_LIBRARY_DIRS} ${GLIB2_LIBRARY_DIRS} ${GLIBMM_LIBRARY_DIRS} + ${IPTCDATA_LIBRARY_DIRS} ${LCMS_LIBRARY_DIRS}) + +set (RTENGINESOURCEFILES colortemp.cc curves.cc dcraw.cc gauss.cc iccstore.cc + image8.cc image16.cc imagedata.cc imageio.cc improcfun.cc init.cc dcrop.cc + loadinitial.cc procparams.cc rawimagesource.cc shmap.cc simpleprocess.cc refreshmap.cc + stdimagesource.cc myfile.cc iccjpeg.c hlmultipliers.cc improccoordinator.cc + processingjob.cc rtthumbnail.cc utils.cc bilateral2.cc) + +add_library (rtengine ${RTENGINESOURCEFILES}) +#It may be nice to store library version too +IF (BUILD_SHARED_LIBS) + install (TARGETS rtengine DESTINATION ${LIBDIR}) +ENDIF (BUILD_SHARED_LIBS) + +set_target_properties (rtengine PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} -ffast-math -funroll-loops") + +target_link_libraries (rtengine rtexif ${EXTRA_LIB} ${GOBJECT_LIBRARIES} ${GTHREAD_LIBRARIES} + ${GLIB2_LIBRARIES} ${GLIBMM_LIBRARIES} ${LCMS_LIBRARIES} ${IPTCDATA_LIBRARIES} + ${JPEG_LIBRARIES} ${PNG_LIBRARIES} ${TIFF_LIBRARIES} ${ZLIB_LIBRARIES}) diff --git a/rtengine/Doxyfile b/rtengine/Doxyfile new file mode 100644 index 000000000..5eb3c98fc --- /dev/null +++ b/rtengine/Doxyfile @@ -0,0 +1,1356 @@ +# Doxyfile 1.5.5 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = RawTherapee Image Processing Engine (RIPE) + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1.0 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, +# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, +# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, +# and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is enabled by default, which results in a transparent +# background. Warning: Depending on the platform used, enabling this option +# may lead to badly anti-aliased labels on the edges of a graph (i.e. they +# become hard to read). + +DOT_TRANSPARENT = YES + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/rtengine/alignedbuffer.h b/rtengine/alignedbuffer.h new file mode 100644 index 000000000..4eabe5665 --- /dev/null +++ b/rtengine/alignedbuffer.h @@ -0,0 +1,40 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _ALIGNEDBUFFER_ +#define _ALIGNEDBUFFER_ + +template class AlignedBuffer { + + private: + T* real ; + + public: + T* data ; + + AlignedBuffer (int size, int align=16) { + real = new T[size+2*align]; + data = (T*)((long)real + (align-((long)real)%align)); + } + + ~AlignedBuffer () { + delete [] real; + } +}; + +#endif diff --git a/rtengine/bilateral2.cc b/rtengine/bilateral2.cc new file mode 100644 index 000000000..956f661e4 --- /dev/null +++ b/rtengine/bilateral2.cc @@ -0,0 +1,35 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include + +void bilateral_unsigned (unsigned short** src, unsigned short** dst, unsigned short** buffer, Dim dim, double sigma, double sens) { + + bilateral (src, dst, buffer, dim, sigma, sens); +} + +void bilateral_signed (short** src, short** dst, short** buffer, Dim dim, double sigma, double sens) { + + bilateral (src, dst, buffer, dim, sigma, sens); +} + +void bilateral_box_unsigned (unsigned short** src, unsigned short** dst, int W, int H, int sigmar, double sigmas, bilateralparams row) { + + bilateral (src, dst, W, H, sigmar, sigmas, row.row_from, row.row_to); +} + diff --git a/rtengine/bilateral2.h b/rtengine/bilateral2.h new file mode 100644 index 000000000..a4fa0d55e --- /dev/null +++ b/rtengine/bilateral2.h @@ -0,0 +1,748 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _BILATERAL2_ +#define _BILATERAL2_ + +#include +#include +#include +#include +#include +#include +#include + +#define ELEM(a,b) (src[i - a][j - b] * ec[src[i - a][j - b]-src[i][j]+0x10000]) +#define SULY(a,b) (ec[src[i - a][j - b]-src[i][j]+0x10000]) + +#define BL_BEGIN(a,b) double scale = (a); \ + int* ec = new int [0x20000]; \ + for (int i=0; i<0x20000; i++) \ + ec[i] = (int)(exp(-(double)(i-0x10000)*(double)(i-0x10000) / (2.0*sens*sens))*scale); \ + int start = row_from; \ + if (start<(b)) start = (b); \ + int end = row_to; \ + if (end>H-(b)) end = H-(b); \ + for (int i=start; i=end || j>=W-(b)) \ + dst[i][j] = src[i][j]; \ + else \ + dst[i][j] = buffer[i][j]; + +#define BL_OPER3(a11,a12,a21,a22) A v = a11*ELEM(-1,-1) + a12*ELEM(-1,0) + a11*ELEM(-1,1) + \ + a21*ELEM(0,-1) + a22*ELEM(0,0) + a21*ELEM(0,1) + \ + a11*ELEM(1,-1) + a12*ELEM(1,0) + a11*ELEM(1,1); \ + v /= a11*SULY(-1,-1) + a12*SULY(-1,0) + a11*SULY(-1,1) + \ + a21*SULY(0,-1) + a22*SULY(0,0) + a21*SULY(0,1) + \ + a11*SULY(1,-1) + a12*SULY(1,0) + a11*SULY(1,1); + + +#define BL_OPER5(a11,a12,a13,a21,a22,a23,a31,a32,a33) A v = a11*ELEM(-2,-2) + a12*ELEM(-2,-1) + a13*ELEM(-2,0) + a12*ELEM(-2,1) + a11*ELEM(-2,2) + \ + a21*ELEM(-1,-2) + a22*ELEM(-1,-1) + a23*ELEM(-1,0) + a22*ELEM(-1,1) + a21*ELEM(-1,2) + \ + a31*ELEM(0,-2) + a32*ELEM(0,-1) + a33*ELEM(0,0) + a32*ELEM(0,1) + a31*ELEM(0,2) + \ + a21*ELEM(1,-2) + a22*ELEM(1,-1) + a23*ELEM(1,0) + a22*ELEM(1,1) + a21*ELEM(1,2) + \ + a11*ELEM(2,-2) + a12*ELEM(2,-1) + a13*ELEM(2,0) + a12*ELEM(2,1) + a11*ELEM(2,2); \ + v /= a11*SULY(-2,-2) + a12*SULY(-2,-1) + a13*SULY(-2,0) + a12*SULY(-2,1) + a11*SULY(-2,2) + \ + a21*SULY(-1,-2) + a22*SULY(-1,-1) + a23*SULY(-1,0) + a22*SULY(-1,1) + a21*SULY(-1,2) + \ + a31*SULY(0,-2) + a32*SULY(0,-1) + a33*SULY(0,0) + a32*SULY(0,1) + a31*SULY(0,2) + \ + a21*SULY(1,-2) + a22*SULY(1,-1) + a23*SULY(1,0) + a22*SULY(1,1) + a21*SULY(1,2) + \ + a11*SULY(2,-2) + a12*SULY(2,-1) + a13*SULY(2,0) + a12*SULY(2,1) + a11*SULY(2,2); + +#define BL_OPER7(a11,a12,a13,a14,a21,a22,a23,a24,a31,a32,a33,a34,a41,a42,a43,a44) \ + A v = a11*ELEM(-3,-3) + a12*ELEM(-3,-2) + a13*ELEM(-3,-1) + a14*ELEM(-3,0) + a13*ELEM(-3,1) + a12*ELEM(-3,2) + a11*ELEM(-3,3) + \ + a21*ELEM(-2,-3) + a22*ELEM(-2,-2) + a23*ELEM(-2,-1) + a24*ELEM(-2,0) + a23*ELEM(-2,1) + a22*ELEM(-2,2) + a21*ELEM(-2,3) + \ + a31*ELEM(-1,-3) + a32*ELEM(-1,-2) + a33*ELEM(-1,-1) + a34*ELEM(-1,0) + a33*ELEM(-1,1) + a32*ELEM(-1,2) + a31*ELEM(-1,3) + \ + a41*ELEM(0,-3) + a42*ELEM(0,-2) + a43*ELEM(0,-1) + a44*ELEM(0,0) + a43*ELEM(0,1) + a42*ELEM(0,2) + a41*ELEM(0,3) + \ + a31*ELEM(1,-3) + a32*ELEM(1,-2) + a33*ELEM(1,-1) + a34*ELEM(1,0) + a33*ELEM(1,1) + a32*ELEM(1,2) + a31*ELEM(1,3) + \ + a21*ELEM(2,-3) + a22*ELEM(2,-2) + a23*ELEM(2,-1) + a24*ELEM(2,0) + a23*ELEM(2,1) + a22*ELEM(2,2) + a21*ELEM(2,3) + \ + a11*ELEM(3,-3) + a12*ELEM(3,-2) + a13*ELEM(3,-1) + a14*ELEM(3,0) + a13*ELEM(3,1) + a12*ELEM(3,2) + a11*ELEM(3,3); \ + v /= a11*SULY(-3,-3) + a12*SULY(-3,-2) + a13*SULY(-3,-1) + a14*SULY(-3,0) + a13*SULY(-3,1) + a12*SULY(-3,2) + a11*SULY(-3,3) + \ + a21*SULY(-2,-3) + a22*SULY(-2,-2) + a23*SULY(-2,-1) + a24*SULY(-2,0) + a23*SULY(-2,1) + a22*SULY(-2,2) + a21*SULY(-2,3) + \ + a31*SULY(-1,-3) + a32*SULY(-1,-2) + a33*SULY(-1,-1) + a34*SULY(-1,0) + a33*SULY(-1,1) + a32*SULY(-1,2) + a31*SULY(-1,3) + \ + a41*SULY(0,-3) + a42*SULY(0,-2) + a43*SULY(0,-1) + a44*SULY(0,0) + a43*SULY(0,1) + a42*SULY(0,2) + a41*SULY(0,3) + \ + a31*SULY(1,-3) + a32*SULY(1,-2) + a33*SULY(1,-1) + a34*SULY(1,0) + a33*SULY(1,1) + a32*SULY(1,2) + a31*SULY(1,3) + \ + a21*SULY(2,-3) + a22*SULY(2,-2) + a23*SULY(2,-1) + a24*SULY(2,0) + a23*SULY(2,1) + a22*SULY(2,2) + a21*SULY(2,3) + \ + a11*SULY(3,-3) + a12*SULY(3,-2) + a13*SULY(3,-1) + a14*SULY(3,0) + a13*SULY(3,1) + a12*SULY(3,2) + a11*SULY(3,3); + + +#define BL_OPER9(a11,a12,a13,a14,a15,a21,a22,a23,a24,a25,a31,a32,a33,a34,a35,a41,a42,a43,a44,a45,a51,a52,a53,a54,a55) \ + A v = a11*ELEM(-4,-4) + a12*ELEM(-4,-3) + a13*ELEM(-4,-2) + a14*ELEM(-4,-1) + a15*ELEM(-4,0) + a14*ELEM(-4,1) + a13*ELEM(-4,2) + a12*ELEM(-4,3) + a11*ELEM(-4,4) + \ + a21*ELEM(-3,-4) + a22*ELEM(-3,-3) + a23*ELEM(-3,-2) + a24*ELEM(-3,-1) + a25*ELEM(-3,0) + a24*ELEM(-3,1) + a23*ELEM(-3,2) + a22*ELEM(-3,3) + a21*ELEM(-3,4) + \ + a31*ELEM(-2,-4) + a32*ELEM(-2,-3) + a33*ELEM(-2,-2) + a34*ELEM(-2,-1) + a35*ELEM(-2,0) + a34*ELEM(-2,1) + a33*ELEM(-2,2) + a32*ELEM(-2,3) + a31*ELEM(-2,4) + \ + a41*ELEM(-1,-4) + a42*ELEM(-1,-3) + a43*ELEM(-1,-2) + a44*ELEM(-1,-1) + a45*ELEM(-1,0) + a44*ELEM(-1,1) + a43*ELEM(-1,2) + a42*ELEM(-1,3) + a41*ELEM(-1,4) + \ + a51*ELEM(0,-4) + a52*ELEM(0,-3) + a53*ELEM(0,-2) + a54*ELEM(0,-1) + a55*ELEM(0,0) + a54*ELEM(0,1) + a53*ELEM(0,2) + a52*ELEM(0,3) + a51*ELEM(0,4) + \ + a41*ELEM(1,-4) + a42*ELEM(1,-3) + a43*ELEM(1,-2) + a44*ELEM(1,-1) + a45*ELEM(1,0) + a44*ELEM(1,1) + a43*ELEM(1,2) + a42*ELEM(1,3) + a41*ELEM(1,4) + \ + a31*ELEM(2,-4) + a32*ELEM(2,-3) + a33*ELEM(2,-2) + a34*ELEM(2,-1) + a35*ELEM(2,0) + a34*ELEM(2,1) + a33*ELEM(2,2) + a32*ELEM(2,3) + a31*ELEM(2,4) + \ + a21*ELEM(3,-4) + a22*ELEM(3,-3) + a23*ELEM(3,-2) + a24*ELEM(3,-1) + a25*ELEM(3,0) + a24*ELEM(3,1) + a23*ELEM(3,2) + a22*ELEM(3,3) + a21*ELEM(3,4) + \ + a11*ELEM(4,-4) + a12*ELEM(4,-3) + a13*ELEM(4,-2) + a14*ELEM(4,-1) + a15*ELEM(4,0) + a14*ELEM(4,1) + a13*ELEM(4,2) + a12*ELEM(4,3) + a11*ELEM(4,4); \ + v /= a11*SULY(-4,-4) + a12*SULY(-4,-3) + a13*SULY(-4,-2) + a14*SULY(-4,-1) + a15*SULY(-4,0) + a14*SULY(-4,1) + a13*SULY(-4,2) + a12*SULY(-4,3) + a11*SULY(-4,4) + \ + a21*SULY(-3,-4) + a22*SULY(-3,-3) + a23*SULY(-3,-2) + a24*SULY(-3,-1) + a25*SULY(-3,0) + a24*SULY(-3,1) + a23*SULY(-3,2) + a22*SULY(-3,3) + a21*SULY(-3,4) + \ + a31*SULY(-2,-4) + a32*SULY(-2,-3) + a33*SULY(-2,-2) + a34*SULY(-2,-1) + a35*SULY(-2,0) + a34*SULY(-2,1) + a33*SULY(-2,2) + a32*SULY(-2,3) + a31*SULY(-2,4) + \ + a41*SULY(-1,-4) + a42*SULY(-1,-3) + a43*SULY(-1,-2) + a44*SULY(-1,-1) + a45*SULY(-1,0) + a44*SULY(-1,1) + a43*SULY(-1,2) + a42*SULY(-1,3) + a41*SULY(-1,4) + \ + a51*SULY(0,-4) + a52*SULY(0,-3) + a53*SULY(0,-2) + a54*SULY(0,-1) + a55*SULY(0,0) + a54*SULY(0,1) + a53*SULY(0,2) + a52*SULY(0,3) + a51*SULY(0,4) + \ + a41*SULY(1,-4) + a42*SULY(1,-3) + a43*SULY(1,-2) + a44*SULY(1,-1) + a45*SULY(1,0) + a44*SULY(1,1) + a43*SULY(1,2) + a42*SULY(1,3) + a41*SULY(1,4) + \ + a31*SULY(2,-4) + a32*SULY(2,-3) + a33*SULY(2,-2) + a34*SULY(2,-1) + a35*SULY(2,0) + a34*SULY(2,1) + a33*SULY(2,2) + a32*SULY(2,3) + a31*SULY(2,4) + \ + a21*SULY(3,-4) + a22*SULY(3,-3) + a23*SULY(3,-2) + a24*SULY(3,-1) + a25*SULY(3,0) + a24*SULY(3,1) + a23*SULY(3,2) + a22*SULY(3,3) + a21*SULY(3,4) + \ + a11*SULY(4,-4) + a12*SULY(4,-3) + a13*SULY(4,-2) + a14*SULY(4,-1) + a15*SULY(4,0) + a14*SULY(4,1) + a13*SULY(4,2) + a12*SULY(4,3) + a11*SULY(4,4); + +#define BL_OPER11(a11,a12,a13,a14,a15,a16,a21,a22,a23,a24,a25,a26,a31,a32,a33,a34,a35,a36,a41,a42,a43,a44,a45,a46,a51,a52,a53,a54,a55,a56,a61,a62,a63,a64,a65,a66) \ + A v = a11*ELEM(-5,-5) + a12*ELEM(-5,-4) + a13*ELEM(-5,-3) + a14*ELEM(-5,-2) + a15*ELEM(-5,-1) + a16*ELEM(-5,0) + a15*ELEM(-5,1) + a14*ELEM(-5,2) + a13*ELEM(-5,3) + a12*ELEM(-5,4) + a11*ELEM(-5,5) + \ + a21*ELEM(-4,-5) + a22*ELEM(-4,-4) + a23*ELEM(-4,-3) + a24*ELEM(-4,-2) + a25*ELEM(-4,-1) + a26*ELEM(-4,0) + a25*ELEM(-4,1) + a24*ELEM(-4,2) + a23*ELEM(-4,3) + a22*ELEM(-4,4) + a21*ELEM(-4,5) + \ + a31*ELEM(-3,-5) + a32*ELEM(-3,-4) + a33*ELEM(-3,-3) + a34*ELEM(-3,-2) + a35*ELEM(-3,-1) + a36*ELEM(-3,0) + a35*ELEM(-3,1) + a34*ELEM(-3,2) + a33*ELEM(-3,3) + a32*ELEM(-3,4) + a31*ELEM(-3,5) + \ + a41*ELEM(-2,-5) + a42*ELEM(-2,-4) + a43*ELEM(-2,-3) + a44*ELEM(-2,-2) + a45*ELEM(-2,-1) + a46*ELEM(-2,0) + a45*ELEM(-2,1) + a44*ELEM(-2,2) + a43*ELEM(-2,3) + a42*ELEM(-2,4) + a41*ELEM(-4,5) + \ + a51*ELEM(-1,-5) + a52*ELEM(-1,-4) + a53*ELEM(-1,-3) + a54*ELEM(-1,-2) + a55*ELEM(-1,-1) + a56*ELEM(-1,0) + a55*ELEM(-1,1) + a54*ELEM(-1,2) + a53*ELEM(-1,3) + a52*ELEM(-1,4) + a51*ELEM(-1,5) + \ + a61*ELEM(0,-5) + a62*ELEM(0,-4) + a63*ELEM(0,-3) + a64*ELEM(0,-2) + a65*ELEM(0,-1) + a66*ELEM(0,0) + a65*ELEM(0,1) + a64*ELEM(0,2) + a63*ELEM(0,3) + a62*ELEM(0,4) + a61*ELEM(0,5) + \ + a51*ELEM(1,-5) + a52*ELEM(1,-4) + a53*ELEM(1,-3) + a54*ELEM(1,-2) + a55*ELEM(1,-1) + a56*ELEM(1,0) + a55*ELEM(1,1) + a54*ELEM(1,2) + a53*ELEM(1,3) + a52*ELEM(1,4) + a51*ELEM(1,5) + \ + a41*ELEM(2,-5) + a42*ELEM(2,-4) + a43*ELEM(2,-3) + a44*ELEM(2,-2) + a45*ELEM(2,-1) + a46*ELEM(2,0) + a45*ELEM(2,1) + a44*ELEM(2,2) + a43*ELEM(2,3) + a42*ELEM(2,4) + a41*ELEM(2,5) + \ + a31*ELEM(3,-5) + a32*ELEM(3,-4) + a33*ELEM(3,-3) + a34*ELEM(3,-2) + a35*ELEM(3,-1) + a36*ELEM(3,0) + a35*ELEM(3,1) + a34*ELEM(3,2) + a33*ELEM(3,3) + a32*ELEM(3,4) + a31*ELEM(3,5) + \ + a21*ELEM(4,-5) + a22*ELEM(4,-4) + a23*ELEM(4,-3) + a24*ELEM(4,-2) + a25*ELEM(4,-1) + a26*ELEM(4,0) + a25*ELEM(4,1) + a24*ELEM(4,2) + a23*ELEM(4,3) + a22*ELEM(4,4) + a21*ELEM(4,5) + \ + a11*ELEM(5,-5) + a12*ELEM(5,-4) + a13*ELEM(5,-3) + a14*ELEM(5,-2) + a15*ELEM(5,-1) + a16*ELEM(5,0) + a15*ELEM(5,1) + a14*ELEM(5,2) + a13*ELEM(5,3) + a12*ELEM(5,4) + a11*ELEM(5,5); \ + v /= a11*SULY(-5,-5) + a12*SULY(-5,-4) + a13*SULY(-5,-3) + a14*SULY(-5,-2) + a15*SULY(-5,-1) + a16*SULY(-5,0) + a15*SULY(-5,1) + a14*SULY(-5,2) + a13*SULY(-5,3) + a12*SULY(-5,4) + a11*SULY(-5,5) + \ + a21*SULY(-4,-5) + a22*SULY(-4,-4) + a23*SULY(-4,-3) + a24*SULY(-4,-2) + a25*SULY(-4,-1) + a26*SULY(-4,0) + a25*SULY(-4,1) + a24*SULY(-4,2) + a23*SULY(-4,3) + a22*SULY(-4,4) + a21*SULY(-4,5) + \ + a31*SULY(-3,-5) + a32*SULY(-3,-4) + a33*SULY(-3,-3) + a34*SULY(-3,-2) + a35*SULY(-3,-1) + a36*SULY(-3,0) + a35*SULY(-3,1) + a34*SULY(-3,2) + a33*SULY(-3,3) + a32*SULY(-3,4) + a31*SULY(-3,5) + \ + a41*SULY(-2,-5) + a42*SULY(-2,-4) + a43*SULY(-2,-3) + a44*SULY(-2,-2) + a45*SULY(-2,-1) + a46*SULY(-2,0) + a45*SULY(-2,1) + a44*SULY(-2,2) + a43*SULY(-2,3) + a42*SULY(-2,4) + a41*SULY(-4,5) + \ + a51*SULY(-1,-5) + a52*SULY(-1,-4) + a53*SULY(-1,-3) + a54*SULY(-1,-2) + a55*SULY(-1,-1) + a56*SULY(-1,0) + a55*SULY(-1,1) + a54*SULY(-1,2) + a53*SULY(-1,3) + a52*SULY(-1,4) + a51*SULY(-1,5) + \ + a61*SULY(0,-5) + a62*SULY(0,-4) + a63*SULY(0,-3) + a64*SULY(0,-2) + a65*SULY(0,-1) + a66*SULY(0,0) + a65*SULY(0,1) + a64*SULY(0,2) + a63*SULY(0,3) + a62*SULY(0,4) + a61*SULY(0,5) + \ + a51*SULY(1,-5) + a52*SULY(1,-4) + a53*SULY(1,-3) + a54*SULY(1,-2) + a55*SULY(1,-1) + a56*SULY(1,0) + a55*SULY(1,1) + a54*SULY(1,2) + a53*SULY(1,3) + a52*SULY(1,4) + a51*SULY(1,5) + \ + a41*SULY(2,-5) + a42*SULY(2,-4) + a43*SULY(2,-3) + a44*SULY(2,-2) + a45*SULY(2,-1) + a46*SULY(2,0) + a45*SULY(2,1) + a44*SULY(2,2) + a43*SULY(2,3) + a42*SULY(2,4) + a41*SULY(2,5) + \ + a31*SULY(3,-5) + a32*SULY(3,-4) + a33*SULY(3,-3) + a34*SULY(3,-2) + a35*SULY(3,-1) + a36*SULY(3,0) + a35*SULY(3,1) + a34*SULY(3,2) + a33*SULY(3,3) + a32*SULY(3,4) + a31*SULY(3,5) + \ + a21*SULY(4,-5) + a22*SULY(4,-4) + a23*SULY(4,-3) + a24*SULY(4,-2) + a25*SULY(4,-1) + a26*SULY(4,0) + a25*SULY(4,1) + a24*SULY(4,2) + a23*SULY(4,3) + a22*SULY(4,4) + a21*SULY(4,5) + \ + a11*SULY(5,-5) + a12*SULY(5,-4) + a13*SULY(5,-3) + a14*SULY(5,-2) + a15*SULY(5,-1) + a16*SULY(5,0) + a15*SULY(5,1) + a14*SULY(5,2) + a13*SULY(5,3) + a12*SULY(5,4) + a11*SULY(5,5); \ + + +// sigma = 0.5 +template void bilateral05 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(318,1) + BL_OPER3(1,7,7,55) + BL_END(1) +} + +// sigma = 0.6 +template void bilateral06 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(768,1) + BL_OPER3(1,4,4,16) + BL_END(1) +} + +// sigma = 0.7 +template void bilateral07 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(366,2) + BL_OPER5(0,0,1,0,8,21,1,21,59) + BL_END(2) +} + +// sigma = 0.8 +template void bilateral08 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(753,2) + BL_OPER5(0,0,1,0,5,10,1,10,23) + BL_END(2) +} + +// sigma = 0.9 +template void bilateral09 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(595,2) + BL_OPER5(0,1,2,1,6,12,2,12,22) + BL_END(2) +} + +// sigma = 1.0 +template void bilateral10 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(910,2) + BL_OPER5(0,1,2,1,4,7,2,7,12) + BL_END(2) +} + +// sigma = 1.1 +template void bilateral11 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(209,3) + BL_OPER7(0,0,1,1,0,2,5,8,1,5,18,27,1,8,27,41) + BL_END(3) +} + +// sigma = 1.2 +template void bilateral12 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(322,3) + BL_OPER7(0,0,1,1,0,1,4,6,1,4,11,16,1,6,16,23) + BL_END(3) +} + +// sigma = 1.3 +template void bilateral13 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(336,3) + BL_OPER7(0,0,1,1,0,2,4,6,1,4,11,14,1,6,14,19) + BL_END(3) +} + +// sigma = 1.4 +template void bilateral14 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(195,3) + BL_OPER7(0,1,2,3,1,4,8,10,2,8,17,21,3,10,21,28) + BL_END(3) +} + +// sigma = 1.5 +template void bilateral15 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(132,4) + BL_OPER9(0,0,0,1,1,0,1,2,4,5,0,2,6,12,14,1,4,12,22,28,1,5,14,28,35) + BL_END(4) +} + +// sigma = 1.6 +template void bilateral16 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(180,4) + BL_OPER9(0,0,0,1,1,0,1,2,3,4,0,2,5,9,10,1,3,9,15,19,1,4,10,19,23) + BL_END(4) +} + +// sigma = 1.7 +template void bilateral17 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(195,4) + BL_OPER9(0,0,1,1,1,0,1,2,3,4,1,2,5,8,9,1,3,8,13,16,1,4,9,16,19) + BL_END(4) +} + +// sigma = 1.8 +template void bilateral18 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(151,4) + BL_OPER9(0,0,1,2,2,0,1,3,5,5,1,3,6,10,12,2,5,10,16,19,2,5,12,19,22) + BL_END(4) +} + +// sigma = 1.9 +template void bilateral19 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(151,4) + BL_OPER9(0,0,1,2,2,0,1,3,4,5,1,3,5,8,9,2,4,8,12,14,2,5,9,14,16) + BL_END(4) +} + +// sigma = 2 +template void bilateral20 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(116,5) + BL_OPER11(0,0,0,1,1,1,0,0,1,2,3,3,0,1,2,4,7,7,1,2,4,8,12,14,1,3,7,12,18,20,1,3,7,14,20,23) + BL_END(5) +} + +// sigma = 2.1 +template void bilateral21 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(127,5) + BL_OPER11(0,0,0,1,1,1,0,0,1,2,3,3,0,1,2,4,6,7,1,2,4,8,11,12,1,3,6,11,15,17,1,3,7,12,17,19) + BL_END(5) +} + +// sigma = 2.2 +template void bilateral22 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(109,5) + BL_OPER11(0,0,0,1,1,2,0,1,2,3,3,4,1,2,3,5,7,8,1,3,5,9,12,13,1,3,7,12,16,18,2,4,8,13,18,20) + BL_END(5) +} + +// sigma = 2.3 +template void bilateral23 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(132,5) + BL_OPER11(0,0,1,1,1,1,0,1,1,2,3,3,1,1,3,5,6,7,1,2,5,7,10,11,1,3,6,10,13,14,1,3,7,11,14,16) + BL_END(5) +} + +// sigma = 2.4 +template void bilateral24 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(156,5) + BL_OPER11(0,0,1,1,1,1,0,1,1,2,3,3,1,1,3,4,5,6,1,2,4,6,8,9,1,3,5,8,10,11,1,3,6,9,11,12) + BL_END(5) +} + +// sigma = 2.5 +template void bilateral25 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(173,5) + BL_OPER11(0,0,1,1,1,1,0,1,1,2,3,3,1,1,2,4,5,5,1,2,4,5,7,7,1,3,5,7,9,9,1,3,5,7,9,10) + BL_END(5) +} + +class Dim { + + public: + int W, H, row_from, row_to; + + Dim (int w, int h, int rf, int rt) : W(w), H(h), row_from(rf), row_to(rt) {} + +}; + +// main bilateral filter +template void bilateral (T** src, T** dst, T** buffer, Dim dim, double sigma, double sens) { + + int W = dim.W; + int H = dim.H; + int row_from = dim.row_from; + int row_to = dim.row_to; + + if (sigma<0.45) + for (int i=row_from; i (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<0.65) + bilateral06 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<0.75) + bilateral07 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<0.85) + bilateral08 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<0.95) + bilateral09 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.05) + bilateral10 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.15) + bilateral11 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.25) + bilateral12 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.35) + bilateral13 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.45) + bilateral14 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.55) + bilateral15 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.65) + bilateral16 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.75) + bilateral17 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.85) + bilateral18 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.95) + bilateral19 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<2.05) + bilateral20 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<2.15) + bilateral21 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<2.25) + bilateral22 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<2.35) + bilateral23 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<2.45) + bilateral24 (src, dst, buffer, W, H, row_from, row_to, sens); + else + bilateral25 (src, dst, buffer, W, H, row_from, row_to, sens); +} + +void bilateral_unsigned (unsigned short** src, unsigned short** dst, unsigned short** buffer, Dim dim, double sigma, double sens); +void bilateral_signed (short** src, short** dst, short** buffer, Dim dim, double sigma, double sens); + +/* +template void bilateral (T** src, int** dst, int W, int H, int sigmar, double sigmas) { + + time_t t1 = clock (); + + int r = 2.0*sigmas + 0.5; + + double scaleg = 1024.0; + + double MAXINT = 65536.0*65536.0; + double sgmax = 275000/(MAXINT/2.0/sigmar/sigmar+(r+1)*(r+1)/sigmas/sigmas); + printf ("sgmax = %lf\n", sgmax); + if (scaleg>sgmax) + scaleg = sgmax; + + // kernel vector for the spatial gaussian filter * 1024 + int* kernel = new int[1+2*r]; + for (int i=0; i<2*r+1; i++) { + kernel[i] = scaleg / (2.0*sigmas*sigmas) * (i-r)*(i-r) + 0.25; + printf ("kerneli = %d\n", kernel[i]); + } + + // exponential lookup table + int scale = (2.0*sigmar*sigmar) / scaleg; + int scalem = 65535/((1+2*r)*(1+2*r)); + int ec[256000]; + for (int i=0; i<256000; i++) + ec[i] = exp (-i/scaleg) * scalem; + + for (int i=r; i0?((a) void bilateral (T** src, T** dst, AlignedBuffer* buffer, int W, int H, double sigmar, double sigmas) { + + time_t t1 = clock (); + + float alpha = 0.5 / sigmar / sigmar; + + // buffer for the final image + float** buff_final = new float*[H]; + for (int i=0; i void bilateral (T** src, T** dst, int W, int H, int sigmar, double sigmas, int row_from, int row_to) { + + // range weights + double* ec = new double [0x20000]; + for (int i=0; i<0x20000; i++) + ec[i] = exp(-(double)(i-0x10000)*(double)(i-0x10000) / (2.0*sigmar*sigmar)); + + // histogram + unsigned short* hist = new unsigned short[1<>TRANSBIT]++; + + sigmar*=2; + + for (int i=row_from; ir) + for (int x = 0; x>TRANSBIT]--; + if (i>TRANSBIT]++; + + memcpy (hist, rhist, (1<r) + for (int x=MAX(0,i-r); x<=MIN(i+r,H-1); x++) + hist[src[x][j-r-1]>>TRANSBIT]--; + if (j>TRANSBIT]++; + + // calculate pixel value + float weight = 0.0; + for (int k=0; k<=(sigmar>>TRANSBIT); k++) { + float w = 1.0 - (double)k/(sigmar>>TRANSBIT); + int v = src[i][j]>>TRANSBIT; + if (v-k >= 0) { + weight += hist [v-k] * w; + buff_final[i][j] += hist [v-k] * w * (src[i][j]-(k< void bilateral (T** src, T** dst, AlignedBuffer* buffer, int W, int H, int sigmar, double sigmas) { + + time_t t1 = clock (); + + unsigned short** rowhist = new unsigned short* [H]; + for (int i=0; i>TRANSBIT]++; + + // let the game begin... + for (int j=r+1; j>TRANSBIT]--; + rowhist[i][src[i][j+r]>>TRANSBIT]++; + } + // sum up upper histograms + memset (hist, 0, (1<>TRANSBIT); k++) { + float w = 1.0 - (double)k/(sigmar>>TRANSBIT); + int v = src[i][j]>>TRANSBIT; + if (v-k >= 0) { + weight += hist [v-k] * w; + buff_final[i][j] += hist [v-k] * w * (src[i][j]-(k<H-r-1 || jW-r-1) + dst[i][j] = src[i][j]; + else + dst[i][j] = (T)CLIP(buff_final[i][j]); + + delete [] hist; + for (int i=0; i + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#define MAXVAL 0xffff +#define CLIP(a) ((a)>0?((a)>8)+1)<<8) / ((src[i][j]>>8)+1)]) +//#define ELEM(a,b) (src[i-a][j-b] * ec[src[i-a][j-b]-src[i][j]+0x10000]) +//#define SULY(a,b) (ec[src[i-a][j-b]-src[i][j]+0x10000]) +#define SULY(a,b) (ec[(((src[i-a][j-b]>>8)+1)<<8) / ((src[i][j]>>8)+1)]) + +#define BL_BEGIN(a,b) double scale = (a); \ + int* ec = new int [0x10001]; \ + ec[0] = 1; \ + for (int i=1; i<0x10001; i++) \ + ec[i] = (int)(exp(-log(i/256.0)*log(i/256.0) / (2.0*sens/1000*sens/1000*i/256.0))*scale); \ +/* ec[i] = (int)(exp(-(double)(i-0x10000)*(double)(i-0x10000) / (2.0*sens*sens))*scale); */\ + int start = row_from; \ + if (start<(b)) start = (b); \ + int end = row_to; \ + if (end>H-(b)) end = H-(b); \ + for (int i=start; i=end || j>=W-(b)) \ + dst[i][j] = src[i][j]; \ + else \ + dst[i][j] = buffer[i][j]; + +#define BL_OPER3(a11,a12,a21,a22) A v = a11*ELEM(-1,-1) + a12*ELEM(-1,0) + a11*ELEM(-1,1) + \ + a21*ELEM(0,-1) + a22*ELEM(0,0) + a21*ELEM(0,1) + \ + a11*ELEM(1,-1) + a12*ELEM(1,0) + a11*ELEM(1,1); \ + v /= a11*SULY(-1,-1) + a12*SULY(-1,0) + a11*SULY(-1,1) + \ + a21*SULY(0,-1) + a22*SULY(0,0) + a21*SULY(0,1) + \ + a11*SULY(1,-1) + a12*SULY(1,0) + a11*SULY(1,1); + + +#define BL_OPER5(a11,a12,a13,a21,a22,a23,a31,a32,a33) A v = a11*ELEM(-2,-2) + a12*ELEM(-2,-1) + a13*ELEM(-2,0) + a12*ELEM(-2,1) + a11*ELEM(-2,2) + \ + a21*ELEM(-1,-2) + a22*ELEM(-1,-1) + a23*ELEM(-1,0) + a22*ELEM(-1,1) + a21*ELEM(-1,2) + \ + a31*ELEM(0,-2) + a32*ELEM(0,-1) + a33*ELEM(0,0) + a32*ELEM(0,1) + a31*ELEM(0,2) + \ + a21*ELEM(1,-2) + a22*ELEM(1,-1) + a23*ELEM(1,0) + a22*ELEM(1,1) + a21*ELEM(1,2) + \ + a11*ELEM(2,-2) + a12*ELEM(2,-1) + a13*ELEM(2,0) + a12*ELEM(2,1) + a11*ELEM(2,2); \ + v /= a11*SULY(-2,-2) + a12*SULY(-2,-1) + a13*SULY(-2,0) + a12*SULY(-2,1) + a11*SULY(-2,2) + \ + a21*SULY(-1,-2) + a22*SULY(-1,-1) + a23*SULY(-1,0) + a22*SULY(-1,1) + a21*SULY(-1,2) + \ + a31*SULY(0,-2) + a32*SULY(0,-1) + a33*SULY(0,0) + a32*SULY(0,1) + a31*SULY(0,2) + \ + a21*SULY(1,-2) + a22*SULY(1,-1) + a23*SULY(1,0) + a22*SULY(1,1) + a21*SULY(1,2) + \ + a11*SULY(2,-2) + a12*SULY(2,-1) + a13*SULY(2,0) + a12*SULY(2,1) + a11*SULY(2,2); + +#define BL_OPER7(a11,a12,a13,a14,a21,a22,a23,a24,a31,a32,a33,a34,a41,a42,a43,a44) \ + A v = a11*ELEM(-3,-3) + a12*ELEM(-3,-2) + a13*ELEM(-3,-1) + a14*ELEM(-3,0) + a13*ELEM(-3,1) + a12*ELEM(-3,2) + a11*ELEM(-3,3) + \ + a21*ELEM(-2,-3) + a22*ELEM(-2,-2) + a23*ELEM(-2,-1) + a24*ELEM(-2,0) + a23*ELEM(-2,1) + a22*ELEM(-2,2) + a21*ELEM(-2,3) + \ + a31*ELEM(-1,-3) + a32*ELEM(-1,-2) + a33*ELEM(-1,-1) + a34*ELEM(-1,0) + a33*ELEM(-1,1) + a32*ELEM(-1,2) + a31*ELEM(-1,3) + \ + a41*ELEM(0,-3) + a42*ELEM(0,-2) + a43*ELEM(0,-1) + a44*ELEM(0,0) + a43*ELEM(0,1) + a42*ELEM(0,2) + a41*ELEM(0,3) + \ + a31*ELEM(1,-3) + a32*ELEM(1,-2) + a33*ELEM(1,-1) + a34*ELEM(1,0) + a33*ELEM(1,1) + a32*ELEM(1,2) + a31*ELEM(1,3) + \ + a21*ELEM(2,-3) + a22*ELEM(2,-2) + a23*ELEM(2,-1) + a24*ELEM(2,0) + a23*ELEM(2,1) + a22*ELEM(2,2) + a21*ELEM(2,3) + \ + a11*ELEM(3,-3) + a12*ELEM(3,-2) + a13*ELEM(3,-1) + a14*ELEM(3,0) + a13*ELEM(3,1) + a12*ELEM(3,2) + a11*ELEM(3,3); \ + v /= a11*SULY(-3,-3) + a12*SULY(-3,-2) + a13*SULY(-3,-1) + a14*SULY(-3,0) + a13*SULY(-3,1) + a12*SULY(-3,2) + a11*SULY(-3,3) + \ + a21*SULY(-2,-3) + a22*SULY(-2,-2) + a23*SULY(-2,-1) + a24*SULY(-2,0) + a23*SULY(-2,1) + a22*SULY(-2,2) + a21*SULY(-2,3) + \ + a31*SULY(-1,-3) + a32*SULY(-1,-2) + a33*SULY(-1,-1) + a34*SULY(-1,0) + a33*SULY(-1,1) + a32*SULY(-1,2) + a31*SULY(-1,3) + \ + a41*SULY(0,-3) + a42*SULY(0,-2) + a43*SULY(0,-1) + a44*SULY(0,0) + a43*SULY(0,1) + a42*SULY(0,2) + a41*SULY(0,3) + \ + a31*SULY(1,-3) + a32*SULY(1,-2) + a33*SULY(1,-1) + a34*SULY(1,0) + a33*SULY(1,1) + a32*SULY(1,2) + a31*SULY(1,3) + \ + a21*SULY(2,-3) + a22*SULY(2,-2) + a23*SULY(2,-1) + a24*SULY(2,0) + a23*SULY(2,1) + a22*SULY(2,2) + a21*SULY(2,3) + \ + a11*SULY(3,-3) + a12*SULY(3,-2) + a13*SULY(3,-1) + a14*SULY(3,0) + a13*SULY(3,1) + a12*SULY(3,2) + a11*SULY(3,3); + + +#define BL_OPER9(a11,a12,a13,a14,a15,a21,a22,a23,a24,a25,a31,a32,a33,a34,a35,a41,a42,a43,a44,a45,a51,a52,a53,a54,a55) \ + A v = a11*ELEM(-4,-4) + a12*ELEM(-4,-3) + a13*ELEM(-4,-2) + a14*ELEM(-4,-1) + a15*ELEM(-4,0) + a14*ELEM(-4,1) + a13*ELEM(-4,2) + a12*ELEM(-4,3) + a11*ELEM(-4,4) + \ + a21*ELEM(-3,-4) + a22*ELEM(-3,-3) + a23*ELEM(-3,-2) + a24*ELEM(-3,-1) + a25*ELEM(-3,0) + a24*ELEM(-3,1) + a23*ELEM(-3,2) + a22*ELEM(-3,3) + a21*ELEM(-3,4) + \ + a31*ELEM(-2,-4) + a32*ELEM(-2,-3) + a33*ELEM(-2,-2) + a34*ELEM(-2,-1) + a35*ELEM(-2,0) + a34*ELEM(-2,1) + a33*ELEM(-2,2) + a32*ELEM(-2,3) + a31*ELEM(-2,4) + \ + a41*ELEM(-1,-4) + a42*ELEM(-1,-3) + a43*ELEM(-1,-2) + a44*ELEM(-1,-1) + a45*ELEM(-1,0) + a44*ELEM(-1,1) + a43*ELEM(-1,2) + a42*ELEM(-1,3) + a41*ELEM(-1,4) + \ + a51*ELEM(0,-4) + a52*ELEM(0,-3) + a53*ELEM(0,-2) + a54*ELEM(0,-1) + a55*ELEM(0,0) + a54*ELEM(0,1) + a53*ELEM(0,2) + a52*ELEM(0,3) + a51*ELEM(0,4) + \ + a41*ELEM(1,-4) + a42*ELEM(1,-3) + a43*ELEM(1,-2) + a44*ELEM(1,-1) + a45*ELEM(1,0) + a44*ELEM(1,1) + a43*ELEM(1,2) + a42*ELEM(1,3) + a41*ELEM(1,4) + \ + a31*ELEM(2,-4) + a32*ELEM(2,-3) + a33*ELEM(2,-2) + a34*ELEM(2,-1) + a35*ELEM(2,0) + a34*ELEM(2,1) + a33*ELEM(2,2) + a32*ELEM(2,3) + a31*ELEM(2,4) + \ + a21*ELEM(3,-4) + a22*ELEM(3,-3) + a23*ELEM(3,-2) + a24*ELEM(3,-1) + a25*ELEM(3,0) + a24*ELEM(3,1) + a23*ELEM(3,2) + a22*ELEM(3,3) + a21*ELEM(3,4) + \ + a11*ELEM(4,-4) + a12*ELEM(4,-3) + a13*ELEM(4,-2) + a14*ELEM(4,-1) + a15*ELEM(4,0) + a14*ELEM(4,1) + a13*ELEM(4,2) + a12*ELEM(4,3) + a11*ELEM(4,4); \ + v /= a11*SULY(-4,-4) + a12*SULY(-4,-3) + a13*SULY(-4,-2) + a14*SULY(-4,-1) + a15*SULY(-4,0) + a14*SULY(-4,1) + a13*SULY(-4,2) + a12*SULY(-4,3) + a11*SULY(-4,4) + \ + a21*SULY(-3,-4) + a22*SULY(-3,-3) + a23*SULY(-3,-2) + a24*SULY(-3,-1) + a25*SULY(-3,0) + a24*SULY(-3,1) + a23*SULY(-3,2) + a22*SULY(-3,3) + a21*SULY(-3,4) + \ + a31*SULY(-2,-4) + a32*SULY(-2,-3) + a33*SULY(-2,-2) + a34*SULY(-2,-1) + a35*SULY(-2,0) + a34*SULY(-2,1) + a33*SULY(-2,2) + a32*SULY(-2,3) + a31*SULY(-2,4) + \ + a41*SULY(-1,-4) + a42*SULY(-1,-3) + a43*SULY(-1,-2) + a44*SULY(-1,-1) + a45*SULY(-1,0) + a44*SULY(-1,1) + a43*SULY(-1,2) + a42*SULY(-1,3) + a41*SULY(-1,4) + \ + a51*SULY(0,-4) + a52*SULY(0,-3) + a53*SULY(0,-2) + a54*SULY(0,-1) + a55*SULY(0,0) + a54*SULY(0,1) + a53*SULY(0,2) + a52*SULY(0,3) + a51*SULY(0,4) + \ + a41*SULY(1,-4) + a42*SULY(1,-3) + a43*SULY(1,-2) + a44*SULY(1,-1) + a45*SULY(1,0) + a44*SULY(1,1) + a43*SULY(1,2) + a42*SULY(1,3) + a41*SULY(1,4) + \ + a31*SULY(2,-4) + a32*SULY(2,-3) + a33*SULY(2,-2) + a34*SULY(2,-1) + a35*SULY(2,0) + a34*SULY(2,1) + a33*SULY(2,2) + a32*SULY(2,3) + a31*SULY(2,4) + \ + a21*SULY(3,-4) + a22*SULY(3,-3) + a23*SULY(3,-2) + a24*SULY(3,-1) + a25*SULY(3,0) + a24*SULY(3,1) + a23*SULY(3,2) + a22*SULY(3,3) + a21*SULY(3,4) + \ + a11*SULY(4,-4) + a12*SULY(4,-3) + a13*SULY(4,-2) + a14*SULY(4,-1) + a15*SULY(4,0) + a14*SULY(4,1) + a13*SULY(4,2) + a12*SULY(4,3) + a11*SULY(4,4); + +#define BL_OPER11(a11,a12,a13,a14,a15,a16,a21,a22,a23,a24,a25,a26,a31,a32,a33,a34,a35,a36,a41,a42,a43,a44,a45,a46,a51,a52,a53,a54,a55,a56,a61,a62,a63,a64,a65,a66) \ + A v = a11*ELEM(-5,-5) + a12*ELEM(-5,-4) + a13*ELEM(-5,-3) + a14*ELEM(-5,-2) + a15*ELEM(-5,-1) + a16*ELEM(-5,0) + a15*ELEM(-5,1) + a14*ELEM(-5,2) + a13*ELEM(-5,3) + a12*ELEM(-5,4) + a11*ELEM(-5,5) + \ + a21*ELEM(-4,-5) + a22*ELEM(-4,-4) + a23*ELEM(-4,-3) + a24*ELEM(-4,-2) + a25*ELEM(-4,-1) + a26*ELEM(-4,0) + a25*ELEM(-4,1) + a24*ELEM(-4,2) + a23*ELEM(-4,3) + a22*ELEM(-4,4) + a21*ELEM(-4,5) + \ + a31*ELEM(-3,-5) + a32*ELEM(-3,-4) + a33*ELEM(-3,-3) + a34*ELEM(-3,-2) + a35*ELEM(-3,-1) + a36*ELEM(-3,0) + a35*ELEM(-3,1) + a34*ELEM(-3,2) + a33*ELEM(-3,3) + a32*ELEM(-3,4) + a31*ELEM(-3,5) + \ + a41*ELEM(-2,-5) + a42*ELEM(-2,-4) + a43*ELEM(-2,-3) + a44*ELEM(-2,-2) + a45*ELEM(-2,-1) + a46*ELEM(-2,0) + a45*ELEM(-2,1) + a44*ELEM(-2,2) + a43*ELEM(-2,3) + a42*ELEM(-2,4) + a41*ELEM(-4,5) + \ + a51*ELEM(-1,-5) + a52*ELEM(-1,-4) + a53*ELEM(-1,-3) + a54*ELEM(-1,-2) + a55*ELEM(-1,-1) + a56*ELEM(-1,0) + a55*ELEM(-1,1) + a54*ELEM(-1,2) + a53*ELEM(-1,3) + a52*ELEM(-1,4) + a51*ELEM(-1,5) + \ + a61*ELEM(0,-5) + a62*ELEM(0,-4) + a63*ELEM(0,-3) + a64*ELEM(0,-2) + a65*ELEM(0,-1) + a66*ELEM(0,0) + a65*ELEM(0,1) + a64*ELEM(0,2) + a63*ELEM(0,3) + a62*ELEM(0,4) + a61*ELEM(0,5) + \ + a51*ELEM(1,-5) + a52*ELEM(1,-4) + a53*ELEM(1,-3) + a54*ELEM(1,-2) + a55*ELEM(1,-1) + a56*ELEM(1,0) + a55*ELEM(1,1) + a54*ELEM(1,2) + a53*ELEM(1,3) + a52*ELEM(1,4) + a51*ELEM(1,5) + \ + a41*ELEM(2,-5) + a42*ELEM(2,-4) + a43*ELEM(2,-3) + a44*ELEM(2,-2) + a45*ELEM(2,-1) + a46*ELEM(2,0) + a45*ELEM(2,1) + a44*ELEM(2,2) + a43*ELEM(2,3) + a42*ELEM(2,4) + a41*ELEM(2,5) + \ + a31*ELEM(3,-5) + a32*ELEM(3,-4) + a33*ELEM(3,-3) + a34*ELEM(3,-2) + a35*ELEM(3,-1) + a36*ELEM(3,0) + a35*ELEM(3,1) + a34*ELEM(3,2) + a33*ELEM(3,3) + a32*ELEM(3,4) + a31*ELEM(3,5) + \ + a21*ELEM(4,-5) + a22*ELEM(4,-4) + a23*ELEM(4,-3) + a24*ELEM(4,-2) + a25*ELEM(4,-1) + a26*ELEM(4,0) + a25*ELEM(4,1) + a24*ELEM(4,2) + a23*ELEM(4,3) + a22*ELEM(4,4) + a21*ELEM(4,5) + \ + a11*ELEM(5,-5) + a12*ELEM(5,-4) + a13*ELEM(5,-3) + a14*ELEM(5,-2) + a15*ELEM(5,-1) + a16*ELEM(5,0) + a15*ELEM(5,1) + a14*ELEM(5,2) + a13*ELEM(5,3) + a12*ELEM(5,4) + a11*ELEM(5,5); \ + v /= a11*SULY(-5,-5) + a12*SULY(-5,-4) + a13*SULY(-5,-3) + a14*SULY(-5,-2) + a15*SULY(-5,-1) + a16*SULY(-5,0) + a15*SULY(-5,1) + a14*SULY(-5,2) + a13*SULY(-5,3) + a12*SULY(-5,4) + a11*SULY(-5,5) + \ + a21*SULY(-4,-5) + a22*SULY(-4,-4) + a23*SULY(-4,-3) + a24*SULY(-4,-2) + a25*SULY(-4,-1) + a26*SULY(-4,0) + a25*SULY(-4,1) + a24*SULY(-4,2) + a23*SULY(-4,3) + a22*SULY(-4,4) + a21*SULY(-4,5) + \ + a31*SULY(-3,-5) + a32*SULY(-3,-4) + a33*SULY(-3,-3) + a34*SULY(-3,-2) + a35*SULY(-3,-1) + a36*SULY(-3,0) + a35*SULY(-3,1) + a34*SULY(-3,2) + a33*SULY(-3,3) + a32*SULY(-3,4) + a31*SULY(-3,5) + \ + a41*SULY(-2,-5) + a42*SULY(-2,-4) + a43*SULY(-2,-3) + a44*SULY(-2,-2) + a45*SULY(-2,-1) + a46*SULY(-2,0) + a45*SULY(-2,1) + a44*SULY(-2,2) + a43*SULY(-2,3) + a42*SULY(-2,4) + a41*SULY(-4,5) + \ + a51*SULY(-1,-5) + a52*SULY(-1,-4) + a53*SULY(-1,-3) + a54*SULY(-1,-2) + a55*SULY(-1,-1) + a56*SULY(-1,0) + a55*SULY(-1,1) + a54*SULY(-1,2) + a53*SULY(-1,3) + a52*SULY(-1,4) + a51*SULY(-1,5) + \ + a61*SULY(0,-5) + a62*SULY(0,-4) + a63*SULY(0,-3) + a64*SULY(0,-2) + a65*SULY(0,-1) + a66*SULY(0,0) + a65*SULY(0,1) + a64*SULY(0,2) + a63*SULY(0,3) + a62*SULY(0,4) + a61*SULY(0,5) + \ + a51*SULY(1,-5) + a52*SULY(1,-4) + a53*SULY(1,-3) + a54*SULY(1,-2) + a55*SULY(1,-1) + a56*SULY(1,0) + a55*SULY(1,1) + a54*SULY(1,2) + a53*SULY(1,3) + a52*SULY(1,4) + a51*SULY(1,5) + \ + a41*SULY(2,-5) + a42*SULY(2,-4) + a43*SULY(2,-3) + a44*SULY(2,-2) + a45*SULY(2,-1) + a46*SULY(2,0) + a45*SULY(2,1) + a44*SULY(2,2) + a43*SULY(2,3) + a42*SULY(2,4) + a41*SULY(2,5) + \ + a31*SULY(3,-5) + a32*SULY(3,-4) + a33*SULY(3,-3) + a34*SULY(3,-2) + a35*SULY(3,-1) + a36*SULY(3,0) + a35*SULY(3,1) + a34*SULY(3,2) + a33*SULY(3,3) + a32*SULY(3,4) + a31*SULY(3,5) + \ + a21*SULY(4,-5) + a22*SULY(4,-4) + a23*SULY(4,-3) + a24*SULY(4,-2) + a25*SULY(4,-1) + a26*SULY(4,0) + a25*SULY(4,1) + a24*SULY(4,2) + a23*SULY(4,3) + a22*SULY(4,4) + a21*SULY(4,5) + \ + a11*SULY(5,-5) + a12*SULY(5,-4) + a13*SULY(5,-3) + a14*SULY(5,-2) + a15*SULY(5,-1) + a16*SULY(5,0) + a15*SULY(5,1) + a14*SULY(5,2) + a13*SULY(5,3) + a12*SULY(5,4) + a11*SULY(5,5); \ + + +// sigma = 0.5 +template void bilateral05 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(318,1) + BL_OPER3(1,7,7,55) + BL_END(1) +} + +// sigma = 0.6 +template void bilateral06 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(768,1) + BL_OPER3(1,4,4,16) + BL_END(1) +} + +// sigma = 0.7 +template void bilateral07 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(366,2) + BL_OPER5(0,0,1,0,8,21,1,21,59) + BL_END(2) +} + +// sigma = 0.8 +template void bilateral08 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(753,2) + BL_OPER5(0,0,1,0,5,10,1,10,23) + BL_END(2) +} + +// sigma = 0.9 +template void bilateral09 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(595,2) + BL_OPER5(0,1,2,1,6,12,2,12,22) + BL_END(2) +} + +// sigma = 1.0 +template void bilateral10 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(910,2) + BL_OPER5(0,1,2,1,4,7,2,7,12) + BL_END(2) +} + +// sigma = 1.1 +template void bilateral11 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(209,3) + BL_OPER7(0,0,1,1,0,2,5,8,1,5,18,27,1,8,27,41) + BL_END(3) +} + +// sigma = 1.2 +template void bilateral12 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(322,3) + BL_OPER7(0,0,1,1,0,1,4,6,1,4,11,16,1,6,16,23) + BL_END(3) +} + +// sigma = 1.3 +template void bilateral13 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(336,3) + BL_OPER7(0,0,1,1,0,2,4,6,1,4,11,14,1,6,14,19) + BL_END(3) +} + +// sigma = 1.4 +template void bilateral14 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(195,3) + BL_OPER7(0,1,2,3,1,4,8,10,2,8,17,21,3,10,21,28) + BL_END(3) +} + +// sigma = 1.5 +template void bilateral15 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(132,4) + BL_OPER9(0,0,0,1,1,0,1,2,4,5,0,2,6,12,14,1,4,12,22,28,1,5,14,28,35) + BL_END(4) +} + +// sigma = 1.6 +template void bilateral16 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(180,4) + BL_OPER9(0,0,0,1,1,0,1,2,3,4,0,2,5,9,10,1,3,9,15,19,1,4,10,19,23) + BL_END(4) +} + +// sigma = 1.7 +template void bilateral17 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(195,4) + BL_OPER9(0,0,1,1,1,0,1,2,3,4,1,2,5,8,9,1,3,8,13,16,1,4,9,16,19) + BL_END(4) +} + +// sigma = 1.8 +template void bilateral18 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(151,4) + BL_OPER9(0,0,1,2,2,0,1,3,5,5,1,3,6,10,12,2,5,10,16,19,2,5,12,19,22) + BL_END(4) +} + +// sigma = 1.9 +template void bilateral19 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(151,4) + BL_OPER9(0,0,1,2,2,0,1,3,4,5,1,3,5,8,9,2,4,8,12,14,2,5,9,14,16) + BL_END(4) +} + +// sigma = 2 +template void bilateral20 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(116,5) + BL_OPER11(0,0,0,1,1,1,0,0,1,2,3,3,0,1,2,4,7,7,1,2,4,8,12,14,1,3,7,12,18,20,1,3,7,14,20,23) + BL_END(5) +} + +// sigma = 2.1 +template void bilateral21 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(127,5) + BL_OPER11(0,0,0,1,1,1,0,0,1,2,3,3,0,1,2,4,6,7,1,2,4,8,11,12,1,3,6,11,15,17,1,3,7,12,17,19) + BL_END(5) +} + +// sigma = 2.2 +template void bilateral22 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(109,5) + BL_OPER11(0,0,0,1,1,2,0,1,2,3,3,4,1,2,3,5,7,8,1,3,5,9,12,13,1,3,7,12,16,18,2,4,8,13,18,20) + BL_END(5) +} + +// sigma = 2.3 +template void bilateral23 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(132,5) + BL_OPER11(0,0,1,1,1,1,0,1,1,2,3,3,1,1,3,5,6,7,1,2,5,7,10,11,1,3,6,10,13,14,1,3,7,11,14,16) + BL_END(5) +} + +// sigma = 2.4 +template void bilateral24 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(156,5) + BL_OPER11(0,0,1,1,1,1,0,1,1,2,3,3,1,1,3,4,5,6,1,2,4,6,8,9,1,3,5,8,10,11,1,3,6,9,11,12) + BL_END(5) +} + +// sigma = 2.5 +template void bilateral25 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(173,5) + BL_OPER11(0,0,1,1,1,1,0,1,1,2,3,3,1,1,2,4,5,5,1,2,4,5,7,7,1,3,5,7,9,9,1,3,5,7,9,10) + BL_END(5) +} + +class Dim { + + public: + int W, H, row_from, row_to; + + Dim (int w, int h, int rf, int rt) : W(w), H(h), row_from(rf), row_to(rt) {} + +}; + +// main bilateral filter +template void bilateral (T** src, T** dst, T** buffer, Dim dim, double sigma, double sens) { + + int W = dim.W; + int H = dim.H; + int row_from = dim.row_from; + int row_to = dim.row_to; + + if (sigma<0.45) + for (int i=row_from; i (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<0.65) + bilateral06 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<0.75) + bilateral07 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<0.85) + bilateral08 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<0.95) + bilateral09 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.05) + bilateral10 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.15) + bilateral11 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.25) + bilateral12 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.35) + bilateral13 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.45) + bilateral14 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.55) + bilateral15 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.65) + bilateral16 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.75) + bilateral17 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.85) + bilateral18 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.95) + bilateral19 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<2.05) + bilateral20 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<2.15) + bilateral21 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<2.25) + bilateral22 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<2.35) + bilateral23 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<2.45) + bilateral24 (src, dst, buffer, W, H, row_from, row_to, sens); + else + bilateral25 (src, dst, buffer, W, H, row_from, row_to, sens); +} + +void bilateral_unsigned (unsigned short** src, unsigned short** dst, unsigned short** buffer, Dim dim, double sigma, double sens) { + + bilateral (src, dst, buffer, dim, sigma, sens); +} + +void bilateral_signed (short** src, short** dst, short** buffer, Dim dim, double sigma, double sens) { + + bilateral (src, dst, buffer, dim, sigma, sens); +} + + + +/* +template void bilateral (T** src, int** dst, int W, int H, int sigmar, double sigmas) { + + time_t t1 = clock (); + + int r = 2.0*sigmas + 0.5; + + double scaleg = 1024.0; + + double MAXINT = 65536.0*65536.0; + double sgmax = 275000/(MAXINT/2.0/sigmar/sigmar+(r+1)*(r+1)/sigmas/sigmas); + printf ("sgmax = %lf\n", sgmax); + if (scaleg>sgmax) + scaleg = sgmax; + + // kernel vector for the spatial gaussian filter * 1024 + int* kernel = new int[1+2*r]; + for (int i=0; i<2*r+1; i++) { + kernel[i] = scaleg / (2.0*sigmas*sigmas) * (i-r)*(i-r) + 0.25; + printf ("kerneli = %d\n", kernel[i]); + } + + // exponential lookup table + int scale = (2.0*sigmar*sigmar) / scaleg; + int scalem = 65535/((1+2*r)*(1+2*r)); + int ec[256000]; + for (int i=0; i<256000; i++) + ec[i] = exp (-i/scaleg) * scalem; + + for (int i=r; i void bilateral (T** src, T** dst, T** buffer, int W, int H, int sigmar, double sigmas) { + + time_t t1 = clock (); + + // buffer for the final image + float** buff_final = new float*[H]; + for (int i=0; i + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +inline double tightestroot (double L, double a, double b, double r1, double r2, double r3); + +#ifndef __COLORCLIP__ +#define __COLORCLIP__ + +#include +#include "median.h" + +// gives back the tightest >0 amplification by which color clipping occures + +inline double tightestroot (double L, double a, double b, double r1, double r2, double r3) { + + register double an = a/500.0, bn = b/200.0, p = (L+16.0)/116.0; + + double coeff3 = r1*an*an*an - r3*bn*bn*bn; + double coeff2 = 3.0 * p * (r1*an*an + r3*bn*bn); + double coeff1 = 3.0 * p*p * (r1*an - r3*bn); + double coeff0 = p*p*p*(r1+r2+r3) - 1.0; + + double a1 = coeff2 / coeff3; + double a2 = coeff1 / coeff3; + double a3 = coeff0 / coeff3; + + double Q = (a1 * a1 - 3.0 * a2) / 9.0; + double R = (2.0 * a1 * a1 * a1 - 9.0 * a1 * a2 + 27.0 * a3) / 54.0; + double Qcubed = Q * Q * Q; + double d = Qcubed - R * R; + +// printf ("input L=%g, a=%g, b=%g\n", L, a, b); +// printf ("c1=%g, c2=%g, c3=%g, c4=%g\n", coeff3, coeff2, coeff1, coeff0); + + + /* Three real roots */ + if (d >= 0) { + double theta = acos(R / sqrt(Qcubed)); + double sqrtQ = sqrt(Q); + double x0 = -2.0 * sqrtQ * cos( theta / 3.0) - a1 / 3.0; + double x1 = -2.0 * sqrtQ * cos((theta + 2.0 * M_PI) / 3.0) - a1 / 3.0; + double x2 = -2.0 * sqrtQ * cos((theta + 4.0 * M_PI) / 3.0) - a1 / 3.0; + +// printf ("3 roots: %g, %g, %g\n", x0, x1, x2); + + SORT3 (x0,x1,x2,a1,a2,a3); + if (a1>0) + return a1; + if (a2>0) + return a2; + if (a3>0) + return a3; + return -1; + } + + /* One real root */ + else { +// double e = pow(sqrt(-d) + fabs(R), 1.0 / 3.0); + double e = exp (1.0 / 3.0 * log (sqrt(-d) + fabs(R))); + + if (R > 0) + e = -e; + + double x0 = (e + Q / e) - a1 / 3.0; + +// printf ("1 root: %g\n", x0); + + if (x0<0) + return -1; + else + return x0; + } +} + + +/******************************************************************************* + * FindCubicRoots + * + * Solve: + * coeff[3] * x^3 + coeff[2] * x^2 + coeff[1] * x + coeff[0] = 0 + * + * returns: + * 3 - 3 real roots + * 1 - 1 real root (2 complex conjugate) + *******************************************************************************/ + +/*long +FindCubicRoots(const FLOAT coeff[4], FLOAT x[3]) +{ + FLOAT a1 = coeff[2] / coeff[3]; + FLOAT a2 = coeff[1] / coeff[3]; + FLOAT a3 = coeff[0] / coeff[3]; + + double_t Q = (a1 * a1 - 3 * a2) / 9; + double_t R = (2 * a1 * a1 * a1 - 9 * a1 * a2 + 27 * a3) / 54; + double_t Qcubed = Q * Q * Q; + double_t d = Qcubed - R * R; + + if (d >= 0) { + double_t theta = acos(R / sqrt(Qcubed)); + double_t sqrtQ = sqrt(Q); + x[0] = -2 * sqrtQ * cos( theta / 3) - a1 / 3; + x[1] = -2 * sqrtQ * cos((theta + 2 * pi) / 3) - a1 / 3; + x[2] = -2 * sqrtQ * cos((theta + 4 * pi) / 3) - a1 / 3; + return (3); + } + + else { + double_t e = pow(sqrt(-d) + fabs(R), 1. / 3.); + if (R > 0) + e = -e; + x[0] = (e + Q / e) - a1 / 3.; + return (1); + } +} +*/ +#endif diff --git a/rtengine/colortemp.cc b/rtengine/colortemp.cc new file mode 100644 index 000000000..92a72c07c --- /dev/null +++ b/rtengine/colortemp.cc @@ -0,0 +1,87 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include + +using namespace rtengine; + +ColorTemp::ColorTemp (double t, double g) : temp(t), green(g) { + + clip (temp, green); +} + +void ColorTemp::clip (double &temp, double &green) { + + if (temp < MINTEMP) + temp = MINTEMP; + else if (temp > MAXTEMP) + temp = MAXTEMP; + + if (green < MINGREEN) + green = MINGREEN; + else if (green > MAXGREEN) + green = MAXGREEN; +} + +void ColorTemp::mul2temp (double rmul, double gmul, double bmul, double& temp, double& green) { + + double maxtemp=20000, mintemp=1000; + double tmpr, tmpg, tmpb; + temp=(maxtemp+mintemp)/2; + while (maxtemp-mintemp>1) { + temp2mul (temp, 1.0, tmpr, tmpg, tmpb); + if (tmpb/tmpr > bmul/rmul) + maxtemp = temp; + else + mintemp = temp; + temp=(maxtemp+mintemp)/2; + } + green = (tmpg/tmpr) / (gmul/rmul); + clip (temp, green); +} + +void ColorTemp::temp2mul (double temp, double green, double& rmul, double& gmul, double& bmul) { + + clip (temp, green); + + double xD; + if (temp<=4000) { + xD = 0.27475e9/(temp*temp*temp) - 0.98598e6/(temp*temp) + 1.17444e3/temp + 0.145986; + } else if (temp<=7000) { + xD = -4.6070e9/(temp*temp*temp) + 2.9678e6/(temp*temp) + 0.09911e3/temp + 0.244063; + } else { + xD = -2.0064e9/(temp*temp*temp) + 1.9018e6/(temp*temp) + 0.24748e3/temp + 0.237040; + } + double yD = -3.0*xD*xD + 2.87*xD - 0.275; + + double X = xD/yD; + double Y = 1.0; + double Z = (1.0-xD-yD)/yD; + + rmul = X * 3.24071 - Y * 1.53726 - Z * 0.498571; + gmul = - X * 0.969258 + Y * 1.87599 + Z * 0.0415557; + bmul = X * 0.0556352 - Y * 0.203996 + Z * 1.05707; + gmul /= green; + + double max = rmul; + if (gmul>max) max = gmul; + if (bmul>max) max = bmul; + rmul /= max; + gmul /= max; + bmul /= max; +} diff --git a/rtengine/colortemp.h b/rtengine/colortemp.h new file mode 100644 index 000000000..8cae8c965 --- /dev/null +++ b/rtengine/colortemp.h @@ -0,0 +1,57 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _COLORTEMP_ +#define _COLORTEMP_ + +#include + +namespace rtengine { + +#define MINTEMP 1200 +#define MAXTEMP 12000 +#define MINGREEN 0.02 +#define MAXGREEN 5.0 + +class ColorTemp { + + private: + double temp; + double green; + + static void clip (double &temp, double &green); + + public: + + ColorTemp () : temp(-1), green(-1) {} + ColorTemp (double t, double g); + ColorTemp (double mulr, double mulg, double mulb) { mul2temp (mulr, mulg, mulb, temp, green); } + + inline double getTemp () { return temp; } + inline double getGreen () { return green; } + + void getMultipliers (double &mulr, double &mulg, double &mulb) { temp2mul (temp, green, mulr, mulg, mulb); } + + static void mul2temp (double rmul, double gmul, double bmul, double& temp, double& green); + static void temp2mul (double temp, double green, double& rmul, double& gmul, double& bmul); + + bool operator== (const ColorTemp& other) { return fabs(temp-other.temp)<1e-10 && fabs(green-other.green)<1e-10; } + bool operator!= (const ColorTemp& other) { return !(*this==other); } +}; +}; +#endif diff --git a/rtengine/common.h b/rtengine/common.h new file mode 100644 index 000000000..6f76831d7 --- /dev/null +++ b/rtengine/common.h @@ -0,0 +1,76 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _COMMON_ +#define _COMMON_ + +#define ISRED(image,row,col) \ + ((image->filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==0) +#define ISGREEN(image,row,col) \ + ((image->filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==1) +#define ISBLUE(image,row,col) \ + ((image->filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==2) + +#define FISRED(filter,row,col) \ + ((filter >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==0 || !filter) +#define FISGREEN(filter,row,col) \ + ((filter >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==1 || !filter) +#define FISBLUE(filter,row,col) \ + ((filter >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==2 || !filter) + +#define CMAXVAL 65535 + +#include + +struct RawImage { + + int width; + int height; + + unsigned filters; + + double red_multiplier; + double green_multiplier; + double blue_multiplier; + + double camwb_red; + double camwb_green; + double camwb_blue; + + int blackpoint; + int rgb_max; + int rotate_deg; + int fuji_width; + + double defgain; + + char *make, *model; + + int exifbase, prefilters, ciff_base, ciff_len; + + unsigned short* allocation; + unsigned short** data; // holds pixel values, data[i][j] corresponds to the ith row and jth column + + float coeff[3][3]; + float icoeff[3][3]; + + int profile_len; + char* profile_data; +}; + +#endif diff --git a/rtengine/coord2d.h b/rtengine/coord2d.h new file mode 100644 index 000000000..a78caf124 --- /dev/null +++ b/rtengine/coord2d.h @@ -0,0 +1,33 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef __COORD2D__ +#define __COORD2D__ + +namespace rtengine { + +class Coord2D { + + public: + double x, y; + Coord2D (double x_, double y_) : x(x_), y(y_) {} + Coord2D () {} + void set (double x_, double y_) { x = x_; y = y_; } +}; +}; +#endif diff --git a/rtengine/cubic.cc b/rtengine/cubic.cc new file mode 100644 index 000000000..9f576d0c8 --- /dev/null +++ b/rtengine/cubic.cc @@ -0,0 +1,82 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +/* Copyright (C) 1997-2001 Ken Turkowski. + * + * All rights reserved. + * + * Warranty Information + * Even though I have reviewed this software, I make no warranty + * or representation, either express or implied, with respect to this + * software, its quality, accuracy, merchantability, or fitness for a + * particular purpose. As a result, this software is provided "as is," + * and you, its user, are assuming the entire risk as to its quality + * and accuracy. + * + * This code may be used and freely distributed as long as it includes + * this copyright notice and the above warranty information. + */ + +#include + + +#define FLOAT float +#define double_t double + +/******************************************************************************* + * FindCubicRoots + * + * Solve: + * coeff[3] * x^3 + coeff[2] * x^2 + coeff[1] * x + coeff[0] = 0 + * + * returns: + * 3 - 3 real roots + * 1 - 1 real root (2 complex conjugate) + *******************************************************************************/ + +long +FindCubicRoots(const FLOAT coeff[4], FLOAT x[3]) +{ + FLOAT a1 = coeff[2] / coeff[3]; + FLOAT a2 = coeff[1] / coeff[3]; + FLOAT a3 = coeff[0] / coeff[3]; + + double_t Q = (a1 * a1 - 3 * a2) / 9; + double_t R = (2 * a1 * a1 * a1 - 9 * a1 * a2 + 27 * a3) / 54; + double_t Qcubed = Q * Q * Q; + double_t d = Qcubed - R * R; + + /* Three real roots */ + if (d >= 0) { + double_t theta = acos(R / sqrt(Qcubed)); + double_t sqrtQ = sqrt(Q); + x[0] = -2 * sqrtQ * cos( theta / 3) - a1 / 3; + x[1] = -2 * sqrtQ * cos((theta + 2 * 3.14159265) / 3) - a1 / 3; + x[2] = -2 * sqrtQ * cos((theta + 4 * 3.14159265) / 3) - a1 / 3; + return (3); + } + + /* One real root */ + else { + double_t e = pow(sqrt(-d) + fabs(R), 1. / 3.); + if (R > 0) + e = -e; + x[0] = (e + Q / e) - a1 / 3.; + return (1); + } +} diff --git a/rtengine/cubint.cc b/rtengine/cubint.cc new file mode 100644 index 000000000..220b6c1c7 --- /dev/null +++ b/rtengine/cubint.cc @@ -0,0 +1,75 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#define A (-0.85) +//#define CLIP(a) ((a>CMAXVAL)?a=CMAXVAL:((a<0)?0:a)) + +inline void cubint (Image16* src, int xs, int ys, double Dx, double Dy, unsigned short *r, unsigned short *g, unsigned short *b, double mul) { + + register double w[4]; + + { register double t1, t2; + t1 = -A*(Dx-1.0)*Dx; + t2 = (3.0-2.0*Dx)*Dx*Dx; + w[3] = t1*Dx; + w[2] = t1*(Dx-1.0) + t2; + w[1] = -t1*Dx + 1.0 - t2; + w[0] = -t1*(Dx-1.0); + } + + register double rd, gd, bd; + double yr[4], yg[4], yb[4]; + + for (int k=ys, kx=0; kr[k][i] * w[ix]; + gd += src->g[k][i] * w[ix]; + bd += src->b[k][i] * w[ix]; + } + yr[kx] = rd; yg[kx] = gd; yb[kx] = bd; + } + + + { register double t1, t2; + t1 = -A*(Dy-1.0)*Dy; + t2 = (3.0-2.0*Dy)*Dy*Dy; + w[3] = t1*Dy; + w[2] = t1*(Dy-1.0) + t2; + w[1] = -t1*Dy + 1.0 - t2; + w[0] = -t1*(Dy-1.0); + } + + rd = gd = bd = 0.0; + for (int i=0; i<4; i++) { + rd += yr[i] * w[i]; + gd += yg[i] * w[i]; + bd += yb[i] * w[i]; + } + + rd*=mul; + gd*=mul; + bd*=mul; + + *r = (int)CLIP(rd); + *g = (int)CLIP(gd); + *b = (int)CLIP(bd); + +// if (xs==100 && ys==100) +// printf ("r=%g, g=%g\n", *r, *g); +} diff --git a/rtengine/cubintch.cc b/rtengine/cubintch.cc new file mode 100644 index 000000000..5e0aa9207 --- /dev/null +++ b/rtengine/cubintch.cc @@ -0,0 +1,61 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ + +inline void cubintch (unsigned short** src, int xs, int ys, double Dx, double Dy, unsigned short *r, double mul) { + + register double w[4]; + + { register double t1, t2; + t1 = -A*(Dx-1.0)*Dx; + t2 = (3.0-2.0*Dx)*Dx*Dx; + w[3] = t1*Dx; + w[2] = t1*(Dx-1.0) + t2; + w[1] = -t1*Dx + 1.0 - t2; + w[0] = -t1*(Dx-1.0); + } + + register double rd; + double yr[4]; + + for (int k=ys, kx=0; k + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include + +#undef CLIPD +#define CLIPD(a) ((a)>0.0?((a)<1.0?(a):1.0):0.0) + + +namespace rtengine { + +Curve::Curve (const std::vector& p) : x(NULL), y(NULL), ypp(NULL) { + + if (p.size()<3) { + kind = 0; + } + else { + kind = p[0]; + if (kind==-1 || kind==1) { + N = (p.size()-1)/2; + x = new double[N]; + y = new double[N]; + int ix = 1; + for (int i=0; i= 0; --k) + ypp[k] = ypp[k] * ypp[k + 1] + u[k]; + + delete [] u; +} + +double Curve::getVal (double t) { + + if (!kind) + return t; + + if (kind==2) { + + if (t<=1e-14) + return 0.0; + double c = -log(2.0)/log(x[2]); + double tv = exp(c*log(t)); + double base = pfull (tv, x[8], x[6], x[5]); + double stretched = base<=1e-14 ? 0.0 : exp(log(base)/c); + + base = pfull (0.5, x[8], x[6], x[5]); + double fc = base<=1e-14 ? 0.0 : exp(log(base)/c); // value of the curve at the center point + if (tx[N-1]) + return y[N-1]; + else if (t 1){ + int k = (k_hi + k_lo) / 2; + if (x[k] > t) + k_hi = k; + else + k_lo = k; + } + + double h = x[k_hi] - x[k_lo]; + if (kind==-1) + return y[k_lo] + (t - x[k_lo]) * ( y[k_hi] - y[k_lo] ) / h; + else if (kind==1) { + double a = (x[k_hi] - t) / h; + double b = (t - x[k_lo]) / h; + double r = a*y[k_lo] + b*y[k_hi] + ((a*a*a - a)*ypp[k_lo] + (b*b*b - b)*ypp[k_hi]) * (h*h)/6.0; + if (r < 0.0) return 0.0; + if (r > 1.0) return 1.0; + return r; + } + else + return t; + } +} + +void Curve::getVal (const std::vector& t, std::vector& res) { + +// TODO!!!! can be made much faster!!! Binary search of getVal(double) at each point can be avoided + + res.resize (t.size()); + for (int i=0; i0) { + if (x>m) + return m + (1.0-m) * tanh (b*(x-m)/(1.0-m)) / tanh (b); + else + return m + m * tanh (b*(x-m)/m) / tanh (b); + } + else { + if (x>m) + return 2.0*x - m - (1.0-m) * tanh (b*(x-m)/(1.0-m)) / tanh (b); + else + return 2.0*x - m - m * tanh (b*(x-m)/m) / tanh (b); + } +} +/* +void CurveFactory::updateCurve3 (int* curve, int* ohistogram, const std::vector& points, double defmul, double ecomp, int black, double hlcompr, double shcompr, double br, double contr, double gamma_, bool igamma, int skip) { + + double def_mul = pow (2.0, defmul); + + // compute parameters of the gamma curve + double start = exp(gamma_*log( -0.099 / ((1.0/gamma_-1.0)*1.099 ))); + double slope = 1.099 * pow (start, 1.0/gamma_-1) - 0.099/start; + double mul = 1.099; + double add = 0.099; + + // theoretical maximum of the curve + double D = gamma_>0 ? gamma (def_mul, gamma_, start, slope, mul, add) : def_mul; + + double a = pow (2.0, ecomp); + double b = black / 65535.0; + + // curve without contrast + double* dcurve = new double[65536]; + + bool needcontrast = contr>0.00001 || contr<-0.00001; + bool needigamma = !needcontrast && igamma && gamma_>0; + + // create a curve if needed + Curve* tcurve = NULL; + if (points.size()>0 && points[0]!=0) + tcurve = new Curve (points); + + for (int i=0; i<=0xffff; i+= i<0xffff-skip ? skip : 1 ) { + + double val = (double)i / 65535.0; + val *= def_mul; + if (gamma_>0) + val = gamma (val, gamma_, start, slope, mul, add); + + val = basecurve (val, a, b, D, hlcompr/100.0, shcompr/100.0); + val = brightness (val, br/100.0); + + if (tcurve) + val = tcurve->getVal (val); + + if (needigamma) + val = igamma2 (val); + + if (val>1.0) + val = 1.0; + else if (val<0.0) + val = 0.0; + dcurve[i] = val; + } + delete tcurve; +/* +if (igamma) { + FILE* f = fopen ("curve.txt","wt"); + for (int i=0; i<65536; i++) +// fprintf (f, "%g\t%g\n", i/65535.0, basel(i/65535.0, 2, 0)); + fprintf (f, "%g\t%g\n", i/65535.0, clower(i/65535.0, 0.500015/0.5, 1.5)); +// fprintf (f, "%g\t%g\n", i/65535.0, basecurve(i/65535.0, 1.25701, 0, 1.47694, 1.0, 1.0)); +// fprintf (f, "%g\t%g\n", i/65535.0, dcurve[i]); + fclose (f); +} +*/ +/* + int prev = 0; + for (int i=1; i<=0xffff-skip; i++) { + if (i%skip==0) { + prev+=skip; + continue; + } + dcurve[i] = ( dcurve[prev] * (skip - i%skip) + dcurve[prev+skip] * (i%skip) ) / skip; + } + + if (needcontrast) { + // compute mean luminance of the image with the curve applied + int sum = 0; + double avg = 0; + for (int i=0; i<=0xffff; i++) { + avg += dcurve[i] * ohistogram[i]; + sum += ohistogram[i]; + } + avg /= sum; + + // compute contrast parameter + double contr_b = contr / 20; + if (contr_b>=0 && contr_b < 0.00001) + contr_b = 0.00001; + else if (contr_b<0 && contr_b > -0.00001) + contr_b = -0.00001; + + // apply contrast enhancement + for (int i=0; i<=0xffff; i++) { + double val = centercontrast (dcurve[i], contr_b, avg); + if (igamma && gamma_>0) + val = igamma2 (val); + if (val>1.0) val = 1.0; + if (val<0.0) val = 0.0; + curve[i] = (int) (65535.0 * val); + } + } + else + for (int i=0; i<=0xffff; i++) + curve[i] = (int) (65535.0 * dcurve[i]); + delete [] dcurve; +}*/ + +void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, double shcompr, double br, double contr, double defmul, double gamma_, bool igamma, const std::vector& curvePoints, unsigned int* histogram, int* outCurve, unsigned int* outBeforeCCurveHistogram, int skip) { + + double def_mul = pow (2.0, defmul); + + // compute parameters of the gamma curve + double start = exp(gamma_*log( -0.099 / ((1.0/gamma_-1.0)*1.099 ))); + double slope = 1.099 * pow (start, 1.0/gamma_-1) - 0.099/start; + double mul = 1.099; + double add = 0.099; + + // theoretical maximum of the curve + double D = gamma_>0 ? gamma (def_mul, gamma_, start, slope, mul, add) : def_mul; + + // a: slope of the curve, black: starting point at the x axis + double a = pow (2.0, ecomp); + + // curve without contrast + double* dcurve = new double[65536]; + + // check if contrast curve is needed + bool needcontrast = contr>0.00001 || contr<-0.00001; + + // check if inverse gamma is needed at the end + bool needigamma = !needcontrast && igamma && gamma_>0; + + // create a curve if needed + Curve* tcurve = NULL; + if (curvePoints.size()>0 && curvePoints[0]!=0) + tcurve = new Curve (curvePoints); + + // clear array that stores histogram valid before applying the custom curve + if (outBeforeCCurveHistogram) + memset (outBeforeCCurveHistogram, 0, 256*sizeof(int)); + + for (int i=0; i<=0xffff; i+= i<0xffff-skip ? skip : 1 ) { + + // change to [0,1] rage + double val = (double)i / 65535.0; + + // apply default multiplier (that is >1 if highlight recovery is on) + val *= def_mul; + + // gamma correction + if (gamma_>0) + val = gamma (val, gamma_, start, slope, mul, add); + + // apply base curve, thus, exposure compensation and black point with shadow and highlight protection + val = basecurve (val, a, black, D, hlcompr/100.0, shcompr/100.0); + + // apply brightness curve + val = brightness (val, br/100.0); + + // apply custom/parametric curve, if any + if (tcurve) { + if (outBeforeCCurveHistogram) { + double hval = val; +// if (needigamma) +// hval = igamma2 (hval); + int hi = (int)(255.0*CLIPD(hval)); + outBeforeCCurveHistogram[hi]+=histogram[i] ; + } + val = tcurve->getVal (val); + } + + // if inverse gamma is needed, do it (standard sRGB inverse gamma is applied) + if (needigamma) + val = igamma2 (val); + + // store result in a temporary array + dcurve[i] = CLIPD(val); + } + delete tcurve; + + // if skip>1, let apply linear interpolation in the skipped points of the curve + int prev = 0; + for (int i=1; i<=0xffff-skip; i++) { + if (i%skip==0) { + prev+=skip; + continue; + } + dcurve[i] = ( dcurve[prev] * (skip - i%skip) + dcurve[prev+skip] * (i%skip) ) / skip; + } + + if (needcontrast) { + // compute mean luminance of the image with the curve applied + int sum = 0; + double avg = 0; + for (int i=0; i<=0xffff; i++) { + avg += dcurve[i] * histogram[i]; + sum += histogram[i]; + } + avg /= sum; + + // compute contrast parameter + double contr_b = contr / 20; + if (contr_b>=0 && contr_b < 0.00001) + contr_b = 0.00001; + else if (contr_b<0 && contr_b > -0.00001) + contr_b = -0.00001; + + // apply contrast enhancement + for (int i=0; i<=0xffff; i++) { + double val = centercontrast (dcurve[i], contr_b, avg); + if (igamma && gamma_>0) + val = igamma2 (val); + outCurve[i] = (int) (65535.0 * CLIPD(val)); + } + } + else + for (int i=0; i<=0xffff; i++) + outCurve[i] = (int) (65535.0 * dcurve[i]); + delete [] dcurve; +} + + +int CurveFactory::gammatab [65536]; +int CurveFactory::igammatab_srgb [65536]; +int CurveFactory::gammatab_srgb [65536]; + +void CurveFactory::init () { + + for (int i=0; i<65536; i++) + gammatab_srgb[i] = (int)(65535 * gamma2 (i/65535.0)); + for (int i=0; i<65536; i++) + igammatab_srgb[i] = (int)(65535 * igamma2 (i/65535.0)); + for (int i=0; i<65536; i++) + gammatab[i] = (int)(65535 * pow (i/65535.0, 0.454545)); + +/* FILE* f = fopen ("c.txt", "wt"); + for (int i=0; i<256; i++) + fprintf (f, "%g %g\n", i/255.0, clower (i/255.0, 2.0, 1.0)); + fclose (f);*/ +} + +} + diff --git a/rtengine/curves.h b/rtengine/curves.h new file mode 100644 index 000000000..39b61bb1f --- /dev/null +++ b/rtengine/curves.h @@ -0,0 +1,158 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef __CURVES_H__ +#define __CURVES_H__ + +#include +#include +#include +#include + +namespace rtengine { + +class CurveFactory { + + friend class Curve; + + protected: + + // look-up tables for the standard srgb gamma and its inverse (filled by init()) + static int igammatab_srgb[65536]; + static int gammatab_srgb[65536]; + // look-up tables for the simple exponential gamma + static int gammatab[65536]; + + // functions calculating the parameters of the contrast curve based on the desired slope at the center + static double solve_upper (double m, double c, double deriv); + static double solve_lower (double m, double c, double deriv); + static double dupper (const double b, const double m, const double c); + static double dlower (const double b, const double m, const double c); + + // basic convex function between (0,0) and (1,1). m1 and m2 controls the slope at the start and end point + static inline double basel (double x, double m1, double m2) { + if (x==0.0) + return 0.0; + double k = sqrt ((m1-1.0)*(m1-m2)/2) / (1.0-m2); + double l = (m1-m2) / (1.0-m2) + k; + double lx = log(x); + return m2*x + (1.0-m2)*(2.0 - exp(k*lx))*exp(l*lx); + } + // basic concave function between (0,0) and (1,1). m1 and m2 controls the slope at the start and end point + static inline double baseu (double x, double m1, double m2) { + return 1.0 - basel(1.0-x, m1, m2); + } + // convex curve between (0,0) and (1,1) with slope m at (0,0). hr controls the highlight recovery + static inline double cupper (double x, double m, double hr) { + if (hr>1.0) + return baseu (x, m, 2.0*(hr-1.0)/m); + double x1 = (1.0-hr)/m; + double x2 = x1 + hr; + if (x>=x2) return 1.0; + if (x1), hr,sr: highlight,shadow recovery + static inline double basecurve (double x, double a, double b, double D, double hr, double sr) { + double m = b+0.5/a0) + return brightnessbase (x, amount); + else + return 1.0 - brightnessbase (1.0-x, -amount); + } + + public: + + static void init (); + + static inline double centercontrast (double x, double b, double m); + + // standard srgb gamma and its inverse + static inline double gamma2 (double x) { + return x <= 0.00304 ? x*12.92 : 1.055*exp(log(x)/2.4)-0.055; + } + static inline double igamma2 (double x) { + return x <= 0.03928 ? x/12.92 : exp(log((x+0.055)/1.055)*2.4); + } + // gamma function with adjustable parameters + static inline double gamma (double x, double gamma, double start, double slope, double mul, double add){ + return (x <= start ? x*slope : exp(log(x)/gamma)*mul-add); + } + + // gamma functions on [0,65535] based on look-up tables + static inline int gamma_srgb (int x) { return gammatab_srgb[x]; } + static inline int gamma (int x) { return gammatab[x]; } + static inline int igamma_srgb (int x) { return igammatab_srgb[x]; } + + public: +// static void updateCurve3 (int* curve, int* ohistogram, const std::vector& cpoints, double defmul, double ecomp, int black, double hlcompr, double shcompr, double br, double contr, double gamma_, bool igamma, int skip=1); + static void complexCurve (double ecomp, double black, double hlcompr, double shcompr, double br, double contr, double defmul, double gamma_, bool igamma, const std::vector& curvePoints, unsigned int* histogram, int* outCurve, unsigned int* outBeforeCCurveHistogram, int skip=1); + +}; + +class Curve { + + protected: + int N; + double* x; + double* y; + double* ypp; + int kind; // = -1: linear interp., 0: empty, 1: spline interp., 2: parametric + + protected: + void spline_cubic_set (); + static inline double p00 (double x, double prot) { return CurveFactory::clower (x, 2.0, prot); } + static inline double p11 (double x, double prot) { return CurveFactory::cupper (x, 2.0, prot); } + static inline double p01 (double x, double prot) { return x<=0.5 ? CurveFactory::clower (x*2, 2.0, prot)/2.0 : 0.5 + CurveFactory::cupper ((x-0.5)*2, 2.0, prot)/2.0; } + static inline double p10 (double x, double prot) { return x<=0.5 ? CurveFactory::cupper (x*2, 2.0, prot)/2.0 : 0.5 + CurveFactory::clower ((x-0.5)*2, 2.0, prot)/2.0; } + static inline double pfull (double x, double prot, double sh, double hl) { return (1-sh)*(1-hl)*p00(x,prot) + sh*hl*p11(x,prot) + (1-sh)*hl*p01(x,prot) + sh*(1-hl)*p10(x,prot); } + + public: + + Curve (const std::vector& points); + ~Curve (); + + double getVal (double x); + void getVal (const std::vector& t, std::vector& res); +}; +}; + +#endif diff --git a/rtengine/dcraw.c b/rtengine/dcraw.c new file mode 100644 index 000000000..338d0cd92 --- /dev/null +++ b/rtengine/dcraw.c @@ -0,0 +1,8784 @@ +/* + dcraw.c -- Dave Coffin's raw photo decoder + Copyright 1997-2009 by Dave Coffin, dcoffin a cybercom o net + + This is a command-line ANSI C program to convert raw photos from + any digital camera on any computer running any operating system. + + No license is required to download and use dcraw.c. However, + to lawfully redistribute dcraw, you must either (a) offer, at + no extra charge, full source code* for all executable files + containing RESTRICTED functions, (b) distribute this code under + the GPL Version 2 or later, (c) remove all RESTRICTED functions, + re-implement them, or copy them from an earlier, unrestricted + Revision of dcraw.c, or (d) purchase a license from the author. + + The functions that process Foveon images have been RESTRICTED + since Revision 1.237. All other code remains free for all uses. + + *If you have not modified dcraw.c in any way, a link to my + homepage qualifies as "full source code". + + $Revision: 1.432 $ + $Date: 2009/12/25 18:51:16 $ + */ + +#define VERSION "8.99" + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* + NO_JPEG disables decoding of compressed Kodak DC120 files. + NO_LCMS disables the "-p" option. + */ +#ifndef NO_JPEG +#include +#endif +#ifndef NO_LCMS +#include +#endif +#ifdef LOCALEDIR +#include +#define _(String) gettext(String) +#else +#define _(String) (String) +#endif +#ifdef DJGPP +#define fseeko fseek +#define ftello ftell +#else +#define fgetc getc_unlocked +#endif +#ifdef __CYGWIN__ +#include +#endif +#ifdef WIN32 +#include +#include +#pragma comment(lib, "ws2_32.lib") +#define snprintf _snprintf +#define strcasecmp stricmp +#define strncasecmp strnicmp +typedef __int64 INT64; +typedef unsigned __int64 UINT64; +#else +#include +#include +#include +typedef long long INT64; +typedef unsigned long long UINT64; +#endif + +#ifdef LJPEG_DECODE +#error Please compile dcraw.c by itself. +#error Do not link it with ljpeg_decode. +#endif + +#ifndef LONG_BIT +#define LONG_BIT (8 * sizeof (long)) +#endif + +#define ushort UshORt +typedef unsigned char uchar; +typedef unsigned short ushort; + +/* + All global variables are defined here, and all functions that + access them are prefixed with "CLASS". Note that a thread-safe + C++ class cannot have non-const static local variables. + */ +FILE *ifp, *ofp; +short order; +const char *ifname; +char *meta_data; +char cdesc[5], desc[512], make[64], model[64], model2[64], artist[64]; +float flash_used, canon_ev, iso_speed, shutter, aperture, focal_len; +time_t timestamp; +unsigned shot_order, kodak_cbpp, filters, exif_cfa, unique_id; +off_t strip_offset, data_offset; +off_t thumb_offset, meta_offset, profile_offset; +unsigned thumb_length, meta_length, profile_length; +unsigned thumb_misc, *oprof, fuji_layout, shot_select=0, multi_out=0; +unsigned tiff_nifds, tiff_samples, tiff_bps, tiff_compress; +unsigned black, maximum, mix_green, raw_color, zero_is_bad; +unsigned zero_after_ff, is_raw, dng_version, is_foveon, data_error; +unsigned tile_width, tile_length, gpsdata[32], load_flags; +ushort raw_height, raw_width, height, width, top_margin, left_margin; +ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height; +int flip, tiff_flip, colors; +double pixel_aspect, aber[4]={1,1,1,1}, gamm[6]={ 0.45,4.5,0,0,0,0 }; +ushort (*image)[4], white[8][8], curve[0x10000], cr2_slice[3], sraw_mul[4]; +float bright=1, user_mul[4]={0,0,0,0}, threshold=0; +int half_size=0, four_color_rgb=0, document_mode=0, highlight=0; +int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_matrix=-1; +int output_color=1, output_bps=8, output_tiff=0, med_passes=0; +int no_auto_bright=0; +unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX }; +float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4]; +const double xyz_rgb[3][3] = { /* XYZ from RGB */ + { 0.412453, 0.357580, 0.180423 }, + { 0.212671, 0.715160, 0.072169 }, + { 0.019334, 0.119193, 0.950227 } }; +const float d65_white[3] = { 0.950456, 1, 1.088754 }; +int histogram[4][0x2000]; +void (*write_thumb)(), (*write_fun)(); +void (*load_raw)(), (*thumb_load_raw)(); +jmp_buf failure; + +struct decode { + struct decode *branch[2]; + int leaf; +} first_decode[2048], *second_decode, *free_decode; + +struct tiff_ifd { + int width, height, bps, comp, phint, offset, flip, samples, bytes; +} tiff_ifd[10]; + +struct ph1 { + int format, key_off, black, black_off, split_col, tag_21a; + float tag_210; +} ph1; + +#define CLASS + +#define FORC(cnt) for (c=0; c < cnt; c++) +#define FORC3 FORC(3) +#define FORC4 FORC(4) +#define FORCC FORC(colors) + +#define SQR(x) ((x)*(x)) +#define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define LIM(x,min,max) MAX(min,MIN(x,max)) +#define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y)) +#define CLIP(x) LIM(x,0,65535) +#define SWAP(a,b) { a ^= b; a ^= (b ^= a); } + +/* + In order to inline this calculation, I make the risky + assumption that all filter patterns can be described + by a repeating pattern of eight rows and two columns + + Do not use the FC or BAYER macros with the Leaf CatchLight, + because its pattern is 16x16, not 2x8. + + Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2 + + PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1 + 0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4: + + 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 + 0 G M G M G M 0 C Y C Y C Y 0 Y C Y C Y C 0 G M G M G M + 1 C Y C Y C Y 1 M G M G M G 1 M G M G M G 1 Y C Y C Y C + 2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y + 3 C Y C Y C Y 3 G M G M G M 3 G M G M G M + 4 C Y C Y C Y 4 Y C Y C Y C + PowerShot A5 5 G M G M G M 5 G M G M G M + 0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y + 7 M G M G M G 7 M G M G M G + 0 1 2 3 4 5 + 0 C Y C Y C Y + 1 G M G M G M + 2 C Y C Y C Y + 3 M G M G M G + + All RGB cameras use one of these Bayer grids: + + 0x16161616: 0x61616161: 0x49494949: 0x94949494: + + 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 + 0 B G B G B G 0 G R G R G R 0 G B G B G B 0 R G R G R G + 1 G R G R G R 1 B G B G B G 1 R G R G R G 1 G B G B G B + 2 B G B G B G 2 G R G R G R 2 G B G B G B 2 R G R G R G + 3 G R G R G R 3 B G B G B G 3 R G R G R G 3 G B G B G B + */ + +#define FC(row,col) \ + (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) + +#define BAYER(row,col) \ + image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)] + +#define BAYER2(row,col) \ + image[((row) >> shrink)*iwidth + ((col) >> shrink)][fc(row,col)] + +int CLASS fc (int row, int col) +{ + static const char filter[16][16] = + { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 }, + { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 }, + { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 }, + { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 }, + { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 }, + { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 }, + { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 }, + { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 }, + { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 }, + { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 }, + { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 }, + { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 }, + { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 }, + { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 }, + { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 }, + { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } }; + + if (filters != 1) return FC(row,col); + return filter[(row+top_margin) & 15][(col+left_margin) & 15]; +} + +#ifndef __GLIBC__ +char *my_memmem (char *haystack, size_t haystacklen, + char *needle, size_t needlelen) +{ + char *c; + for (c = haystack; c <= haystack + haystacklen - needlelen; c++) + if (!memcmp (c, needle, needlelen)) + return c; + return 0; +} +#define memmem my_memmem +#endif + +void CLASS merror (void *ptr, const char *where) +{ + if (ptr) return; + fprintf (stderr,_("%s: Out of memory in %s\n"), ifname, where); + longjmp (failure, 1); +} + +void CLASS derror() +{ + if (!data_error) { + fprintf (stderr, "%s: ", ifname); + if (feof(ifp)) + fprintf (stderr,_("Unexpected end of file\n")); + else + fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp)); + } + data_error++; +} + +ushort CLASS sget2 (uchar *s) +{ + if (order == 0x4949) /* "II" means little-endian */ + return s[0] | s[1] << 8; + else /* "MM" means big-endian */ + return s[0] << 8 | s[1]; +} + +ushort CLASS get2() +{ + uchar str[2] = { 0xff,0xff }; + fread (str, 1, 2, ifp); + return sget2(str); +} + +unsigned CLASS sget4 (uchar *s) +{ + if (order == 0x4949) + return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; + else + return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; +} +#define sget4(s) sget4((uchar *)s) + +unsigned CLASS get4() +{ + uchar str[4] = { 0xff,0xff,0xff,0xff }; + fread (str, 1, 4, ifp); + return sget4(str); +} + +unsigned CLASS getint (int type) +{ + return type == 3 ? get2() : get4(); +} + +float CLASS int_to_float (int i) +{ + union { int i; float f; } u; + u.i = i; + return u.f; +} + +double CLASS getreal (int type) +{ + union { char c[8]; double d; } u; + int i, rev; + + switch (type) { + case 3: return (unsigned short) get2(); + case 4: return (unsigned int) get4(); + case 5: u.d = (unsigned int) get4(); + return u.d / (unsigned int) get4(); + case 8: return (signed short) get2(); + case 9: return (signed int) get4(); + case 10: u.d = (signed int) get4(); + return u.d / (signed int) get4(); + case 11: return int_to_float (get4()); + case 12: + rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234)); + for (i=0; i < 8; i++) + u.c[i ^ rev] = fgetc(ifp); + return u.d; + default: return fgetc(ifp); + } +} + +void CLASS read_shorts (ushort *pixel, int count) +{ + if (fread (pixel, 2, count, ifp) < count) derror(); + if ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) + swab (pixel, pixel, count*2); +} + +void CLASS canon_black (double dark[2], int nblack) +{ + int c, diff, row, col; + + if (!nblack) return; + FORC(2) dark[c] /= nblack >> 1; + if ((diff = dark[0] - dark[1])) + for (row=0; row < height; row++) + for (col=1; col < width; col+=2) + BAYER(row,col) += diff; + dark[1] += diff; + black = (dark[0] + dark[1] + 1) / 2; +} + +void CLASS canon_600_fixed_wb (int temp) +{ + static const short mul[4][5] = { + { 667, 358,397,565,452 }, + { 731, 390,367,499,517 }, + { 1119, 396,348,448,537 }, + { 1399, 485,431,508,688 } }; + int lo, hi, i; + float frac=0; + + for (lo=4; --lo; ) + if (*mul[lo] <= temp) break; + for (hi=0; hi < 3; hi++) + if (*mul[hi] >= temp) break; + if (lo != hi) + frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]); + for (i=1; i < 5; i++) + pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]); +} + +/* Return values: 0 = white 1 = near white 2 = not white */ +int CLASS canon_600_color (int ratio[2], int mar) +{ + int clipped=0, target, miss; + + if (flash_used) { + if (ratio[1] < -104) + { ratio[1] = -104; clipped = 1; } + if (ratio[1] > 12) + { ratio[1] = 12; clipped = 1; } + } else { + if (ratio[1] < -264 || ratio[1] > 461) return 2; + if (ratio[1] < -50) + { ratio[1] = -50; clipped = 1; } + if (ratio[1] > 307) + { ratio[1] = 307; clipped = 1; } + } + target = flash_used || ratio[1] < 197 + ? -38 - (398 * ratio[1] >> 10) + : -123 + (48 * ratio[1] >> 10); + if (target - mar <= ratio[0] && + target + 20 >= ratio[0] && !clipped) return 0; + miss = target - ratio[0]; + if (abs(miss) >= mar*4) return 2; + if (miss < -20) miss = -20; + if (miss > mar) miss = mar; + ratio[0] = target - miss; + return 1; +} + +void CLASS canon_600_auto_wb() +{ + int mar, row, col, i, j, st, count[] = { 0,0 }; + int test[8], total[2][8], ratio[2][2], stat[2]; + + memset (&total, 0, sizeof total); + i = canon_ev + 0.5; + if (i < 10) mar = 150; + else if (i > 12) mar = 20; + else mar = 280 - 20 * i; + if (flash_used) mar = 80; + for (row=14; row < height-14; row+=4) + for (col=10; col < width; col+=2) { + for (i=0; i < 8; i++) + test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] = + BAYER(row+(i >> 1),col+(i & 1)); + for (i=0; i < 8; i++) + if (test[i] < 150 || test[i] > 1500) goto next; + for (i=0; i < 4; i++) + if (abs(test[i] - test[i+4]) > 50) goto next; + for (i=0; i < 2; i++) { + for (j=0; j < 4; j+=2) + ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j]; + stat[i] = canon_600_color (ratio[i], mar); + } + if ((st = stat[0] | stat[1]) > 1) goto next; + for (i=0; i < 2; i++) + if (stat[i]) + for (j=0; j < 2; j++) + test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10; + for (i=0; i < 8; i++) + total[st][i] += test[i]; + count[st]++; +next: ; + } + if (count[0] | count[1]) { + st = count[0]*200 < count[1]; + for (i=0; i < 4; i++) + pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]); + } +} + +void CLASS canon_600_coeff() +{ + static const short table[6][12] = { + { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 }, + { -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 }, + { -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 }, + { -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 }, + { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 }, + { -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } }; + int t=0, i, c; + float mc, yc; + + mc = pre_mul[1] / pre_mul[2]; + yc = pre_mul[3] / pre_mul[2]; + if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1; + if (mc > 1.28 && mc <= 2) { + if (yc < 0.8789) t=3; + else if (yc <= 2) t=4; + } + if (flash_used) t=5; + for (raw_color = i=0; i < 3; i++) + FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0; +} + +void CLASS canon_600_load_raw() +{ + uchar data[1120], *dp; + ushort pixel[896], *pix; + int irow, row, col, val; + static const short mul[4][2] = + { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } }; + + for (irow=row=0; irow < height; irow++) { + if (fread (data, 1, raw_width*5/4, ifp) < raw_width*5/4) derror(); + for (dp=data, pix=pixel; dp < data+1120; dp+=10, pix+=8) { + pix[0] = (dp[0] << 2) + (dp[1] >> 6 ); + pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3); + pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3); + pix[3] = (dp[4] << 2) + (dp[1] & 3); + pix[4] = (dp[5] << 2) + (dp[9] & 3); + pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3); + pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3); + pix[7] = (dp[8] << 2) + (dp[9] >> 6 ); + } + for (col=0; col < width; col++) + BAYER(row,col) = pixel[col]; + for (col=width; col < raw_width; col++) + black += pixel[col]; + if ((row+=2) > height) row = 1; + } + if (raw_width > width) + black = black / ((raw_width - width) * height) - 4; + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + if ((val = BAYER(row,col) - black) < 0) val = 0; + val = val * mul[row & 3][col & 1] >> 9; + BAYER(row,col) = val; + } + canon_600_fixed_wb(1311); + canon_600_auto_wb(); + canon_600_coeff(); + maximum = (0x3ff - black) * 1109 >> 9; + black = 0; +} + +void CLASS remove_zeroes() +{ + unsigned row, col, tot, n, r, c; + + for (row=0; row < height; row++) + for (col=0; col < width; col++) + if (BAYER(row,col) == 0) { + tot = n = 0; + for (r = row-2; r <= row+2; r++) + for (c = col-2; c <= col+2; c++) + if (r < height && c < width && + FC(r,c) == FC(row,col) && BAYER(r,c)) + tot += (n++,BAYER(r,c)); + if (n) BAYER(row,col) = tot/n; + } +} + +int CLASS canon_s2is() +{ + unsigned row; + + for (row=0; row < 100; row++) { + fseek (ifp, row*3340 + 3284, SEEK_SET); + if (getc(ifp) > 15) return 1; + } + return 0; +} + +/* + getbits(-1) initializes the buffer + getbits(n) where 0 <= n <= 25 returns an n-bit integer + */ +unsigned CLASS getbithuff (int nbits, ushort *huff) +{ + static unsigned bitbuf=0; + static int vbits=0, reset=0; + unsigned c; + + if (nbits == -1) + return bitbuf = vbits = reset = 0; + if (nbits == 0 || vbits < 0) return 0; + while (!reset && vbits < nbits && (c = fgetc(ifp)) != EOF && + !(reset = zero_after_ff && c == 0xff && fgetc(ifp))) { + bitbuf = (bitbuf << 8) + (uchar) c; + vbits += 8; + } + c = bitbuf << (32-vbits) >> (32-nbits); + if (huff) { + vbits -= huff[c] >> 8; + c = (uchar) huff[c]; + } else + vbits -= nbits; + if (vbits < 0) derror(); + return c; +} + +#define getbits(n) getbithuff(n,0) +#define gethuff(h) getbithuff(*h,h+1) + +/* + Construct a decode tree according the specification in *source. + The first 16 bytes specify how many codes should be 1-bit, 2-bit + 3-bit, etc. Bytes after that are the leaf values. + + For example, if the source is + + { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, + 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff }, + + then the code is + + 00 0x04 + 010 0x03 + 011 0x05 + 100 0x06 + 101 0x02 + 1100 0x07 + 1101 0x01 + 11100 0x08 + 11101 0x09 + 11110 0x00 + 111110 0x0a + 1111110 0x0b + 1111111 0xff + */ +ushort * CLASS make_decoder_ref (const uchar **source) +{ + int max, len, h, i, j; + const uchar *count; + ushort *huff; + + count = (*source += 16) - 17; + for (max=16; max && !count[max]; max--); + huff = (ushort *) calloc (1 + (1 << max), sizeof *huff); + merror (huff, "make_decoder()"); + huff[0] = max; + for (h=len=1; len <= max; len++) + for (i=0; i < count[len]; i++, ++*source) + for (j=0; j < 1 << (max-len); j++) + if (h <= 1 << max) + huff[h++] = len << 8 | **source; + return huff; +} + +ushort * CLASS make_decoder (const uchar *source) +{ + return make_decoder_ref (&source); +} + +void CLASS crw_init_tables (unsigned table, ushort *huff[2]) +{ + static const uchar first_tree[3][29] = { + { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, + 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff }, + { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0, + 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff }, + { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0, + 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff }, + }; + static const uchar second_tree[3][180] = { + { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139, + 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08, + 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0, + 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42, + 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57, + 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9, + 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98, + 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6, + 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4, + 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7, + 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1, + 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64, + 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba, + 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4, + 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff }, + { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140, + 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06, + 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32, + 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51, + 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26, + 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59, + 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9, + 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99, + 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85, + 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8, + 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a, + 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9, + 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8, + 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8, + 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff }, + { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117, + 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08, + 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22, + 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34, + 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41, + 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48, + 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69, + 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8, + 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94, + 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a, + 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6, + 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62, + 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5, + 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3, + 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff } + }; + if (table > 2) table = 2; + huff[0] = make_decoder ( first_tree[table]); + huff[1] = make_decoder (second_tree[table]); +} + +/* + Return 0 if the image starts with compressed data, + 1 if it starts with uncompressed low-order bits. + + In Canon compressed data, 0xff is always followed by 0x00. + */ +int CLASS canon_has_lowbits() +{ + uchar test[0x4000]; + int ret=1, i; + + fseek (ifp, 0, SEEK_SET); + fread (test, 1, sizeof test, ifp); + for (i=540; i < sizeof test - 1; i++) + if (test[i] == 0xff) { + if (test[i+1]) return 1; + ret=0; + } + return ret; +} + +void CLASS canon_compressed_load_raw() +{ + ushort *pixel, *prow, *huff[2]; + int nblocks, lowbits, i, c, row, r, col, save, val, nblack=0; + unsigned irow, icol; + int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2]; + double dark[2] = { 0,0 }; + + crw_init_tables (tiff_compress, huff); + pixel = (ushort *) calloc (raw_width*8, sizeof *pixel); + merror (pixel, "canon_compressed_load_raw()"); + lowbits = canon_has_lowbits(); + if (!lowbits) maximum = 0x3ff; + fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET); + zero_after_ff = 1; + getbits(-1); + for (row=0; row < raw_height; row+=8) { + nblocks = MIN (8, raw_height-row) * raw_width >> 6; + for (block=0; block < nblocks; block++) { + memset (diffbuf, 0, sizeof diffbuf); + for (i=0; i < 64; i++ ) { + leaf = gethuff(huff[i > 0]); + if (leaf == 0 && i) break; + if (leaf == 0xff) continue; + i += leaf >> 4; + len = leaf & 15; + if (len == 0) continue; + diff = getbits(len); + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + if (i < 64) diffbuf[i] = diff; + } + diffbuf[0] += carry; + carry = diffbuf[0]; + for (i=0; i < 64; i++ ) { + if (pnum++ % raw_width == 0) + base[0] = base[1] = 512; + if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10) + derror(); + } + } + if (lowbits) { + save = ftell(ifp); + fseek (ifp, 26 + row*raw_width/4, SEEK_SET); + for (prow=pixel, i=0; i < raw_width*2; i++) { + c = fgetc(ifp); + for (r=0; r < 8; r+=2, prow++) { + val = (*prow << 2) + ((c >> r) & 3); + if (raw_width == 2672 && val < 512) val += 2; + *prow = val; + } + } + fseek (ifp, save, SEEK_SET); + } + for (r=0; r < 8; r++) { + irow = row - top_margin + r; + if (irow >= height) continue; + for (col=0; col < raw_width; col++) { + icol = col - left_margin; + if (icol < width) + BAYER(irow,icol) = pixel[r*raw_width+col]; + else if (col > 1 && (unsigned) (col-left_margin+2) > width+3) + dark[icol & 1] += (nblack++,pixel[r*raw_width+col]); + } + } + } + free (pixel); + FORC(2) free (huff[c]); + canon_black (dark, nblack); +} + +/* + Not a full implementation of Lossless JPEG, just + enough to decode Canon, Kodak and Adobe DNG images. + */ +struct jhead { + int bits, high, wide, clrs, sraw, psv, restart, vpred[6]; + ushort *huff[6], *free[4], *row; +}; + +int CLASS ljpeg_start (struct jhead *jh, int info_only) +{ + int c, tag, len; + uchar data[0x10000]; + const uchar *dp; + + memset (jh, 0, sizeof *jh); + jh->restart = INT_MAX; + fread (data, 2, 1, ifp); + if (data[1] != 0xd8) return 0; + do { + fread (data, 2, 2, ifp); + tag = data[0] << 8 | data[1]; + len = (data[2] << 8 | data[3]) - 2; + if (tag <= 0xff00) return 0; + fread (data, 1, len, ifp); + switch (tag) { + case 0xffc3: + jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3; + case 0xffc0: + jh->bits = data[0]; + jh->high = data[1] << 8 | data[2]; + jh->wide = data[3] << 8 | data[4]; + jh->clrs = data[5] + jh->sraw; + if (len == 9 && !dng_version) getc(ifp); + break; + case 0xffc4: + if (info_only) break; + for (dp = data; dp < data+len && (c = *dp++) < 4; ) + jh->free[c] = jh->huff[c] = make_decoder_ref (&dp); + break; + case 0xffda: + jh->psv = data[1+data[0]*2]; + jh->bits -= data[3+data[0]*2] & 15; + break; + case 0xffdd: + jh->restart = data[0] << 8 | data[1]; + } + } while (tag != 0xffda); + if (info_only) return 1; + FORC(5) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c]; + if (jh->sraw) { + FORC(4) jh->huff[2+c] = jh->huff[1]; + FORC(jh->sraw) jh->huff[1+c] = jh->huff[0]; + } + jh->row = (ushort *) calloc (jh->wide*jh->clrs, 4); + merror (jh->row, "ljpeg_start()"); + return zero_after_ff = 1; +} + +void CLASS ljpeg_end (struct jhead *jh) +{ + int c; + FORC4 if (jh->free[c]) free (jh->free[c]); + free (jh->row); +} + +int CLASS ljpeg_diff (ushort *huff) +{ + int len, diff; + + len = gethuff(huff); + if (len == 16 && (!dng_version || dng_version >= 0x1010000)) + return -32768; + diff = getbits(len); + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + return diff; +} + +ushort * CLASS ljpeg_row (int jrow, struct jhead *jh) +{ + int col, c, diff, pred, spred=0; + ushort mark=0, *row[3]; + + if (jrow * jh->wide % jh->restart == 0) { + FORC(6) jh->vpred[c] = 1 << (jh->bits-1); + if (jrow) { + fseek (ifp, -2, SEEK_CUR); + do mark = (mark << 8) + (c = fgetc(ifp)); + while (c != EOF && mark >> 4 != 0xffd); + } + getbits(-1); + } + FORC3 row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1); + for (col=0; col < jh->wide; col++) + FORC(jh->clrs) { + diff = ljpeg_diff (jh->huff[c]); + if (jh->sraw && c <= jh->sraw && (col | c)) + pred = spred; + else if (col) pred = row[0][-jh->clrs]; + else pred = (jh->vpred[c] += diff) - diff; + if (jrow && col) switch (jh->psv) { + case 1: break; + case 2: pred = row[1][0]; break; + case 3: pred = row[1][-jh->clrs]; break; + case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break; + case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break; + case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break; + case 7: pred = (pred + row[1][0]) >> 1; break; + default: pred = 0; + } + if ((**row = pred + diff) >> jh->bits) derror(); + if (c <= jh->sraw) spred = **row; + row[0]++; row[1]++; + } + return row[2]; +} + +void CLASS lossless_jpeg_load_raw() +{ + int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0, nblack=0; + double dark[2] = { 0,0 }; + struct jhead jh; + int min=INT_MAX; + ushort *rp; + + if (!ljpeg_start (&jh, 0)) return; + jwide = jh.wide * jh.clrs; + + for (jrow=0; jrow < jh.high; jrow++) { + rp = ljpeg_row (jrow, &jh); + for (jcol=0; jcol < jwide; jcol++) { + val = *rp++; + if (jh.bits <= 12) + val = curve[val & 0xfff]; + if (cr2_slice[0]) { + jidx = jrow*jwide + jcol; + i = jidx / (cr2_slice[1]*jh.high); + if ((j = i >= cr2_slice[0])) + i = cr2_slice[0]; + jidx -= i * (cr2_slice[1]*jh.high); + row = jidx / cr2_slice[1+j]; + col = jidx % cr2_slice[1+j] + i*cr2_slice[1]; + } + if (raw_width == 3984 && (col -= 2) < 0) + col += (row--,raw_width); + if ((unsigned) (row-top_margin) < height) { + if ((unsigned) (col-left_margin) < width) { + BAYER(row-top_margin,col-left_margin) = val; + if (min > val) min = val; + } else if (col > 1 && (unsigned) (col-left_margin+2) > width+3) + dark[(col-left_margin) & 1] += (nblack++,val); + } + if (++col >= raw_width) + col = (row++,0); + } + } + ljpeg_end (&jh); + canon_black (dark, nblack); + if (!strcasecmp(make,"KODAK")) + black = min; +} + +void CLASS canon_sraw_load_raw() +{ + struct jhead jh; + short *rp=0, (*ip)[4]; + int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c; + int v[3]={0,0,0}, ver, hue; + char *cp; + + if (!ljpeg_start (&jh, 0)) return; + jwide = (jh.wide >>= 1) * jh.clrs; + + for (ecol=slice=0; slice <= cr2_slice[0]; slice++) { + scol = ecol; + ecol += cr2_slice[1] * 2 / jh.clrs; + if (!cr2_slice[0] || ecol > raw_width-1) ecol = raw_width & -2; + for (row=0; row < height; row += (jh.clrs >> 1) - 1) { + ip = (short (*)[4]) image + row*width; + for (col=scol; col < ecol; col+=2, jcol+=jh.clrs) { + if ((jcol %= jwide) == 0) + rp = (short *) ljpeg_row (jrow++, &jh); + if (col >= width) continue; + FORC (jh.clrs-2) + ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c]; + ip[col][1] = rp[jcol+jh.clrs-2] - 16384; + ip[col][2] = rp[jcol+jh.clrs-1] - 16384; + } + } + } + for (cp=model2; *cp && !isdigit(*cp); cp++); + sscanf (cp, "%d.%d.%d", v, v+1, v+2); + ver = (v[0]*1000 + v[1])*1000 + v[2]; + hue = (jh.sraw+1) << 2; + if (unique_id == 0x80000218 && ver > 1000006 && ver < 3000000) + hue = jh.sraw << 1; + ip = (short (*)[4]) image; + rp = ip[0]; + for (row=0; row < height; row++, ip+=width) { + if (row & (jh.sraw >> 1)) + for (col=0; col < width; col+=2) + for (c=1; c < 3; c++) + if (row == height-1) + ip[col][c] = ip[col-width][c]; + else ip[col][c] = (ip[col-width][c] + ip[col+width][c] + 1) >> 1; + for (col=1; col < width; col+=2) + for (c=1; c < 3; c++) + if (col == width-1) + ip[col][c] = ip[col-1][c]; + else ip[col][c] = (ip[col-1][c] + ip[col+1][c] + 1) >> 1; + } + for ( ; rp < ip[0]; rp+=4) { + if (unique_id < 0x80000218) { + pix[0] = rp[0] + rp[2] - 512; + pix[2] = rp[0] + rp[1] - 512; + pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12) - 512; + } else { + rp[1] = (rp[1] << 2) + hue; + rp[2] = (rp[2] << 2) + hue; + pix[0] = rp[0] + (( 200*rp[1] + 22929*rp[2]) >> 14); + pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14); + pix[2] = rp[0] + ((29040*rp[1] - 101*rp[2]) >> 14); + } + FORC3 rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10); + } + ljpeg_end (&jh); + maximum = 0x3fff; +} + +void CLASS adobe_copy_pixel (int row, int col, ushort **rp) +{ + unsigned r, c; + + r = row -= top_margin; + c = col -= left_margin; + if (is_raw == 2 && shot_select) (*rp)++; + if (filters) { + if (fuji_width) { + r = row + fuji_width - 1 - (col >> 1); + c = row + ((col+1) >> 1); + } + if (r < height && c < width) + BAYER(r,c) = **rp < 0x1000 ? curve[**rp] : **rp; + *rp += is_raw; + } else { + if (r < height && c < width) + FORC(tiff_samples) + image[row*width+col][c] = (*rp)[c] < 0x1000 ? curve[(*rp)[c]]:(*rp)[c]; + *rp += tiff_samples; + } + if (is_raw == 2 && shot_select) (*rp)--; +} + +void CLASS adobe_dng_load_raw_lj() +{ + unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col; + struct jhead jh; + ushort *rp; + + while (trow < raw_height) { + save = ftell(ifp); + if (tile_length < INT_MAX) + fseek (ifp, get4(), SEEK_SET); + if (!ljpeg_start (&jh, 0)) break; + jwide = jh.wide; + if (filters) jwide *= jh.clrs; + jwide /= is_raw; + for (row=col=jrow=0; jrow < jh.high; jrow++) { + rp = ljpeg_row (jrow, &jh); + for (jcol=0; jcol < jwide; jcol++) { + adobe_copy_pixel (trow+row, tcol+col, &rp); + if (++col >= tile_width || col >= raw_width) + row += 1 + (col = 0); + } + } + fseek (ifp, save+4, SEEK_SET); + if ((tcol += tile_width) >= raw_width) + trow += tile_length + (tcol = 0); + ljpeg_end (&jh); + } +} + +void CLASS adobe_dng_load_raw_nc() +{ + ushort *pixel, *rp; + int row, col; + + pixel = (ushort *) calloc (raw_width * tiff_samples, sizeof *pixel); + merror (pixel, "adobe_dng_load_raw_nc()"); + for (row=0; row < raw_height; row++) { + if (tiff_bps == 16) + read_shorts (pixel, raw_width * tiff_samples); + else { + getbits(-1); + for (col=0; col < raw_width * tiff_samples; col++) + pixel[col] = getbits(tiff_bps); + } + for (rp=pixel, col=0; col < raw_width; col++) + adobe_copy_pixel (row, col, &rp); + } + free (pixel); +} + +void CLASS pentax_load_raw() +{ + ushort bit[2][13], huff[4097]; + int row, col, diff, c, i; + ushort vpred[2][2] = {{0,0},{0,0}}, hpred[2]; + + fseek (ifp, meta_offset, SEEK_SET); + FORC(13) bit[0][c] = get2(); + FORC(13) bit[1][c] = fgetc(ifp); + FORC(13) + for (i=bit[0][c]; i <= ((bit[0][c]+(4096 >> bit[1][c])-1) & 4095); ) + huff[++i] = bit[1][c] << 8 | c; + huff[0] = 12; + fseek (ifp, data_offset, SEEK_SET); + getbits(-1); + for (row=0; row < raw_height; row++) + for (col=0; col < raw_width; col++) { + diff = ljpeg_diff (huff); + if (col < 2) hpred[col] = vpred[row & 1][col] += diff; + else hpred[col & 1] += diff; + if ((unsigned) (row-top_margin) < height && col < width) + BAYER(row-top_margin,col) = hpred[col & 1]; + if (hpred[col & 1] >> 12) derror(); + } +} + +void CLASS nikon_compressed_load_raw() +{ + static const uchar nikon_tree[][32] = { + { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy */ + 5,4,3,6,2,7,1,0,8,9,11,10,12 }, + { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy after split */ + 0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 }, + { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, /* 12-bit lossless */ + 5,4,6,3,7,2,8,1,9,0,10,11,12 }, + { 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0, /* 14-bit lossy */ + 5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 }, + { 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0, /* 14-bit lossy after split */ + 8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 }, + { 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0, /* 14-bit lossless */ + 7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 } }; + ushort *huff, ver0, ver1, vpred[2][2], hpred[2], csize; + int i, min, max, step=0, tree=0, split=0, row, col, len, shl, diff; + + fseek (ifp, meta_offset, SEEK_SET); + ver0 = fgetc(ifp); + ver1 = fgetc(ifp); + if (ver0 == 0x49 || ver1 == 0x58) + fseek (ifp, 2110, SEEK_CUR); + if (ver0 == 0x46) tree = 2; + if (tiff_bps == 14) tree += 3; + read_shorts (vpred[0], 4); + max = 1 << tiff_bps & 0x7fff; + if ((csize = get2()) > 1) + step = max / (csize-1); + if (ver0 == 0x44 && ver1 == 0x20 && step > 0) { + for (i=0; i < csize; i++) + curve[i*step] = get2(); + for (i=0; i < max; i++) + curve[i] = ( curve[i-i%step]*(step-i%step) + + curve[i-i%step+step]*(i%step) ) / step; + fseek (ifp, meta_offset+562, SEEK_SET); + split = get2(); + } else if (ver0 != 0x46 && csize <= 0x4001) + read_shorts (curve, max=csize); + while (curve[max-2] == curve[max-1]) max--; + huff = make_decoder (nikon_tree[tree]); + fseek (ifp, data_offset, SEEK_SET); + getbits(-1); + for (min=row=0; row < height; row++) { + if (split && row == split) { + free (huff); + huff = make_decoder (nikon_tree[tree+1]); + max += (min = 16) << 1; + } + for (col=0; col < raw_width; col++) { + i = gethuff(huff); + len = i & 15; + shl = i >> 4; + diff = ((getbits(len-shl) << 1) + 1) << shl >> 1; + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - !shl; + if (col < 2) hpred[col] = vpred[row & 1][col] += diff; + else hpred[col & 1] += diff; + if ((ushort)(hpred[col & 1] + min) >= max) derror(); + if ((unsigned) (col-left_margin) < width) + BAYER(row,col-left_margin) = curve[LIM((short)hpred[col & 1],0,0x3fff)]; + } + } + free (huff); +} + +/* + Figure out if a NEF file is compressed. These fancy heuristics + are only needed for the D100, thanks to a bug in some cameras + that tags all images as "compressed". + */ +int CLASS nikon_is_compressed() +{ + uchar test[256]; + int i; + + fseek (ifp, data_offset, SEEK_SET); + fread (test, 1, 256, ifp); + for (i=15; i < 256; i+=16) + if (test[i]) return 1; + return 0; +} + +/* + Returns 1 for a Coolpix 995, 0 for anything else. + */ +int CLASS nikon_e995() +{ + int i, histo[256]; + const uchar often[] = { 0x00, 0x55, 0xaa, 0xff }; + + memset (histo, 0, sizeof histo); + fseek (ifp, -2000, SEEK_END); + for (i=0; i < 2000; i++) + histo[fgetc(ifp)]++; + for (i=0; i < 4; i++) + if (histo[often[i]] < 200) + return 0; + return 1; +} + +/* + Returns 1 for a Coolpix 2100, 0 for anything else. + */ +int CLASS nikon_e2100() +{ + uchar t[12]; + int i; + + fseek (ifp, 0, SEEK_SET); + for (i=0; i < 1024; i++) { + fread (t, 1, 12, ifp); + if (((t[2] & t[4] & t[7] & t[9]) >> 4 + & t[1] & t[6] & t[8] & t[11] & 3) != 3) + return 0; + } + return 1; +} + +void CLASS nikon_3700() +{ + int bits, i; + uchar dp[24]; + static const struct { + int bits; + char make[12], model[15]; + } table[] = { + { 0x00, "PENTAX", "Optio 33WR" }, + { 0x03, "NIKON", "E3200" }, + { 0x32, "NIKON", "E3700" }, + { 0x33, "OLYMPUS", "C740UZ" } }; + + fseek (ifp, 3072, SEEK_SET); + fread (dp, 1, 24, ifp); + bits = (dp[8] & 3) << 4 | (dp[20] & 3); + for (i=0; i < sizeof table / sizeof *table; i++) + if (bits == table[i].bits) { + strcpy (make, table[i].make ); + strcpy (model, table[i].model); + } +} + +/* + Separates a Minolta DiMAGE Z2 from a Nikon E4300. + */ +int CLASS minolta_z2() +{ + int i, nz; + char tail[424]; + + fseek (ifp, -sizeof tail, SEEK_END); + fread (tail, 1, sizeof tail, ifp); + for (nz=i=0; i < sizeof tail; i++) + if (tail[i]) nz++; + return nz > 20; +} + +/* + The Fuji Super CCD is just a Bayer grid rotated 45 degrees. + */ +void CLASS fuji_load_raw() +{ + ushort *pixel; + int wide, row, col, r, c; + + fseek (ifp, (top_margin*raw_width + left_margin) * 2, SEEK_CUR); + wide = fuji_width << !fuji_layout; + pixel = (ushort *) calloc (wide, sizeof *pixel); + merror (pixel, "fuji_load_raw()"); + for (row=0; row < raw_height; row++) { + read_shorts (pixel, wide); + fseek (ifp, 2*(raw_width - wide), SEEK_CUR); + for (col=0; col < wide; col++) { + if (fuji_layout) { + r = fuji_width - 1 - col + (row >> 1); + c = col + ((row+1) >> 1); + } else { + r = fuji_width - 1 + row - (col >> 1); + c = row + ((col+1) >> 1); + } + BAYER(r,c) = pixel[col]; + } + } + free (pixel); +} + +void CLASS jpeg_thumb(); + +void CLASS ppm_thumb() +{ + char *thumb; + thumb_length = thumb_width*thumb_height*3; + thumb = (char *) malloc (thumb_length); + merror (thumb, "ppm_thumb()"); + fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); + fread (thumb, 1, thumb_length, ifp); + fwrite (thumb, 1, thumb_length, ofp); + free (thumb); +} + +void CLASS layer_thumb() +{ + int i, c; + char *thumb, map[][4] = { "012","102" }; + + colors = thumb_misc >> 5 & 7; + thumb_length = thumb_width*thumb_height; + thumb = (char *) calloc (colors, thumb_length); + merror (thumb, "layer_thumb()"); + fprintf (ofp, "P%d\n%d %d\n255\n", + 5 + (colors >> 1), thumb_width, thumb_height); + fread (thumb, thumb_length, colors, ifp); + for (i=0; i < thumb_length; i++) + FORCC putc (thumb[i+thumb_length*(map[thumb_misc >> 8][c]-'0')], ofp); + free (thumb); +} + +void CLASS rollei_thumb() +{ + unsigned i; + ushort *thumb; + + thumb_length = thumb_width * thumb_height; + thumb = (ushort *) calloc (thumb_length, 2); + merror (thumb, "rollei_thumb()"); + fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); + read_shorts (thumb, thumb_length); + for (i=0; i < thumb_length; i++) { + putc (thumb[i] << 3, ofp); + putc (thumb[i] >> 5 << 2, ofp); + putc (thumb[i] >> 11 << 3, ofp); + } + free (thumb); +} + +void CLASS rollei_load_raw() +{ + uchar pixel[10]; + unsigned iten=0, isix, i, buffer=0, row, col, todo[16]; + + isix = raw_width * raw_height * 5 / 8; + while (fread (pixel, 1, 10, ifp) == 10) { + for (i=0; i < 10; i+=2) { + todo[i] = iten++; + todo[i+1] = pixel[i] << 8 | pixel[i+1]; + buffer = pixel[i] >> 2 | buffer << 6; + } + for ( ; i < 16; i+=2) { + todo[i] = isix++; + todo[i+1] = buffer >> (14-i)*5; + } + for (i=0; i < 16; i+=2) { + row = todo[i] / raw_width - top_margin; + col = todo[i] % raw_width - left_margin; + if (row < height && col < width) + BAYER(row,col) = (todo[i+1] & 0x3ff); + } + } + maximum = 0x3ff; +} + +int CLASS bayer (unsigned row, unsigned col) +{ + return (row < height && col < width) ? BAYER(row,col) : 0; +} + +void CLASS phase_one_flat_field (int is_float, int nc) +{ + ushort head[8]; + unsigned wide, y, x, c, rend, cend, row, col; + float *mrow, num, mult[4]; + + read_shorts (head, 8); + wide = head[2] / head[4]; + mrow = (float *) calloc (nc*wide, sizeof *mrow); + merror (mrow, "phase_one_flat_field()"); + for (y=0; y < head[3] / head[5]; y++) { + for (x=0; x < wide; x++) + for (c=0; c < nc; c+=2) { + num = is_float ? getreal(11) : get2()/32768.0; + if (y==0) mrow[c*wide+x] = num; + else mrow[(c+1)*wide+x] = (num - mrow[c*wide+x]) / head[5]; + } + if (y==0) continue; + rend = head[1]-top_margin + y*head[5]; + for (row = rend-head[5]; row < height && row < rend; row++) { + for (x=1; x < wide; x++) { + for (c=0; c < nc; c+=2) { + mult[c] = mrow[c*wide+x-1]; + mult[c+1] = (mrow[c*wide+x] - mult[c]) / head[4]; + } + cend = head[0]-left_margin + x*head[4]; + for (col = cend-head[4]; col < width && col < cend; col++) { + c = nc > 2 ? FC(row,col) : 0; + if (!(c & 1)) { + c = BAYER(row,col) * mult[c]; + BAYER(row,col) = LIM(c,0,65535); + } + for (c=0; c < nc; c+=2) + mult[c] += mult[c+1]; + } + } + for (x=0; x < wide; x++) + for (c=0; c < nc; c+=2) + mrow[c*wide+x] += mrow[(c+1)*wide+x]; + } + } + free (mrow); +} + +void CLASS phase_one_correct() +{ + unsigned entries, tag, data, save, col, row, type; + int len, i, j, k, cip, val[4], dev[4], sum, max; + int head[9], diff, mindiff=INT_MAX, off_412=0; + static const signed char dir[12][2] = + { {-1,-1}, {-1,1}, {1,-1}, {1,1}, {-2,0}, {0,-2}, {0,2}, {2,0}, + {-2,-2}, {-2,2}, {2,-2}, {2,2} }; + float poly[8], num, cfrac, frac, mult[2], *yval[2]; + ushort *xval[2]; + + if (half_size || !meta_length) return; + if (verbose) fprintf (stderr,_("Phase One correction...\n")); + fseek (ifp, meta_offset, SEEK_SET); + order = get2(); + fseek (ifp, 6, SEEK_CUR); + fseek (ifp, meta_offset+get4(), SEEK_SET); + entries = get4(); get4(); + while (entries--) { + tag = get4(); + len = get4(); + data = get4(); + save = ftell(ifp); + fseek (ifp, meta_offset+data, SEEK_SET); + if (tag == 0x419) { /* Polynomial curve */ + for (get4(), i=0; i < 8; i++) + poly[i] = getreal(11); + poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1; + for (i=0; i < 0x10000; i++) { + num = (poly[5]*i + poly[3])*i + poly[1]; + curve[i] = LIM(num,0,65535); + } goto apply; /* apply to right half */ + } else if (tag == 0x41a) { /* Polynomial curve */ + for (i=0; i < 4; i++) + poly[i] = getreal(11); + for (i=0; i < 0x10000; i++) { + for (num=0, j=4; j--; ) + num = num * i + poly[j]; + curve[i] = LIM(num+i,0,65535); + } apply: /* apply to whole image */ + for (row=0; row < height; row++) + for (col = (tag & 1)*ph1.split_col; col < width; col++) + BAYER(row,col) = curve[BAYER(row,col)]; + } else if (tag == 0x400) { /* Sensor defects */ + while ((len -= 8) >= 0) { + col = get2() - left_margin; + row = get2() - top_margin; + type = get2(); get2(); + if (col >= width) continue; + if (type == 131) /* Bad column */ + for (row=0; row < height; row++) + if (FC(row,col) == 1) { + for (sum=i=0; i < 4; i++) + sum += val[i] = bayer (row+dir[i][0], col+dir[i][1]); + for (max=i=0; i < 4; i++) { + dev[i] = abs((val[i] << 2) - sum); + if (dev[max] < dev[i]) max = i; + } + BAYER(row,col) = (sum - val[max])/3.0 + 0.5; + } else { + for (sum=0, i=8; i < 12; i++) + sum += bayer (row+dir[i][0], col+dir[i][1]); + BAYER(row,col) = 0.5 + sum * 0.0732233 + + (bayer(row,col-2) + bayer(row,col+2)) * 0.3535534; + } + else if (type == 129) { /* Bad pixel */ + if (row >= height) continue; + j = (FC(row,col) != 1) * 4; + for (sum=0, i=j; i < j+8; i++) + sum += bayer (row+dir[i][0], col+dir[i][1]); + BAYER(row,col) = (sum + 4) >> 3; + } + } + } else if (tag == 0x401) { /* All-color flat fields */ + phase_one_flat_field (1, 2); + } else if (tag == 0x416 || tag == 0x410) { + phase_one_flat_field (0, 2); + } else if (tag == 0x40b) { /* Red+blue flat field */ + phase_one_flat_field (0, 4); + } else if (tag == 0x412) { + fseek (ifp, 36, SEEK_CUR); + diff = abs (get2() - ph1.tag_21a); + if (mindiff > diff) { + mindiff = diff; + off_412 = ftell(ifp) - 38; + } + } + fseek (ifp, save, SEEK_SET); + } + if (off_412) { + fseek (ifp, off_412, SEEK_SET); + for (i=0; i < 9; i++) head[i] = get4() & 0x7fff; + yval[0] = (float *) calloc (head[1]*head[3] + head[2]*head[4], 6); + merror (yval[0], "phase_one_correct()"); + yval[1] = (float *) (yval[0] + head[1]*head[3]); + xval[0] = (ushort *) (yval[1] + head[2]*head[4]); + xval[1] = (ushort *) (xval[0] + head[1]*head[3]); + get2(); + for (i=0; i < 2; i++) + for (j=0; j < head[i+1]*head[i+3]; j++) + yval[i][j] = getreal(11); + for (i=0; i < 2; i++) + for (j=0; j < head[i+1]*head[i+3]; j++) + xval[i][j] = get2(); + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + cfrac = (float) col * head[3] / raw_width; + cfrac -= cip = cfrac; + num = BAYER(row,col) * 0.5; + for (i=cip; i < cip+2; i++) { + for (k=j=0; j < head[1]; j++) + if (num < xval[0][k = head[1]*i+j]) break; + frac = (j == 0 || j == head[1]) ? 0 : + (xval[0][k] - num) / (xval[0][k] - xval[0][k-1]); + mult[i-cip] = yval[0][k-1] * frac + yval[0][k] * (1-frac); + } + i = ((mult[0] * (1-cfrac) + mult[1] * cfrac) + * (row + top_margin) + num) * 2; + BAYER(row,col) = LIM(i,0,65535); + } + free (yval[0]); + } +} + +void CLASS phase_one_load_raw() +{ + int row, col, a, b; + ushort *pixel, akey, bkey, mask; + + fseek (ifp, ph1.key_off, SEEK_SET); + akey = get2(); + bkey = get2(); + mask = ph1.format == 1 ? 0x5555:0x1354; + fseek (ifp, data_offset + top_margin*raw_width*2, SEEK_SET); + pixel = (ushort *) calloc (raw_width, sizeof *pixel); + merror (pixel, "phase_one_load_raw()"); + for (row=0; row < height; row++) { + read_shorts (pixel, raw_width); + for (col=0; col < raw_width; col+=2) { + a = pixel[col+0] ^ akey; + b = pixel[col+1] ^ bkey; + pixel[col+0] = (a & mask) | (b & ~mask); + pixel[col+1] = (b & mask) | (a & ~mask); + } + for (col=0; col < width; col++) + BAYER(row,col) = pixel[col+left_margin]; + } + free (pixel); + phase_one_correct(); +} + +unsigned CLASS ph1_bithuff (int nbits, ushort *huff) +{ + static UINT64 bitbuf=0; + static int vbits=0; + unsigned c; + + if (nbits == -1) + return bitbuf = vbits = 0; + if (nbits == 0) return 0; + if (vbits < nbits) { + bitbuf = bitbuf << 32 | get4(); + vbits += 32; + } + c = bitbuf << (64-vbits) >> (64-nbits); + if (huff) { + vbits -= huff[c] >> 8; + return (uchar) huff[c]; + } + vbits -= nbits; + return c; +} +#define ph1_bits(n) ph1_bithuff(n,0) +#define ph1_huff(h) ph1_bithuff(*h,h+1) + +void CLASS phase_one_load_raw_c() +{ + static const int length[] = { 8,7,6,9,11,10,5,12,14,13 }; + int *offset, len[2], pred[2], row, col, i, j; + ushort *pixel; + short (*black)[2]; + + pixel = (ushort *) calloc (raw_width + raw_height*4, 2); + merror (pixel, "phase_one_load_raw_c()"); + offset = (int *) (pixel + raw_width); + fseek (ifp, strip_offset, SEEK_SET); + for (row=0; row < raw_height; row++) + offset[row] = get4(); + black = (short (*)[2]) offset + raw_height; + fseek (ifp, ph1.black_off, SEEK_SET); + if (ph1.black_off) + read_shorts ((ushort *) black[0], raw_height*2); + for (i=0; i < 256; i++) + curve[i] = i*i / 3.969 + 0.5; + for (row=0; row < raw_height; row++) { + fseek (ifp, data_offset + offset[row], SEEK_SET); + ph1_bits(-1); + pred[0] = pred[1] = 0; + for (col=0; col < raw_width; col++) { + if (col >= (raw_width & -8)) + len[0] = len[1] = 14; + else if ((col & 7) == 0) + for (i=0; i < 2; i++) { + for (j=0; j < 5 && !ph1_bits(1); j++); + if (j--) len[i] = length[j*2 + ph1_bits(1)]; + } + if ((i = len[col & 1]) == 14) + pixel[col] = pred[col & 1] = ph1_bits(16); + else + pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1)); + if (pred[col & 1] >> 16) derror(); + if (ph1.format == 5 && pixel[col] < 256) + pixel[col] = curve[pixel[col]]; + } + if ((unsigned) (row-top_margin) < height) + for (col=0; col < width; col++) { + i = (pixel[col+left_margin] << 2) + - ph1.black + black[row][col >= ph1.split_col]; + if (i > 0) BAYER(row-top_margin,col) = i; + } + } + free (pixel); + phase_one_correct(); + maximum = 0xfffc - ph1.black; +} + +void CLASS hasselblad_load_raw() +{ + struct jhead jh; + int row, col, pred[2], len[2], diff, c; + + if (!ljpeg_start (&jh, 0)) return; + order = 0x4949; + ph1_bits(-1); + for (row=-top_margin; row < height; row++) { + pred[0] = pred[1] = 0x8000; + for (col=-left_margin; col < raw_width-left_margin; col+=2) { + FORC(2) len[c] = ph1_huff(jh.huff[0]); + FORC(2) { + diff = ph1_bits(len[c]); + if ((diff & (1 << (len[c]-1))) == 0) + diff -= (1 << len[c]) - 1; + if (diff == 65535) diff = -32768; + pred[c] += diff; + if (row >= 0 && (unsigned)(col+c) < width) + BAYER(row,col+c) = pred[c]; + } + } + } + ljpeg_end (&jh); + maximum = 0xffff; +} + +void CLASS leaf_hdr_load_raw() +{ + ushort *pixel; + unsigned tile=0, r, c, row, col; + + pixel = (ushort *) calloc (raw_width, sizeof *pixel); + merror (pixel, "leaf_hdr_load_raw()"); + FORC(tiff_samples) + for (r=0; r < raw_height; r++) { + if (r % tile_length == 0) { + fseek (ifp, data_offset + 4*tile++, SEEK_SET); + fseek (ifp, get4() + 2*left_margin, SEEK_SET); + } + if (filters && c != shot_select) continue; + read_shorts (pixel, raw_width); + if ((row = r - top_margin) >= height) continue; + for (col=0; col < width; col++) + if (filters) BAYER(row,col) = pixel[col]; + else image[row*width+col][c] = pixel[col]; + } + free (pixel); + if (!filters) { + maximum = 0xffff; + raw_color = 1; + } +} + +void CLASS unpacked_load_raw(); + +void CLASS sinar_4shot_load_raw() +{ + ushort *pixel; + unsigned shot, row, col, r, c; + + if ((shot = shot_select) || half_size) { + if (shot) shot--; + if (shot > 3) shot = 3; + fseek (ifp, data_offset + shot*4, SEEK_SET); + fseek (ifp, get4(), SEEK_SET); + unpacked_load_raw(); + return; + } + free (image); + image = (ushort (*)[4]) + calloc ((iheight=height)*(iwidth=width), sizeof *image); + merror (image, "sinar_4shot_load_raw()"); + pixel = (ushort *) calloc (raw_width, sizeof *pixel); + merror (pixel, "sinar_4shot_load_raw()"); + for (shot=0; shot < 4; shot++) { + fseek (ifp, data_offset + shot*4, SEEK_SET); + fseek (ifp, get4(), SEEK_SET); + for (row=0; row < raw_height; row++) { + read_shorts (pixel, raw_width); + if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue; + for (col=0; col < raw_width; col++) { + if ((c = col-left_margin - (shot & 1)) >= width) continue; + image[r*width+c][FC(row,col)] = pixel[col]; + } + } + } + free (pixel); + shrink = filters = 0; +} + +void CLASS imacon_full_load_raw() +{ + int row, col; + + for (row=0; row < height; row++) + for (col=0; col < width; col++) + read_shorts (image[row*width+col], 3); +} + +void CLASS packed_load_raw() +{ + int vbits=0, bwide, pwide, rbits, bite, half, irow, row, col, val, i; + UINT64 bitbuf=0; + + if (raw_width * 8 >= width * tiff_bps) /* Is raw_width in bytes? */ + pwide = (bwide = raw_width) * 8 / tiff_bps; + else bwide = (pwide = raw_width) * tiff_bps / 8; + rbits = bwide * 8 - pwide * tiff_bps; + if (load_flags & 1) bwide = bwide * 16 / 15; + fseek (ifp, top_margin*bwide, SEEK_CUR); + bite = 8 + (load_flags & 24); + half = (height+1) >> 1; + for (irow=0; irow < height; irow++) { + row = irow; + if (load_flags & 2 && + (row = irow % half * 2 + irow / half) == 1 && + load_flags & 4) { + if (vbits=0, tiff_compress) + fseek (ifp, data_offset - (-half*bwide & -2048), SEEK_SET); + else { + fseek (ifp, 0, SEEK_END); + fseek (ifp, ftell(ifp) >> 3 << 2, SEEK_SET); + } + } + for (col=0; col < pwide; col++) { + for (vbits -= tiff_bps; vbits < 0; vbits += bite) { + bitbuf <<= bite; + for (i=0; i < bite; i+=8) + bitbuf |= (unsigned) (fgetc(ifp) << i); + } + val = bitbuf << (64-tiff_bps-vbits) >> (64-tiff_bps); + i = (col ^ (bite == 24)) - left_margin; + if ((unsigned) i < width) + BAYER(row,i) = val << (load_flags >> 6); + else if (load_flags & 32) + black += val; + if (load_flags & 1 && (col % 10) == 9 && + fgetc(ifp) && col < width+left_margin) derror(); + } + vbits -= rbits; + } + if (load_flags & 32 && pwide > width) + black /= (pwide - width) * height; +} + +void CLASS unpacked_load_raw() +{ + ushort *pixel; + int row, col, bits=0; + + while (1 << ++bits < maximum); + fseek (ifp, (top_margin*raw_width + left_margin) * 2, SEEK_CUR); + pixel = (ushort *) calloc (width, sizeof *pixel); + merror (pixel, "unpacked_load_raw()"); + for (row=0; row < height; row++) { + read_shorts (pixel, width); + fseek (ifp, 2*(raw_width - width), SEEK_CUR); + for (col=0; col < width; col++) + if ((BAYER2(row,col) = pixel[col]) >> bits) derror(); + } + free (pixel); +} + +void CLASS nokia_load_raw() +{ + uchar *data, *dp; + ushort *pixel, *pix; + int dwide, row, c; + + dwide = raw_width * 5 / 4; + data = (uchar *) malloc (dwide + raw_width*2); + merror (data, "nokia_load_raw()"); + pixel = (ushort *) (data + dwide); + for (row=0; row < raw_height; row++) { + if (fread (data, 1, dwide, ifp) < dwide) derror(); + for (dp=data, pix=pixel; pix < pixel+raw_width; dp+=5, pix+=4) + FORC4 pix[c] = (dp[c] << 2) | (dp[4] >> (c << 1) & 3); + if (row < top_margin) + FORC(width) black += pixel[c]; + else + FORC(width) BAYER(row-top_margin,c) = pixel[c]; + } + free (data); + if (top_margin) black /= top_margin * width; + maximum = 0x3ff; +} + +unsigned CLASS pana_bits (int nbits) +{ + static uchar buf[0x4000]; + static int vbits; + int byte; + + if (!nbits) return vbits=0; + if (!vbits) { + fread (buf+load_flags, 1, 0x4000-load_flags, ifp); + fread (buf, 1, load_flags, ifp); + } + vbits = (vbits - nbits) & 0x1ffff; + byte = vbits >> 3 ^ 0x3ff0; + return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits); +} + +void CLASS panasonic_load_raw() +{ + int row, col, i, j, sh=0, pred[2], nonz[2]; + + pana_bits(0); + for (row=0; row < height; row++) + for (col=0; col < raw_width; col++) { + if ((i = col % 14) == 0) + pred[0] = pred[1] = nonz[0] = nonz[1] = 0; + if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2)); + if (nonz[i & 1]) { + if ((j = pana_bits(8))) { + if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4) + pred[i & 1] &= ~(-1 << sh); + pred[i & 1] += j << sh; + } + } else if ((nonz[i & 1] = pana_bits(8)) || i > 11) + pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4); + if (col < width) + if ((BAYER(row,col) = pred[col & 1]) > 4098) derror(); + } +} + +void CLASS olympus_load_raw() +{ + ushort huff[4096]; + int row, col, nbits, sign, low, high, i, c, w, n, nw; + int acarry[2][3], *carry, pred, diff; + + huff[n=0] = 0xc0c; + for (i=12; i--; ) + FORC(2048 >> i) huff[++n] = (i+1) << 8 | i; + fseek (ifp, 7, SEEK_CUR); + getbits(-1); + for (row=0; row < height; row++) { + memset (acarry, 0, sizeof acarry); + for (col=0; col < raw_width; col++) { + carry = acarry[col & 1]; + i = 2 * (carry[2] < 3); + for (nbits=2+i; (ushort) carry[0] >> (nbits+i); nbits++); + low = (sign = getbits(3)) & 3; + sign = sign << 29 >> 31; + if ((high = getbithuff(12,huff)) == 12) + high = getbits(16-nbits) >> 1; + carry[0] = (high << nbits) | getbits(nbits); + diff = (carry[0] ^ sign) + carry[1]; + carry[1] = (diff*3 + carry[1]) >> 5; + carry[2] = carry[0] > 16 ? 0 : carry[2]+1; + if (col >= width) continue; + if (row < 2 && col < 2) pred = 0; + else if (row < 2) pred = BAYER(row,col-2); + else if (col < 2) pred = BAYER(row-2,col); + else { + w = BAYER(row,col-2); + n = BAYER(row-2,col); + nw = BAYER(row-2,col-2); + if ((w < nw && nw < n) || (n < nw && nw < w)) { + if (ABS(w-nw) > 32 || ABS(n-nw) > 32) + pred = w + n - nw; + else pred = (w + n) >> 1; + } else pred = ABS(w-nw) > ABS(n-nw) ? w : n; + } + if ((BAYER(row,col) = pred + ((diff << 2) | low)) >> 12) derror(); + } + } +} + +void CLASS minolta_rd175_load_raw() +{ + uchar pixel[768]; + unsigned irow, box, row, col; + + for (irow=0; irow < 1481; irow++) { + if (fread (pixel, 1, 768, ifp) < 768) derror(); + box = irow / 82; + row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2); + switch (irow) { + case 1477: case 1479: continue; + case 1476: row = 984; break; + case 1480: row = 985; break; + case 1478: row = 985; box = 1; + } + if ((box < 12) && (box & 1)) { + for (col=0; col < 1533; col++, row ^= 1) + if (col != 1) BAYER(row,col) = (col+1) & 2 ? + pixel[col/2-1] + pixel[col/2+1] : pixel[col/2] << 1; + BAYER(row,1) = pixel[1] << 1; + BAYER(row,1533) = pixel[765] << 1; + } else + for (col=row & 1; col < 1534; col+=2) + BAYER(row,col) = pixel[col/2] << 1; + } + maximum = 0xff << 1; +} + +void CLASS quicktake_100_load_raw() +{ + uchar pixel[484][644]; + static const short gstep[16] = + { -89,-60,-44,-32,-22,-15,-8,-2,2,8,15,22,32,44,60,89 }; + static const short rstep[6][4] = + { { -3,-1,1,3 }, { -5,-1,1,5 }, { -8,-2,2,8 }, + { -13,-3,3,13 }, { -19,-4,4,19 }, { -28,-6,6,28 } }; + static const short curve[256] = + { 0,1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27, + 28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,53, + 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,74,75,76,77,78, + 79,80,81,82,83,84,86,88,90,92,94,97,99,101,103,105,107,110,112,114,116, + 118,120,123,125,127,129,131,134,136,138,140,142,144,147,149,151,153,155, + 158,160,162,164,166,168,171,173,175,177,179,181,184,186,188,190,192,195, + 197,199,201,203,205,208,210,212,214,216,218,221,223,226,230,235,239,244, + 248,252,257,261,265,270,274,278,283,287,291,296,300,305,309,313,318,322, + 326,331,335,339,344,348,352,357,361,365,370,374,379,383,387,392,396,400, + 405,409,413,418,422,426,431,435,440,444,448,453,457,461,466,470,474,479, + 483,487,492,496,500,508,519,531,542,553,564,575,587,598,609,620,631,643, + 654,665,676,687,698,710,721,732,743,754,766,777,788,799,810,822,833,844, + 855,866,878,889,900,911,922,933,945,956,967,978,989,1001,1012,1023 }; + int rb, row, col, sharp, val=0; + + getbits(-1); + memset (pixel, 0x80, sizeof pixel); + for (row=2; row < height+2; row++) { + for (col=2+(row & 1); col < width+2; col+=2) { + val = ((pixel[row-1][col-1] + 2*pixel[row-1][col+1] + + pixel[row][col-2]) >> 2) + gstep[getbits(4)]; + pixel[row][col] = val = LIM(val,0,255); + if (col < 4) + pixel[row][col-2] = pixel[row+1][~row & 1] = val; + if (row == 2) + pixel[row-1][col+1] = pixel[row-1][col+3] = val; + } + pixel[row][col] = val; + } + for (rb=0; rb < 2; rb++) + for (row=2+rb; row < height+2; row+=2) + for (col=3-(row & 1); col < width+2; col+=2) { + if (row < 4 || col < 4) sharp = 2; + else { + val = ABS(pixel[row-2][col] - pixel[row][col-2]) + + ABS(pixel[row-2][col] - pixel[row-2][col-2]) + + ABS(pixel[row][col-2] - pixel[row-2][col-2]); + sharp = val < 4 ? 0 : val < 8 ? 1 : val < 16 ? 2 : + val < 32 ? 3 : val < 48 ? 4 : 5; + } + val = ((pixel[row-2][col] + pixel[row][col-2]) >> 1) + + rstep[sharp][getbits(2)]; + pixel[row][col] = val = LIM(val,0,255); + if (row < 4) pixel[row-2][col+2] = val; + if (col < 4) pixel[row+2][col-2] = val; + } + for (row=2; row < height+2; row++) + for (col=3-(row & 1); col < width+2; col+=2) { + val = ((pixel[row][col-1] + (pixel[row][col] << 2) + + pixel[row][col+1]) >> 1) - 0x100; + pixel[row][col] = LIM(val,0,255); + } + for (row=0; row < height; row++) + for (col=0; col < width; col++) + BAYER(row,col) = curve[pixel[row+2][col+2]]; + maximum = 0x3ff; +} + +#define radc_token(tree) ((signed char) getbithuff(8,huff[tree])) + +#define FORYX for (y=1; y < 3; y++) for (x=col+1; x >= col; x--) + +#define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \ +: (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4) + +void CLASS kodak_radc_load_raw() +{ + static const char src[] = { + 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8, + 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8, + 2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8, + 2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8, + 2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8, + 2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8, + 2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8, + 2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8, + 2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4, + 2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8, + 1,0, 2,2, 2,-2, + 1,-3, 1,3, + 2,-17, 2,-5, 2,5, 2,17, + 2,-7, 2,2, 2,9, 2,18, + 2,-18, 2,-9, 2,-2, 2,7, + 2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79, + 2,-1, 2,13, 2,26, 3,39, 4,-16, 5,55, 6,-37, 6,76, + 2,-26, 2,-13, 2,1, 3,-39, 4,16, 5,-55, 6,-76, 6,37 + }; + ushort huff[19][256]; + int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val; + short last[3] = { 16,16,16 }, mul[3], buf[3][3][386]; + static const ushort pt[] = + { 0,0, 1280,1344, 2320,3616, 3328,8000, 4095,16383, 65535,16383 }; + + for (i=2; i < 12; i+=2) + for (c=pt[i-2]; c <= pt[i]; c++) + curve[c] = (float) + (c-pt[i-2]) / (pt[i]-pt[i-2]) * (pt[i+1]-pt[i-1]) + pt[i-1] + 0.5; + for (s=i=0; i < sizeof src; i+=2) + FORC(256 >> src[i]) + huff[0][s++] = src[i] << 8 | (uchar) src[i+1]; + s = kodak_cbpp == 243 ? 2 : 3; + FORC(256) huff[18][c] = (8-s) << 8 | c >> s << s | 1 << (s-1); + getbits(-1); + for (i=0; i < sizeof(buf)/sizeof(short); i++) + buf[0][0][i] = 2048; + for (row=0; row < height; row+=4) { + FORC3 mul[c] = getbits(6); + FORC3 { + val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c]; + s = val > 65564 ? 10:12; + x = ~(-1 << (s-1)); + val <<= 12-s; + for (i=0; i < sizeof(buf[0])/sizeof(short); i++) + buf[c][0][i] = (buf[c][0][i] * val + x) >> s; + last[c] = mul[c]; + for (r=0; r <= !c; r++) { + buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7; + for (tree=1, col=width/2; col > 0; ) { + if ((tree = radc_token(tree))) { + col -= 2; + if (tree == 8) + FORYX buf[c][y][x] = (uchar) radc_token(18) * mul[c]; + else + FORYX buf[c][y][x] = radc_token(tree+10) * 16 + PREDICTOR; + } else + do { + nreps = (col > 2) ? radc_token(9) + 1 : 1; + for (rep=0; rep < 8 && rep < nreps && col > 0; rep++) { + col -= 2; + FORYX buf[c][y][x] = PREDICTOR; + if (rep & 1) { + step = radc_token(10) << 4; + FORYX buf[c][y][x] += step; + } + } + } while (nreps == 9); + } + for (y=0; y < 2; y++) + for (x=0; x < width/2; x++) { + val = (buf[c][y+1][x] << 4) / mul[c]; + if (val < 0) val = 0; + if (c) BAYER(row+y*2+c-1,x*2+2-c) = val; + else BAYER(row+r*2+y,x*2+y) = val; + } + memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c); + } + } + for (y=row; y < row+4; y++) + for (x=0; x < width; x++) + if ((x+y) & 1) { + r = x ? x-1 : x+1; + s = x+1 < width ? x+1 : x-1; + val = (BAYER(y,x)-2048)*2 + (BAYER(y,r)+BAYER(y,s))/2; + if (val < 0) val = 0; + BAYER(y,x) = val; + } + } + for (i=0; i < iheight*iwidth*4; i++) + image[0][i] = curve[image[0][i]]; + maximum = 0x3fff; +} + +#undef FORYX +#undef PREDICTOR + +#ifdef NO_JPEG +void CLASS kodak_jpeg_load_raw() {} +#else + +METHODDEF(boolean) +fill_input_buffer (j_decompress_ptr cinfo) +{ + static uchar jpeg_buffer[4096]; + size_t nbytes; + + nbytes = fread (jpeg_buffer, 1, 4096, ifp); + swab (jpeg_buffer, jpeg_buffer, nbytes); + cinfo->src->next_input_byte = jpeg_buffer; + cinfo->src->bytes_in_buffer = nbytes; + return TRUE; +} + +void CLASS kodak_jpeg_load_raw() +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + JSAMPARRAY buf; + JSAMPLE (*pixel)[3]; + int row, col; + + cinfo.err = jpeg_std_error (&jerr); + jpeg_create_decompress (&cinfo); + jpeg_stdio_src (&cinfo, ifp); + cinfo.src->fill_input_buffer = fill_input_buffer; + jpeg_read_header (&cinfo, TRUE); + jpeg_start_decompress (&cinfo); + if ((cinfo.output_width != width ) || + (cinfo.output_height*2 != height ) || + (cinfo.output_components != 3 )) { + fprintf (stderr,_("%s: incorrect JPEG dimensions\n"), ifname); + jpeg_destroy_decompress (&cinfo); + longjmp (failure, 3); + } + buf = (*cinfo.mem->alloc_sarray) + ((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1); + + while (cinfo.output_scanline < cinfo.output_height) { + row = cinfo.output_scanline * 2; + jpeg_read_scanlines (&cinfo, buf, 1); + pixel = (JSAMPLE (*)[3]) buf[0]; + for (col=0; col < width; col+=2) { + BAYER(row+0,col+0) = pixel[col+0][1] << 1; + BAYER(row+1,col+1) = pixel[col+1][1] << 1; + BAYER(row+0,col+1) = pixel[col][0] + pixel[col+1][0]; + BAYER(row+1,col+0) = pixel[col][2] + pixel[col+1][2]; + } + } + jpeg_finish_decompress (&cinfo); + jpeg_destroy_decompress (&cinfo); + maximum = 0xff << 1; +} +#endif + +void CLASS kodak_dc120_load_raw() +{ + static const int mul[4] = { 162, 192, 187, 92 }; + static const int add[4] = { 0, 636, 424, 212 }; + uchar pixel[848]; + int row, shift, col; + + for (row=0; row < height; row++) { + if (fread (pixel, 1, 848, ifp) < 848) derror(); + shift = row * mul[row & 3] + add[row & 3]; + for (col=0; col < width; col++) + BAYER(row,col) = (ushort) pixel[(col + shift) % 848]; + } + maximum = 0xff; +} + +void CLASS eight_bit_load_raw() +{ + uchar *pixel; + unsigned row, col, val, lblack=0; + + pixel = (uchar *) calloc (raw_width, sizeof *pixel); + merror (pixel, "eight_bit_load_raw()"); + fseek (ifp, top_margin*raw_width, SEEK_CUR); + for (row=0; row < height; row++) { + if (fread (pixel, 1, raw_width, ifp) < raw_width) derror(); + for (col=0; col < raw_width; col++) { + val = curve[pixel[col]]; + if ((unsigned) (col-left_margin) < width) + BAYER(row,col-left_margin) = val; + else lblack += val; + } + } + free (pixel); + if (raw_width > width+1) + black = lblack / ((raw_width - width) * height); + if (!strncmp(model,"DC2",3)) + black = 0; + maximum = curve[0xff]; +} + +void CLASS kodak_yrgb_load_raw() +{ + uchar *pixel; + int row, col, y, cb, cr, rgb[3], c; + + pixel = (uchar *) calloc (raw_width, 3*sizeof *pixel); + merror (pixel, "kodak_yrgb_load_raw()"); + for (row=0; row < height; row++) { + if (~row & 1) + if (fread (pixel, raw_width, 3, ifp) < 3) derror(); + for (col=0; col < raw_width; col++) { + y = pixel[width*2*(row & 1) + col]; + cb = pixel[width + (col & -2)] - 128; + cr = pixel[width + (col & -2)+1] - 128; + rgb[1] = y-((cb + cr + 2) >> 2); + rgb[2] = rgb[1] + cb; + rgb[0] = rgb[1] + cr; + FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)]; + } + } + free (pixel); + maximum = curve[0xff]; +} + +void CLASS kodak_262_load_raw() +{ + static const uchar kodak_tree[2][26] = + { { 0,1,5,1,1,2,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9 }, + { 0,3,1,1,1,1,1,2,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9 } }; + ushort *huff[2]; + uchar *pixel; + int *strip, ns, c, row, col, chess, pi=0, pi1, pi2, pred, val; + + FORC(2) huff[c] = make_decoder (kodak_tree[c]); + ns = (raw_height+63) >> 5; + pixel = (uchar *) malloc (raw_width*32 + ns*4); + merror (pixel, "kodak_262_load_raw()"); + strip = (int *) (pixel + raw_width*32); + order = 0x4d4d; + FORC(ns) strip[c] = get4(); + for (row=0; row < raw_height; row++) { + if ((row & 31) == 0) { + fseek (ifp, strip[row >> 5], SEEK_SET); + getbits(-1); + pi = 0; + } + for (col=0; col < raw_width; col++) { + chess = (row + col) & 1; + pi1 = chess ? pi-2 : pi-raw_width-1; + pi2 = chess ? pi-2*raw_width : pi-raw_width+1; + if (col <= chess) pi1 = -1; + if (pi1 < 0) pi1 = pi2; + if (pi2 < 0) pi2 = pi1; + if (pi1 < 0 && col > 1) pi1 = pi2 = pi-2; + pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1; + pixel[pi] = val = pred + ljpeg_diff (huff[chess]); + if (val >> 8) derror(); + val = curve[pixel[pi++]]; + if ((unsigned) (col-left_margin) < width) + BAYER(row,col-left_margin) = val; + else black += val; + } + } + free (pixel); + FORC(2) free (huff[c]); + if (raw_width > width) + black /= (raw_width - width) * height; +} + +int CLASS kodak_65000_decode (short *out, int bsize) +{ + uchar c, blen[768]; + ushort raw[6]; + INT64 bitbuf=0; + int save, bits=0, i, j, len, diff; + + save = ftell(ifp); + bsize = (bsize + 3) & -4; + for (i=0; i < bsize; i+=2) { + c = fgetc(ifp); + if ((blen[i ] = c & 15) > 12 || + (blen[i+1] = c >> 4) > 12 ) { + fseek (ifp, save, SEEK_SET); + for (i=0; i < bsize; i+=8) { + read_shorts (raw, 6); + out[i ] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12; + out[i+1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12; + for (j=0; j < 6; j++) + out[i+2+j] = raw[j] & 0xfff; + } + return 1; + } + } + if ((bsize & 7) == 4) { + bitbuf = fgetc(ifp) << 8; + bitbuf += fgetc(ifp); + bits = 16; + } + for (i=0; i < bsize; i++) { + len = blen[i]; + if (bits < len) { + for (j=0; j < 32; j+=8) + bitbuf += (INT64) fgetc(ifp) << (bits+(j^8)); + bits += 32; + } + diff = bitbuf & (0xffff >> (16-len)); + bitbuf >>= len; + bits -= len; + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + out[i] = diff; + } + return 0; +} + +void CLASS kodak_65000_load_raw() +{ + short buf[256]; + int row, col, len, pred[2], ret, i; + + for (row=0; row < height; row++) + for (col=0; col < width; col+=256) { + pred[0] = pred[1] = 0; + len = MIN (256, width-col); + ret = kodak_65000_decode (buf, len); + for (i=0; i < len; i++) + if ((BAYER(row,col+i) = curve[ret ? buf[i] : + (pred[i & 1] += buf[i])]) >> 12) derror(); + } +} + +void CLASS kodak_ycbcr_load_raw() +{ + short buf[384], *bp; + int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3]; + ushort *ip; + + for (row=0; row < height; row+=2) + for (col=0; col < width; col+=128) { + len = MIN (128, width-col); + kodak_65000_decode (buf, len*3); + y[0][1] = y[1][1] = cb = cr = 0; + for (bp=buf, i=0; i < len; i+=2, bp+=2) { + cb += bp[4]; + cr += bp[5]; + rgb[1] = -((cb + cr + 2) >> 2); + rgb[2] = rgb[1] + cb; + rgb[0] = rgb[1] + cr; + for (j=0; j < 2; j++) + for (k=0; k < 2; k++) { + if ((y[j][k] = y[j][k^1] + *bp++) >> 10) derror(); + ip = image[(row+j)*width + col+i+k]; + FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)]; + } + } + } +} + +void CLASS kodak_rgb_load_raw() +{ + short buf[768], *bp; + int row, col, len, c, i, rgb[3]; + ushort *ip=image[0]; + + for (row=0; row < height; row++) + for (col=0; col < width; col+=256) { + len = MIN (256, width-col); + kodak_65000_decode (buf, len*3); + memset (rgb, 0, sizeof rgb); + for (bp=buf, i=0; i < len; i++, ip+=4) + FORC3 if ((ip[c] = rgb[c] += *bp++) >> 12) derror(); + } +} + +void CLASS kodak_thumb_load_raw() +{ + int row, col; + colors = thumb_misc >> 5; + for (row=0; row < height; row++) + for (col=0; col < width; col++) + read_shorts (image[row*width+col], colors); + maximum = (1 << (thumb_misc & 31)) - 1; +} + +void CLASS sony_decrypt (unsigned *data, int len, int start, int key) +{ + static unsigned pad[128], p; + + if (start) { + for (p=0; p < 4; p++) + pad[p] = key = key * 48828125 + 1; + pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31; + for (p=4; p < 127; p++) + pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31; + for (p=0; p < 127; p++) + pad[p] = htonl(pad[p]); + } + while (len--) + *data++ ^= pad[p++ & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127]; +} + +void CLASS sony_load_raw() +{ + uchar head[40]; + ushort *pixel; + unsigned i, key, row, col; + + fseek (ifp, 200896, SEEK_SET); + fseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR); + order = 0x4d4d; + key = get4(); + fseek (ifp, 164600, SEEK_SET); + fread (head, 1, 40, ifp); + sony_decrypt ((unsigned int *) head, 10, 1, key); + for (i=26; i-- > 22; ) + key = key << 8 | head[i]; + fseek (ifp, data_offset, SEEK_SET); + pixel = (ushort *) calloc (raw_width, sizeof *pixel); + merror (pixel, "sony_load_raw()"); + for (row=0; row < height; row++) { + if (fread (pixel, 2, raw_width, ifp) < raw_width) derror(); + sony_decrypt ((unsigned int *) pixel, raw_width/2, !row, key); + for (col=9; col < left_margin; col++) + black += ntohs(pixel[col]); + for (col=0; col < width; col++) + if ((BAYER(row,col) = ntohs(pixel[col+left_margin])) >> 14) + derror(); + } + free (pixel); + if (left_margin > 9) + black /= (left_margin-9) * height; + maximum = 0x3ff0; +} + +void CLASS sony_arw_load_raw() +{ + ushort huff[32768]; + static const ushort tab[18] = + { 0xf11,0xf10,0xe0f,0xd0e,0xc0d,0xb0c,0xa0b,0x90a,0x809, + 0x708,0x607,0x506,0x405,0x304,0x303,0x300,0x202,0x201 }; + int i, c, n, col, row, len, diff, sum=0; + + for (n=i=0; i < 18; i++) + FORC(32768 >> (tab[i] >> 8)) huff[n++] = tab[i]; + getbits(-1); + for (col = raw_width; col--; ) + for (row=0; row < raw_height+1; row+=2) { + if (row == raw_height) row = 1; + len = getbithuff(15,huff); + diff = getbits(len); + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + if ((sum += diff) >> 12) derror(); + if (row < height) BAYER(row,col) = sum; + } +} + +void CLASS sony_arw2_load_raw() +{ + uchar *data, *dp; + ushort pix[16]; + int row, col, val, max, min, imax, imin, sh, bit, i; + + data = (uchar *) malloc (raw_width); + merror (data, "sony_arw2_load_raw()"); + for (row=0; row < height; row++) { + fread (data, 1, raw_width, ifp); + for (dp=data, col=0; col < width-30; dp+=16) { + max = 0x7ff & (val = sget4(dp)); + min = 0x7ff & val >> 11; + imax = 0x0f & val >> 22; + imin = 0x0f & val >> 26; + for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++); + for (bit=30, i=0; i < 16; i++) + if (i == imax) pix[i] = max; + else if (i == imin) pix[i] = min; + else { + pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min; + if (pix[i] > 0x7ff) pix[i] = 0x7ff; + bit += 7; + } + for (i=0; i < 16; i++, col+=2) + BAYER(row,col) = curve[pix[i] << 1] >> 1; + col -= col & 1 ? 1:31; + } + } + free (data); +} + +#define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1) + +/* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */ +void CLASS smal_decode_segment (unsigned seg[2][2], int holes) +{ + uchar hist[3][13] = { + { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 }, + { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 }, + { 3, 3, 0, 0, 63, 47, 31, 15, 0 } }; + int low, high=0xff, carry=0, nbits=8; + int s, count, bin, next, i, sym[3]; + uchar diff, pred[]={0,0}; + ushort data=0, range=0; + unsigned pix, row, col; + + fseek (ifp, seg[0][1]+1, SEEK_SET); + getbits(-1); + for (pix=seg[0][0]; pix < seg[1][0]; pix++) { + for (s=0; s < 3; s++) { + data = data << nbits | getbits(nbits); + if (carry < 0) + carry = (nbits += carry+1) < 1 ? nbits-1 : 0; + while (--nbits >= 0) + if ((data >> nbits & 0xff) == 0xff) break; + if (nbits > 0) + data = ((data & ((1 << (nbits-1)) - 1)) << 1) | + ((data + (((data & (1 << (nbits-1)))) << 1)) & (-1 << nbits)); + if (nbits >= 0) { + data += getbits(1); + carry = nbits - 8; + } + count = ((((data-range+1) & 0xffff) << 2) - 1) / (high >> 4); + for (bin=0; hist[s][bin+5] > count; bin++); + low = hist[s][bin+5] * (high >> 4) >> 2; + if (bin) high = hist[s][bin+4] * (high >> 4) >> 2; + high -= low; + for (nbits=0; high << nbits < 128; nbits++); + range = (range+low) << nbits; + high <<= nbits; + next = hist[s][1]; + if (++hist[s][2] > hist[s][3]) { + next = (next+1) & hist[s][0]; + hist[s][3] = (hist[s][next+4] - hist[s][next+5]) >> 2; + hist[s][2] = 1; + } + if (hist[s][hist[s][1]+4] - hist[s][hist[s][1]+5] > 1) { + if (bin < hist[s][1]) + for (i=bin; i < hist[s][1]; i++) hist[s][i+5]--; + else if (next <= bin) + for (i=hist[s][1]; i < bin; i++) hist[s][i+5]++; + } + hist[s][1] = next; + sym[s] = bin; + } + diff = sym[2] << 5 | sym[1] << 2 | (sym[0] & 3); + if (sym[0] & 4) + diff = diff ? -diff : 0x80; + if (ftell(ifp) + 12 >= seg[1][1]) + diff = 0; + pred[pix & 1] += diff; + row = pix / raw_width - top_margin; + col = pix % raw_width - left_margin; + if (row < height && col < width) + BAYER(row,col) = pred[pix & 1]; + if (!(pix & 1) && HOLE(row)) pix += 2; + } + maximum = 0xff; +} + +void CLASS smal_v6_load_raw() +{ + unsigned seg[2][2]; + + fseek (ifp, 16, SEEK_SET); + seg[0][0] = 0; + seg[0][1] = get2(); + seg[1][0] = raw_width * raw_height; + seg[1][1] = INT_MAX; + smal_decode_segment (seg, 0); +} + +int CLASS median4 (int *p) +{ + int min, max, sum, i; + + min = max = sum = p[0]; + for (i=1; i < 4; i++) { + sum += p[i]; + if (min > p[i]) min = p[i]; + if (max < p[i]) max = p[i]; + } + return (sum - min - max) >> 1; +} + +void CLASS fill_holes (int holes) +{ + int row, col, val[4]; + + for (row=2; row < height-2; row++) { + if (!HOLE(row)) continue; + for (col=1; col < width-1; col+=4) { + val[0] = BAYER(row-1,col-1); + val[1] = BAYER(row-1,col+1); + val[2] = BAYER(row+1,col-1); + val[3] = BAYER(row+1,col+1); + BAYER(row,col) = median4(val); + } + for (col=2; col < width-2; col+=4) + if (HOLE(row-2) || HOLE(row+2)) + BAYER(row,col) = (BAYER(row,col-2) + BAYER(row,col+2)) >> 1; + else { + val[0] = BAYER(row,col-2); + val[1] = BAYER(row,col+2); + val[2] = BAYER(row-2,col); + val[3] = BAYER(row+2,col); + BAYER(row,col) = median4(val); + } + } +} + +void CLASS smal_v9_load_raw() +{ + unsigned seg[256][2], offset, nseg, holes, i; + + fseek (ifp, 67, SEEK_SET); + offset = get4(); + nseg = fgetc(ifp); + fseek (ifp, offset, SEEK_SET); + for (i=0; i < nseg*2; i++) + seg[0][i] = get4() + data_offset*(i & 1); + fseek (ifp, 78, SEEK_SET); + holes = fgetc(ifp); + fseek (ifp, 88, SEEK_SET); + seg[nseg][0] = raw_height * raw_width; + seg[nseg][1] = get4() + data_offset; + for (i=0; i < nseg; i++) + smal_decode_segment (seg+i, holes); + if (holes) fill_holes (holes); +} + +/* RESTRICTED code starts here */ + +void CLASS foveon_decoder (unsigned size, unsigned code) +{ + static unsigned huff[1024]; + struct decode *cur; + int i, len; + + if (!code) { + for (i=0; i < size; i++) + huff[i] = get4(); + memset (first_decode, 0, sizeof first_decode); + free_decode = first_decode; + } + cur = free_decode++; + if (free_decode > first_decode+2048) { + fprintf (stderr,_("%s: decoder table overflow\n"), ifname); + longjmp (failure, 2); + } + if (code) + for (i=0; i < size; i++) + if (huff[i] == code) { + cur->leaf = i; + return; + } + if ((len = code >> 27) > 26) return; + code = (len+1) << 27 | (code & 0x3ffffff) << 1; + + cur->branch[0] = free_decode; + foveon_decoder (size, code); + cur->branch[1] = free_decode; + foveon_decoder (size, code+1); +} + +void CLASS foveon_thumb() +{ + unsigned bwide, row, col, bitbuf=0, bit=1, c, i; + char *buf; + struct decode *dindex; + short pred[3]; + + bwide = get4(); + fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); + if (bwide > 0) { + if (bwide < thumb_width*3) return; + buf = (char *) malloc (bwide); + merror (buf, "foveon_thumb()"); + for (row=0; row < thumb_height; row++) { + fread (buf, 1, bwide, ifp); + fwrite (buf, 3, thumb_width, ofp); + } + free (buf); + return; + } + foveon_decoder (256, 0); + + for (row=0; row < thumb_height; row++) { + memset (pred, 0, sizeof pred); + if (!bit) get4(); + for (bit=col=0; col < thumb_width; col++) + FORC3 { + for (dindex=first_decode; dindex->branch[0]; ) { + if ((bit = (bit-1) & 31) == 31) + for (i=0; i < 4; i++) + bitbuf = (bitbuf << 8) + fgetc(ifp); + dindex = dindex->branch[bitbuf >> bit & 1]; + } + pred[c] += dindex->leaf; + fputc (pred[c], ofp); + } + } +} + +void CLASS foveon_load_camf() +{ + unsigned key, i, val; + + fseek (ifp, meta_offset, SEEK_SET); + key = get4(); + fread (meta_data, 1, meta_length, ifp); + for (i=0; i < meta_length; i++) { + key = (key * 1597 + 51749) % 244944; + val = key * (INT64) 301593171 >> 24; + meta_data[i] ^= ((((key << 8) - val) >> 1) + val) >> 17; + } +} + +void CLASS foveon_load_raw() +{ + struct decode *dindex; + short diff[1024]; + unsigned bitbuf=0; + int pred[3], fixed, row, col, bit=-1, c, i; + + fixed = get4(); + read_shorts ((ushort *) diff, 1024); + if (!fixed) foveon_decoder (1024, 0); + + for (row=0; row < height; row++) { + memset (pred, 0, sizeof pred); + if (!bit && !fixed && atoi(model+2) < 14) get4(); + for (col=bit=0; col < width; col++) { + if (fixed) { + bitbuf = get4(); + FORC3 pred[2-c] += diff[bitbuf >> c*10 & 0x3ff]; + } + else FORC3 { + for (dindex=first_decode; dindex->branch[0]; ) { + if ((bit = (bit-1) & 31) == 31) + for (i=0; i < 4; i++) + bitbuf = (bitbuf << 8) + fgetc(ifp); + dindex = dindex->branch[bitbuf >> bit & 1]; + } + pred[c] += diff[dindex->leaf]; + if (pred[c] >> 16 && ~pred[c] >> 16) derror(); + } + FORC3 image[row*width+col][c] = pred[c]; + } + } + if (document_mode) + for (i=0; i < height*width*4; i++) + if ((short) image[0][i] < 0) image[0][i] = 0; + foveon_load_camf(); +} + +const char * CLASS foveon_camf_param (const char *block, const char *param) +{ + unsigned idx, num; + char *pos, *cp, *dp; + + for (idx=0; idx < meta_length; idx += sget4(pos+8)) { + pos = meta_data + idx; + if (strncmp (pos, "CMb", 3)) break; + if (pos[3] != 'P') continue; + if (strcmp (block, pos+sget4(pos+12))) continue; + cp = pos + sget4(pos+16); + num = sget4(cp); + dp = pos + sget4(cp+4); + while (num--) { + cp += 8; + if (!strcmp (param, dp+sget4(cp))) + return dp+sget4(cp+4); + } + } + return 0; +} + +void * CLASS foveon_camf_matrix (unsigned dim[3], const char *name) +{ + unsigned i, idx, type, ndim, size, *mat; + char *pos, *cp, *dp; + double dsize; + + for (idx=0; idx < meta_length; idx += sget4(pos+8)) { + pos = meta_data + idx; + if (strncmp (pos, "CMb", 3)) break; + if (pos[3] != 'M') continue; + if (strcmp (name, pos+sget4(pos+12))) continue; + dim[0] = dim[1] = dim[2] = 1; + cp = pos + sget4(pos+16); + type = sget4(cp); + if ((ndim = sget4(cp+4)) > 3) break; + dp = pos + sget4(cp+8); + for (i=ndim; i--; ) { + cp += 12; + dim[i] = sget4(cp); + } + if ((dsize = (double) dim[0]*dim[1]*dim[2]) > meta_length/4) break; + mat = (unsigned *) malloc ((size = dsize) * 4); + merror (mat, "foveon_camf_matrix()"); + for (i=0; i < size; i++) + if (type && type != 6) + mat[i] = sget4(dp + i*4); + else + mat[i] = sget4(dp + i*2) & 0xffff; + return mat; + } + fprintf (stderr,_("%s: \"%s\" matrix not found!\n"), ifname, name); + return 0; +} + +int CLASS foveon_fixed (void *ptr, int size, const char *name) +{ + void *dp; + unsigned dim[3]; + + dp = foveon_camf_matrix (dim, name); + if (!dp) return 0; + memcpy (ptr, dp, size*4); + free (dp); + return 1; +} + +float CLASS foveon_avg (short *pix, int range[2], float cfilt) +{ + int i; + float val, min=FLT_MAX, max=-FLT_MAX, sum=0; + + for (i=range[0]; i <= range[1]; i++) { + sum += val = pix[i*4] + (pix[i*4]-pix[(i-1)*4]) * cfilt; + if (min > val) min = val; + if (max < val) max = val; + } + if (range[1] - range[0] == 1) return sum/2; + return (sum - min - max) / (range[1] - range[0] - 1); +} + +short * CLASS foveon_make_curve (double max, double mul, double filt) +{ + short *curve; + unsigned i, size; + double x; + + if (!filt) filt = 0.8; + size = 4*M_PI*max / filt; + if (size == UINT_MAX) size--; + curve = (short *) calloc (size+1, sizeof *curve); + merror (curve, "foveon_make_curve()"); + curve[0] = size; + for (i=0; i < size; i++) { + x = i*filt/max/4; + curve[i+1] = (cos(x)+1)/2 * tanh(i*filt/mul) * mul + 0.5; + } + return curve; +} + +void CLASS foveon_make_curves + (short **curvep, float dq[3], float div[3], float filt) +{ + double mul[3], max=0; + int c; + + FORC3 mul[c] = dq[c]/div[c]; + FORC3 if (max < mul[c]) max = mul[c]; + FORC3 curvep[c] = foveon_make_curve (max, mul[c], filt); +} + +int CLASS foveon_apply_curve (short *curve, int i) +{ + if (abs(i) >= curve[0]) return 0; + return i < 0 ? -curve[1-i] : curve[1+i]; +} + +#define image ((short (*)[4]) image) + +void CLASS foveon_interpolate() +{ + static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 }; + short *pix, prev[3], *curve[8], (*shrink)[3]; + float cfilt=0, ddft[3][3][2], ppm[3][3][3]; + float cam_xyz[3][3], correct[3][3], last[3][3], trans[3][3]; + float chroma_dq[3], color_dq[3], diag[3][3], div[3]; + float (*black)[3], (*sgain)[3], (*sgrow)[3]; + float fsum[3], val, frow, num; + int row, col, c, i, j, diff, sgx, irow, sum, min, max, limit; + int dscr[2][2], dstb[4], (*smrow[7])[3], total[4], ipix[3]; + int work[3][3], smlast, smred, smred_p=0, dev[3]; + int satlev[3], keep[4], active[4]; + unsigned dim[3], *badpix; + double dsum=0, trsum[3]; + char str[128]; + const char* cp; + + if (verbose) + fprintf (stderr,_("Foveon interpolation...\n")); + + foveon_fixed (dscr, 4, "DarkShieldColRange"); + foveon_fixed (ppm[0][0], 27, "PostPolyMatrix"); + foveon_fixed (satlev, 3, "SaturationLevel"); + foveon_fixed (keep, 4, "KeepImageArea"); + foveon_fixed (active, 4, "ActiveImageArea"); + foveon_fixed (chroma_dq, 3, "ChromaDQ"); + foveon_fixed (color_dq, 3, + foveon_camf_param ("IncludeBlocks", "ColorDQ") ? + "ColorDQ" : "ColorDQCamRGB"); + if (foveon_camf_param ("IncludeBlocks", "ColumnFilter")) + foveon_fixed (&cfilt, 1, "ColumnFilter"); + + memset (ddft, 0, sizeof ddft); + if (!foveon_camf_param ("IncludeBlocks", "DarkDrift") + || !foveon_fixed (ddft[1][0], 12, "DarkDrift")) + for (i=0; i < 2; i++) { + foveon_fixed (dstb, 4, i ? "DarkShieldBottom":"DarkShieldTop"); + for (row = dstb[1]; row <= dstb[3]; row++) + for (col = dstb[0]; col <= dstb[2]; col++) + FORC3 ddft[i+1][c][1] += (short) image[row*width+col][c]; + FORC3 ddft[i+1][c][1] /= (dstb[3]-dstb[1]+1) * (dstb[2]-dstb[0]+1); + } + + if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2))) + { fprintf (stderr,_("%s: Invalid white balance \"%s\"\n"), ifname, model2); + return; } + foveon_fixed (cam_xyz, 9, cp); + foveon_fixed (correct, 9, + foveon_camf_param ("WhiteBalanceCorrections", model2)); + memset (last, 0, sizeof last); + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + FORC3 last[i][j] += correct[i][c] * cam_xyz[c][j]; + + #define LAST(x,y) last[(i+x)%3][(c+y)%3] + for (i=0; i < 3; i++) + FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1); + #undef LAST + FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583; + sprintf (str, "%sRGBNeutral", model2); + if (foveon_camf_param ("IncludeBlocks", str)) + foveon_fixed (div, 3, str); + num = 0; + FORC3 if (num < div[c]) num = div[c]; + FORC3 div[c] /= num; + + memset (trans, 0, sizeof trans); + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + FORC3 trans[i][j] += rgb_cam[i][c] * last[c][j] * div[j]; + FORC3 trsum[c] = trans[c][0] + trans[c][1] + trans[c][2]; + dsum = (6*trsum[0] + 11*trsum[1] + 3*trsum[2]) / 20; + for (i=0; i < 3; i++) + FORC3 last[i][c] = trans[i][c] * dsum / trsum[i]; + memset (trans, 0, sizeof trans); + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + FORC3 trans[i][j] += (i==c ? 32 : -1) * last[c][j] / 30; + + foveon_make_curves (curve, color_dq, div, cfilt); + FORC3 chroma_dq[c] /= 3; + foveon_make_curves (curve+3, chroma_dq, div, cfilt); + FORC3 dsum += chroma_dq[c] / div[c]; + curve[6] = foveon_make_curve (dsum, dsum, cfilt); + curve[7] = foveon_make_curve (dsum*2, dsum*2, cfilt); + + sgain = (float (*)[3]) foveon_camf_matrix (dim, "SpatialGain"); + if (!sgain) return; + sgrow = (float (*)[3]) calloc (dim[1], sizeof *sgrow); + sgx = (width + dim[1]-2) / (dim[1]-1); + + black = (float (*)[3]) calloc (height, sizeof *black); + for (row=0; row < height; row++) { + for (i=0; i < 6; i++) + ddft[0][0][i] = ddft[1][0][i] + + row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][i]); + FORC3 black[row][c] = + ( foveon_avg (image[row*width]+c, dscr[0], cfilt) + + foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3 + - ddft[0][c][0] ) / 4 - ddft[0][c][1]; + } + memcpy (black, black+8, sizeof *black*8); + memcpy (black+height-11, black+height-22, 11*sizeof *black); + memcpy (last, black, sizeof last); + + for (row=1; row < height-1; row++) { + FORC3 if (last[1][c] > last[0][c]) { + if (last[1][c] > last[2][c]) + black[row][c] = (last[0][c] > last[2][c]) ? last[0][c]:last[2][c]; + } else + if (last[1][c] < last[2][c]) + black[row][c] = (last[0][c] < last[2][c]) ? last[0][c]:last[2][c]; + memmove (last, last+1, 2*sizeof last[0]); + memcpy (last[2], black[row+1], sizeof last[2]); + } + FORC3 black[row][c] = (last[0][c] + last[1][c])/2; + FORC3 black[0][c] = (black[1][c] + black[3][c])/2; + + val = 1 - exp(-1/24.0); + memcpy (fsum, black, sizeof fsum); + for (row=1; row < height; row++) + FORC3 fsum[c] += black[row][c] = + (black[row][c] - black[row-1][c])*val + black[row-1][c]; + memcpy (last[0], black[height-1], sizeof last[0]); + FORC3 fsum[c] /= height; + for (row = height; row--; ) + FORC3 last[0][c] = black[row][c] = + (black[row][c] - fsum[c] - last[0][c])*val + last[0][c]; + + memset (total, 0, sizeof total); + for (row=2; row < height; row+=4) + for (col=2; col < width; col+=4) { + FORC3 total[c] += (short) image[row*width+col][c]; + total[3]++; + } + for (row=0; row < height; row++) + FORC3 black[row][c] += fsum[c]/2 + total[c]/(total[3]*100.0); + + for (row=0; row < height; row++) { + for (i=0; i < 6; i++) + ddft[0][0][i] = ddft[1][0][i] + + row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][i]); + pix = image[row*width]; + memcpy (prev, pix, sizeof prev); + frow = row / (height-1.0) * (dim[2]-1); + if ((irow = frow) == dim[2]-1) irow--; + frow -= irow; + for (i=0; i < dim[1]; i++) + FORC3 sgrow[i][c] = sgain[ irow *dim[1]+i][c] * (1-frow) + + sgain[(irow+1)*dim[1]+i][c] * frow; + for (col=0; col < width; col++) { + FORC3 { + diff = pix[c] - prev[c]; + prev[c] = pix[c]; + ipix[c] = pix[c] + floor ((diff + (diff*diff >> 14)) * cfilt + - ddft[0][c][1] - ddft[0][c][0] * ((float) col/width - 0.5) + - black[row][c] ); + } + FORC3 { + work[0][c] = ipix[c] * ipix[c] >> 14; + work[2][c] = ipix[c] * work[0][c] >> 14; + work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14; + } + FORC3 { + for (val=i=0; i < 3; i++) + for ( j=0; j < 3; j++) + val += ppm[c][i][j] * work[i][j]; + ipix[c] = floor ((ipix[c] + floor(val)) * + ( sgrow[col/sgx ][c] * (sgx - col%sgx) + + sgrow[col/sgx+1][c] * (col%sgx) ) / sgx / div[c]); + if (ipix[c] > 32000) ipix[c] = 32000; + pix[c] = ipix[c]; + } + pix += 4; + } + } + free (black); + free (sgrow); + free (sgain); + + if ((badpix = (unsigned int *) foveon_camf_matrix (dim, "BadPixels"))) { + for (i=0; i < dim[0]; i++) { + col = (badpix[i] >> 8 & 0xfff) - keep[0]; + row = (badpix[i] >> 20 ) - keep[1]; + if ((unsigned)(row-1) > height-3 || (unsigned)(col-1) > width-3) + continue; + memset (fsum, 0, sizeof fsum); + for (sum=j=0; j < 8; j++) + if (badpix[i] & (1 << j)) { + FORC3 fsum[c] += (short) + image[(row+hood[j*2])*width+col+hood[j*2+1]][c]; + sum++; + } + if (sum) FORC3 image[row*width+col][c] = fsum[c]/sum; + } + free (badpix); + } + + /* Array for 5x5 Gaussian averaging of red values */ + smrow[6] = (int (*)[3]) calloc (width*5, sizeof **smrow); + merror (smrow[6], "foveon_interpolate()"); + for (i=0; i < 5; i++) + smrow[i] = smrow[6] + i*width; + + /* Sharpen the reds against these Gaussian averages */ + for (smlast=-1, row=2; row < height-2; row++) { + while (smlast < row+2) { + for (i=0; i < 6; i++) + smrow[(i+5) % 6] = smrow[i]; + pix = image[++smlast*width+2]; + for (col=2; col < width-2; col++) { + smrow[4][col][0] = + (pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4; + pix += 4; + } + } + pix = image[row*width+2]; + for (col=2; col < width-2; col++) { + smred = ( 6 * smrow[2][col][0] + + 4 * (smrow[1][col][0] + smrow[3][col][0]) + + smrow[0][col][0] + smrow[4][col][0] + 8 ) >> 4; + if (col == 2) + smred_p = smred; + i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 3); + if (i > 32000) i = 32000; + pix[0] = i; + smred_p = smred; + pix += 4; + } + } + + /* Adjust the brighter pixels for better linearity */ + min = 0xffff; + FORC3 { + i = satlev[c] / div[c]; + if (min > i) min = i; + } + limit = min * 9 >> 4; + for (pix=image[0]; pix < image[height*width]; pix+=4) { + if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit) + continue; + min = max = pix[0]; + for (c=1; c < 3; c++) { + if (min > pix[c]) min = pix[c]; + if (max < pix[c]) max = pix[c]; + } + if (min >= limit*2) { + pix[0] = pix[1] = pix[2] = max; + } else { + i = 0x4000 - ((min - limit) << 14) / limit; + i = 0x4000 - (i*i >> 14); + i = i*i >> 14; + FORC3 pix[c] += (max - pix[c]) * i >> 14; + } + } +/* + Because photons that miss one detector often hit another, + the sum R+G+B is much less noisy than the individual colors. + So smooth the hues without smoothing the total. + */ + for (smlast=-1, row=2; row < height-2; row++) { + while (smlast < row+2) { + for (i=0; i < 6; i++) + smrow[(i+5) % 6] = smrow[i]; + pix = image[++smlast*width+2]; + for (col=2; col < width-2; col++) { + FORC3 smrow[4][col][c] = (pix[c-4]+2*pix[c]+pix[c+4]+2) >> 2; + pix += 4; + } + } + pix = image[row*width+2]; + for (col=2; col < width-2; col++) { + FORC3 dev[c] = -foveon_apply_curve (curve[7], pix[c] - + ((smrow[1][col][c] + 2*smrow[2][col][c] + smrow[3][col][c]) >> 2)); + sum = (dev[0] + dev[1] + dev[2]) >> 3; + FORC3 pix[c] += dev[c] - sum; + pix += 4; + } + } + for (smlast=-1, row=2; row < height-2; row++) { + while (smlast < row+2) { + for (i=0; i < 6; i++) + smrow[(i+5) % 6] = smrow[i]; + pix = image[++smlast*width+2]; + for (col=2; col < width-2; col++) { + FORC3 smrow[4][col][c] = + (pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8]+2) >> 2; + pix += 4; + } + } + pix = image[row*width+2]; + for (col=2; col < width-2; col++) { + for (total[3]=375, sum=60, c=0; c < 3; c++) { + for (total[c]=i=0; i < 5; i++) + total[c] += smrow[i][col][c]; + total[3] += total[c]; + sum += pix[c]; + } + if (sum < 0) sum = 0; + j = total[3] > 375 ? (sum << 16) / total[3] : sum * 174; + FORC3 pix[c] += foveon_apply_curve (curve[6], + ((j*total[c] + 0x8000) >> 16) - pix[c]); + pix += 4; + } + } + + /* Transform the image to a different colorspace */ + for (pix=image[0]; pix < image[height*width]; pix+=4) { + FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]); + sum = (pix[0]+pix[1]+pix[1]+pix[2]) >> 2; + FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]-sum); + FORC3 { + for (dsum=i=0; i < 3; i++) + dsum += trans[c][i] * pix[i]; + if (dsum < 0) dsum = 0; + if (dsum > 24000) dsum = 24000; + ipix[c] = dsum + 0.5; + } + FORC3 pix[c] = ipix[c]; + } + + /* Smooth the image bottom-to-top and save at 1/4 scale */ + shrink = (short (*)[3]) calloc ((width/4) * (height/4), sizeof *shrink); + merror (shrink, "foveon_interpolate()"); + for (row = height/4; row--; ) + for (col=0; col < width/4; col++) { + ipix[0] = ipix[1] = ipix[2] = 0; + for (i=0; i < 4; i++) + for (j=0; j < 4; j++) + FORC3 ipix[c] += image[(row*4+i)*width+col*4+j][c]; + FORC3 + if (row+2 > height/4) + shrink[row*(width/4)+col][c] = ipix[c] >> 4; + else + shrink[row*(width/4)+col][c] = + (shrink[(row+1)*(width/4)+col][c]*1840 + ipix[c]*141 + 2048) >> 12; + } + /* From the 1/4-scale image, smooth right-to-left */ + for (row=0; row < (height & ~3); row++) { + ipix[0] = ipix[1] = ipix[2] = 0; + if ((row & 3) == 0) + for (col = width & ~3 ; col--; ) + FORC3 smrow[0][col][c] = ipix[c] = + (shrink[(row/4)*(width/4)+col/4][c]*1485 + ipix[c]*6707 + 4096) >> 13; + + /* Then smooth left-to-right */ + ipix[0] = ipix[1] = ipix[2] = 0; + for (col=0; col < (width & ~3); col++) + FORC3 smrow[1][col][c] = ipix[c] = + (smrow[0][col][c]*1485 + ipix[c]*6707 + 4096) >> 13; + + /* Smooth top-to-bottom */ + if (row == 0) + memcpy (smrow[2], smrow[1], sizeof **smrow * width); + else + for (col=0; col < (width & ~3); col++) + FORC3 smrow[2][col][c] = + (smrow[2][col][c]*6707 + smrow[1][col][c]*1485 + 4096) >> 13; + + /* Adjust the chroma toward the smooth values */ + for (col=0; col < (width & ~3); col++) { + for (i=j=30, c=0; c < 3; c++) { + i += smrow[2][col][c]; + j += image[row*width+col][c]; + } + j = (j << 16) / i; + for (sum=c=0; c < 3; c++) { + ipix[c] = foveon_apply_curve (curve[c+3], + ((smrow[2][col][c] * j + 0x8000) >> 16) - image[row*width+col][c]); + sum += ipix[c]; + } + sum >>= 3; + FORC3 { + i = image[row*width+col][c] + ipix[c] - sum; + if (i < 0) i = 0; + image[row*width+col][c] = i; + } + } + } + free (shrink); + free (smrow[6]); + for (i=0; i < 8; i++) + free (curve[i]); + + /* Trim off the black border */ + active[1] -= keep[1]; + active[3] -= 2; + i = active[2] - active[0]; + for (row=0; row < active[3]-active[1]; row++) + memcpy (image[row*i], image[(row+active[1])*width+active[0]], + i * sizeof *image); + width = i; + height = row; +} +#undef image + +/* RESTRICTED code ends here */ + +/* + Seach from the current directory up to the root looking for + a ".badpixels" file, and fix those pixels now. + */ +void CLASS bad_pixels (const char *cfname) +{ + FILE *fp=0; + char *fname, *cp, line[128]; + int len, time, row, col, r, c, rad, tot, n, fixed=0; + + if (!filters) return; + if (cfname) + fp = fopen (cfname, "r"); + else { + for (len=32 ; ; len *= 2) { + fname = (char *) malloc (len); + if (!fname) return; + if (getcwd (fname, len-16)) break; + free (fname); + if (errno != ERANGE) return; + } +#if defined(WIN32) || defined(DJGPP) + if (fname[1] == ':') + memmove (fname, fname+2, len-2); + for (cp=fname; *cp; cp++) + if (*cp == '\\') *cp = '/'; +#endif + cp = fname + strlen(fname); + if (cp[-1] == '/') cp--; + while (*fname == '/') { + strcpy (cp, "/.badpixels"); + if ((fp = fopen (fname, "r"))) break; + if (cp == fname) break; + while (*--cp != '/'); + } + free (fname); + } + if (!fp) return; + while (fgets (line, 128, fp)) { + cp = strchr (line, '#'); + if (cp) *cp = 0; + if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue; + if ((unsigned) col >= width || (unsigned) row >= height) continue; + if (time > timestamp) continue; + for (tot=n=0, rad=1; rad < 3 && n==0; rad++) + for (r = row-rad; r <= row+rad; r++) + for (c = col-rad; c <= col+rad; c++) + if ((unsigned) r < height && (unsigned) c < width && + (r != row || c != col) && fc(r,c) == fc(row,col)) { + tot += BAYER2(r,c); + n++; + } + BAYER2(row,col) = tot/n; + if (verbose) { + if (!fixed++) + fprintf (stderr,_("Fixed dead pixels at:")); + fprintf (stderr, " %d,%d", col, row); + } + } + if (fixed) fputc ('\n', stderr); + fclose (fp); +} + +void CLASS subtract (const char *fname) +{ + FILE *fp; + int dim[3]={0,0,0}, comment=0, number=0, error=0, nd=0, c, row, col; + ushort *pixel; + + if (!(fp = fopen (fname, "rb"))) { + perror (fname); return; + } + if (fgetc(fp) != 'P' || fgetc(fp) != '5') error = 1; + while (!error && nd < 3 && (c = fgetc(fp)) != EOF) { + if (c == '#') comment = 1; + if (c == '\n') comment = 0; + if (comment) continue; + if (isdigit(c)) number = 1; + if (number) { + if (isdigit(c)) dim[nd] = dim[nd]*10 + c -'0'; + else if (isspace(c)) { + number = 0; nd++; + } else error = 1; + } + } + if (error || nd < 3) { + fprintf (stderr,_("%s is not a valid PGM file!\n"), fname); + fclose (fp); return; + } else if (dim[0] != width || dim[1] != height || dim[2] != 65535) { + fprintf (stderr,_("%s has the wrong dimensions!\n"), fname); + fclose (fp); return; + } + pixel = (ushort *) calloc (width, sizeof *pixel); + merror (pixel, "subtract()"); + for (row=0; row < height; row++) { + fread (pixel, 2, width, fp); + for (col=0; col < width; col++) + BAYER(row,col) = MAX (BAYER(row,col) - ntohs(pixel[col]), 0); + } + free (pixel); + black = 0; +} + +void CLASS gamma_curve (double pwr, double ts, int mode, int imax) +{ + int i; + double g[6], bnd[2]={0,0}, r; + + g[0] = pwr; + g[1] = ts; + g[2] = g[3] = g[4] = 0; + bnd[g[1] >= 1] = 1; + if (g[1] && (g[1]-1)*(g[0]-1) <= 0) { + for (i=0; i < 48; i++) { + g[2] = (bnd[0] + bnd[1])/2; + if (g[0]) bnd[(pow(g[2]/g[1],-g[0]) - 1)/g[0] - 1/g[2] > -1] = g[2]; + else bnd[g[2]/exp(1-1/g[2]) < g[1]] = g[2]; + } + g[3] = g[2] / g[1]; + if (g[0]) g[4] = g[2] * (1/g[0] - 1); + } + if (g[0]) g[5] = 1 / (g[1]*SQR(g[3])/2 - g[4]*(1 - g[3]) + + (1 - pow(g[3],1+g[0]))*(1 + g[4])/(1 + g[0])) - 1; + else g[5] = 1 / (g[1]*SQR(g[3])/2 + 1 + - g[2] - g[3] - g[2]*g[3]*(log(g[3]) - 1)) - 1; + if (!mode--) { + memcpy (gamm, g, sizeof gamm); + return; + } + for (i=0; i < 0x10000; i++) { + curve[i] = 0xffff; + if ((r = (double) i / imax) < 1) + curve[i] = 0x10000 * ( mode + ? (r < g[3] ? r*g[1] : (g[0] ? pow( r,g[0])*(1+g[4])-g[4] : log(r)*g[2]+1)) + : (r < g[2] ? r/g[1] : (g[0] ? pow((r+g[4])/(1+g[4]),1/g[0]) : exp((r-1)/g[2])))); + } +} + +void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size) +{ + double work[3][6], num; + int i, j, k; + + for (i=0; i < 3; i++) { + for (j=0; j < 6; j++) + work[i][j] = j == i+3; + for (j=0; j < 3; j++) + for (k=0; k < size; k++) + work[i][j] += in[k][i] * in[k][j]; + } + for (i=0; i < 3; i++) { + num = work[i][i]; + for (j=0; j < 6; j++) + work[i][j] /= num; + for (k=0; k < 3; k++) { + if (k==i) continue; + num = work[k][i]; + for (j=0; j < 6; j++) + work[k][j] -= work[i][j] * num; + } + } + for (i=0; i < size; i++) + for (j=0; j < 3; j++) + for (out[i][j]=k=0; k < 3; k++) + out[i][j] += work[j][k+3] * in[i][k]; +} + +void CLASS cam_xyz_coeff (double cam_xyz[4][3]) +{ + double cam_rgb[4][3], inverse[4][3], num; + int i, j, k; + + for (i=0; i < colors; i++) /* Multiply out XYZ colorspace */ + for (j=0; j < 3; j++) + for (cam_rgb[i][j] = k=0; k < 3; k++) + cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j]; + + for (i=0; i < colors; i++) { /* Normalize cam_rgb so that */ + for (num=j=0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */ + num += cam_rgb[i][j]; + for (j=0; j < 3; j++) + cam_rgb[i][j] /= num; + pre_mul[i] = 1 / num; + } + pseudoinverse (cam_rgb, inverse, colors); + for (raw_color = i=0; i < 3; i++) + for (j=0; j < colors; j++) + rgb_cam[i][j] = inverse[j][i]; +} + +#ifdef COLORCHECK +void CLASS colorcheck() +{ +#define NSQ 24 +// Coordinates of the GretagMacbeth ColorChecker squares +// width, height, 1st_column, 1st_row + int cut[NSQ][4]; // you must set these +// ColorChecker Chart under 6500-kelvin illumination + static const double gmb_xyY[NSQ][3] = { + { 0.400, 0.350, 10.1 }, // Dark Skin + { 0.377, 0.345, 35.8 }, // Light Skin + { 0.247, 0.251, 19.3 }, // Blue Sky + { 0.337, 0.422, 13.3 }, // Foliage + { 0.265, 0.240, 24.3 }, // Blue Flower + { 0.261, 0.343, 43.1 }, // Bluish Green + { 0.506, 0.407, 30.1 }, // Orange + { 0.211, 0.175, 12.0 }, // Purplish Blue + { 0.453, 0.306, 19.8 }, // Moderate Red + { 0.285, 0.202, 6.6 }, // Purple + { 0.380, 0.489, 44.3 }, // Yellow Green + { 0.473, 0.438, 43.1 }, // Orange Yellow + { 0.187, 0.129, 6.1 }, // Blue + { 0.305, 0.478, 23.4 }, // Green + { 0.539, 0.313, 12.0 }, // Red + { 0.448, 0.470, 59.1 }, // Yellow + { 0.364, 0.233, 19.8 }, // Magenta + { 0.196, 0.252, 19.8 }, // Cyan + { 0.310, 0.316, 90.0 }, // White + { 0.310, 0.316, 59.1 }, // Neutral 8 + { 0.310, 0.316, 36.2 }, // Neutral 6.5 + { 0.310, 0.316, 19.8 }, // Neutral 5 + { 0.310, 0.316, 9.0 }, // Neutral 3.5 + { 0.310, 0.316, 3.1 } }; // Black + double gmb_cam[NSQ][4], gmb_xyz[NSQ][3]; + double inverse[NSQ][3], cam_xyz[4][3], num; + int c, i, j, k, sq, row, col, count[4]; + + memset (gmb_cam, 0, sizeof gmb_cam); + for (sq=0; sq < NSQ; sq++) { + FORCC count[c] = 0; + for (row=cut[sq][3]; row < cut[sq][3]+cut[sq][1]; row++) + for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) { + c = FC(row,col); + if (c >= colors) c -= 2; + gmb_cam[sq][c] += BAYER(row,col); + count[c]++; + } + FORCC gmb_cam[sq][c] = gmb_cam[sq][c]/count[c] - black; + gmb_xyz[sq][0] = gmb_xyY[sq][2] * gmb_xyY[sq][0] / gmb_xyY[sq][1]; + gmb_xyz[sq][1] = gmb_xyY[sq][2]; + gmb_xyz[sq][2] = gmb_xyY[sq][2] * + (1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1]; + } + pseudoinverse (gmb_xyz, inverse, NSQ); + for (i=0; i < colors; i++) + for (j=0; j < 3; j++) + for (cam_xyz[i][j] = k=0; k < NSQ; k++) + cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j]; + cam_xyz_coeff (cam_xyz); + if (verbose) { + printf (" { \"%s %s\", %d,\n\t{", make, model, black); + num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]); + FORCC for (j=0; j < 3; j++) + printf ("%c%d", (c | j) ? ',':' ', (int) (cam_xyz[c][j] * num + 0.5)); + puts (" } },"); + } +#undef NSQ +} +#endif + +void CLASS hat_transform (float *temp, float *base, int st, int size, int sc) +{ + int i; + for (i=0; i < sc; i++) + temp[i] = 2*base[st*i] + base[st*(sc-i)] + base[st*(i+sc)]; + for (; i+sc < size; i++) + temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(i+sc)]; + for (; i < size; i++) + temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(2*size-2-(i+sc))]; +} + +void CLASS wavelet_denoise() +{ + float *fimg=0, *temp, thold, mul[2], avg, diff; + int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast; + ushort *window[4]; + static const float noise[] = + { 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 }; + + if (verbose) fprintf (stderr,_("Wavelet denoising...\n")); + + while (maximum << scale < 0x10000) scale++; + maximum <<= --scale; + black <<= scale; + if ((size = iheight*iwidth) < 0x15550000) + fimg = (float *) malloc ((size*3 + iheight + iwidth) * sizeof *fimg); + merror (fimg, "wavelet_denoise()"); + temp = fimg + size*3; + if ((nc = colors) == 3 && filters) nc++; + FORC(nc) { /* denoise R,G1,B,G3 individually */ + for (i=0; i < size; i++) + fimg[i] = 256 * sqrt(image[i][c] << scale); + for (hpass=lev=0; lev < 5; lev++) { + lpass = size*((lev & 1)+1); + for (row=0; row < iheight; row++) { + hat_transform (temp, fimg+hpass+row*iwidth, 1, iwidth, 1 << lev); + for (col=0; col < iwidth; col++) + fimg[lpass + row*iwidth + col] = temp[col] * 0.25; + } + for (col=0; col < iwidth; col++) { + hat_transform (temp, fimg+lpass+col, iwidth, iheight, 1 << lev); + for (row=0; row < iheight; row++) + fimg[lpass + row*iwidth + col] = temp[row] * 0.25; + } + thold = threshold * noise[lev]; + for (i=0; i < size; i++) { + fimg[hpass+i] -= fimg[lpass+i]; + if (fimg[hpass+i] < -thold) fimg[hpass+i] += thold; + else if (fimg[hpass+i] > thold) fimg[hpass+i] -= thold; + else fimg[hpass+i] = 0; + if (hpass) fimg[i] += fimg[hpass+i]; + } + hpass = lpass; + } + for (i=0; i < size; i++) + image[i][c] = CLIP(SQR(fimg[i]+fimg[lpass+i])/0x10000); + } + if (filters && colors == 3) { /* pull G1 and G3 closer together */ + for (row=0; row < 2; row++) + mul[row] = 0.125 * pre_mul[FC(row+1,0) | 1] / pre_mul[FC(row,0) | 1]; + for (i=0; i < 4; i++) + window[i] = (ushort *) fimg + width*i; + for (wlast=-1, row=1; row < height-1; row++) { + while (wlast < row+1) { + for (wlast++, i=0; i < 4; i++) + window[(i+3) & 3] = window[i]; + for (col = FC(wlast,1) & 1; col < width; col+=2) + window[2][col] = BAYER(wlast,col); + } + thold = threshold/512; + for (col = (FC(row,0) & 1)+1; col < width-1; col+=2) { + avg = ( window[0][col-1] + window[0][col+1] + + window[2][col-1] + window[2][col+1] - black*4 ) + * mul[row & 1] + (window[1][col] - black) * 0.5 + black; + avg = avg < 0 ? 0 : sqrt(avg); + diff = sqrt(BAYER(row,col)) - avg; + if (diff < -thold) diff += thold; + else if (diff > thold) diff -= thold; + else diff = 0; + BAYER(row,col) = CLIP(SQR(avg+diff) + 0.5); + } + } + } + free (fimg); +} + +void CLASS scale_colors() +{ + unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8]; + int val, dark, sat; + double dsum[8], dmin, dmax; + float scale_mul[4], fr, fc; + ushort *img=0, *pix; + + if (user_mul[0]) + memcpy (pre_mul, user_mul, sizeof pre_mul); + if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) { + memset (dsum, 0, sizeof dsum); + bottom = MIN (greybox[1]+greybox[3], height); + right = MIN (greybox[0]+greybox[2], width); + for (row=greybox[1]; row < bottom; row += 8) + for (col=greybox[0]; col < right; col += 8) { + memset (sum, 0, sizeof sum); + for (y=row; y < row+8 && y < bottom; y++) + for (x=col; x < col+8 && x < right; x++) + FORC4 { + if (filters) { + c = FC(y,x); + val = BAYER(y,x); + } else + val = image[y*width+x][c]; + if (val > maximum-25) goto skip_block; + if ((val -= black) < 0) val = 0; + sum[c] += val; + sum[c+4]++; + if (filters) break; + } + FORC(8) dsum[c] += sum[c]; +skip_block: ; + } + FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c]; + } + if (use_camera_wb && cam_mul[0] != -1) { + memset (sum, 0, sizeof sum); + for (row=0; row < 8; row++) + for (col=0; col < 8; col++) { + c = FC(row,col); + if ((val = white[row][col] - black) > 0) + sum[c] += val; + sum[c+4]++; + } + if (sum[0] && sum[1] && sum[2] && sum[3]) + FORC4 pre_mul[c] = (float) sum[c+4] / sum[c]; + else if (cam_mul[0] && cam_mul[2]) + memcpy (pre_mul, cam_mul, sizeof pre_mul); + else + fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname); + } + if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1; + dark = black; + sat = maximum; + if (threshold) wavelet_denoise(); + maximum -= black; + for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) { + if (dmin > pre_mul[c]) + dmin = pre_mul[c]; + if (dmax < pre_mul[c]) + dmax = pre_mul[c]; + } + if (!highlight) dmax = dmin; + FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum; + if (verbose) { + fprintf (stderr, + _("Scaling with darkness %d, saturation %d, and\nmultipliers"), dark, sat); + FORC4 fprintf (stderr, " %f", pre_mul[c]); + fputc ('\n', stderr); + } + size = iheight*iwidth; + for (i=0; i < size*4; i++) { + val = image[0][i]; + if (!val) continue; + val -= black; + val *= scale_mul[i & 3]; + image[0][i] = CLIP(val); + } + if ((aber[0] != 1 || aber[2] != 1) && colors == 3) { + if (verbose) + fprintf (stderr,_("Correcting chromatic aberration...\n")); + for (c=0; c < 4; c+=2) { + if (aber[c] == 1) continue; + img = (ushort *) malloc (size * sizeof *img); + merror (img, "scale_colors()"); + for (i=0; i < size; i++) + img[i] = image[i][c]; + for (row=0; row < iheight; row++) { + ur = fr = (row - iheight*0.5) * aber[c] + iheight*0.5; + if (ur > iheight-2) continue; + fr -= ur; + for (col=0; col < iwidth; col++) { + uc = fc = (col - iwidth*0.5) * aber[c] + iwidth*0.5; + if (uc > iwidth-2) continue; + fc -= uc; + pix = img + ur*iwidth + uc; + image[row*iwidth+col][c] = + (pix[ 0]*(1-fc) + pix[ 1]*fc) * (1-fr) + + (pix[iwidth]*(1-fc) + pix[iwidth+1]*fc) * fr; + } + } + free(img); + } + } +} + +void CLASS pre_interpolate() +{ + ushort (*img)[4]; + int row, col, c; + + if (shrink) { + if (half_size) { + height = iheight; + width = iwidth; + } else { + img = (ushort (*)[4]) calloc (height*width, sizeof *img); + merror (img, "pre_interpolate()"); + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + c = fc(row,col); + img[row*width+col][c] = image[(row >> 1)*iwidth+(col >> 1)][c]; + } + free (image); + image = img; + shrink = 0; + } + } + if (filters && colors == 3) { + if ((mix_green = four_color_rgb)) colors++; + else { + for (row = FC(1,0) >> 1; row < height; row+=2) + for (col = FC(row,1) & 1; col < width; col+=2) + image[row*width+col][1] = image[row*width+col][3]; + filters &= ~((filters & 0x55555555) << 1); + } + } + if (half_size) filters = 0; +} + +void CLASS border_interpolate (int border) +{ + unsigned row, col, y, x, f, c, sum[8]; + + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + if (col==border && row >= border && row < height-border) + col = width-border; + memset (sum, 0, sizeof sum); + for (y=row-1; y != row+2; y++) + for (x=col-1; x != col+2; x++) + if (y < height && x < width) { + f = fc(y,x); + sum[f] += image[y*width+x][f]; + sum[f+4]++; + } + f = fc(row,col); + FORCC if (c != f && sum[c+4]) + image[row*width+col][c] = sum[c] / sum[c+4]; + } +} + +void CLASS lin_interpolate() +{ + int code[16][16][32], *ip, sum[4]; + int c, i, x, y, row, col, shift, color; + ushort *pix; + + if (verbose) fprintf (stderr,_("Bilinear interpolation...\n")); + + border_interpolate(1); + for (row=0; row < 16; row++) + for (col=0; col < 16; col++) { + ip = code[row][col]; + memset (sum, 0, sizeof sum); + for (y=-1; y <= 1; y++) + for (x=-1; x <= 1; x++) { + shift = (y==0) + (x==0); + if (shift == 2) continue; + color = fc(row+y,col+x); + *ip++ = (width*y + x)*4 + color; + *ip++ = shift; + *ip++ = color; + sum[color] += 1 << shift; + } + FORCC + if (c != fc(row,col)) { + *ip++ = c; + *ip++ = 256 / sum[c]; + } + } + for (row=1; row < height-1; row++) + for (col=1; col < width-1; col++) { + pix = image[row*width+col]; + ip = code[row & 15][col & 15]; + memset (sum, 0, sizeof sum); + for (i=8; i--; ip+=3) + sum[ip[2]] += pix[ip[0]] << ip[1]; + for (i=colors; --i; ip+=2) + pix[ip[0]] = sum[ip[0]] * ip[1] >> 8; + } +} + +/* + This algorithm is officially called: + + "Interpolation using a Threshold-based variable number of gradients" + + described in http://scien.stanford.edu/class/psych221/projects/99/tingchen/algodep/vargra.html + + I've extended the basic idea to work with non-Bayer filter arrays. + Gradients are numbered clockwise from NW=0 to W=7. + */ +void CLASS vng_interpolate() +{ + static const signed char *cp, terms[] = { + -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01, + -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01, + -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03, + -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06, + -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04, + -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01, + -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40, + -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11, + -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11, + -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22, + -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44, + -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10, + -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04, + +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40, + +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20, + +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08, + +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20, + +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44, + +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60, + +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80, + +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40, + +1,+0,+2,+1,0,0x10 + }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 }; + ushort (*brow[5])[4], *pix; + int prow=7, pcol=1, *ip, *code[16][16], gval[8], gmin, gmax, sum[4]; + int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag; + int g, diff, thold, num, c; + + lin_interpolate(); + if (verbose) fprintf (stderr,_("VNG interpolation...\n")); + + if (filters == 1) prow = pcol = 15; + ip = (int *) calloc ((prow+1)*(pcol+1), 1280); + merror (ip, "vng_interpolate()"); + for (row=0; row <= prow; row++) /* Precalculate for VNG */ + for (col=0; col <= pcol; col++) { + code[row][col] = ip; + for (cp=terms, t=0; t < 64; t++) { + y1 = *cp++; x1 = *cp++; + y2 = *cp++; x2 = *cp++; + weight = *cp++; + grads = *cp++; + color = fc(row+y1,col+x1); + if (fc(row+y2,col+x2) != color) continue; + diag = (fc(row,col+1) == color && fc(row+1,col) == color) ? 2:1; + if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue; + *ip++ = (y1*width + x1)*4 + color; + *ip++ = (y2*width + x2)*4 + color; + *ip++ = weight; + for (g=0; g < 8; g++) + if (grads & 1< gval[g]) gmin = gval[g]; + if (gmax < gval[g]) gmax = gval[g]; + } + if (gmax == 0) { + memcpy (brow[2][col], pix, sizeof *image); + continue; + } + thold = gmin + (gmax >> 1); + memset (sum, 0, sizeof sum); + color = fc(row,col); + for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */ + if (gval[g] <= thold) { + FORCC + if (c == color && ip[1]) + sum[c] += (pix[c] + pix[ip[1]]) >> 1; + else + sum[c] += pix[ip[0] + c]; + num++; + } + } + FORCC { /* Save to buffer */ + t = pix[color]; + if (c != color) + t += (sum[c] - sum[color]) / num; + brow[2][col][c] = CLIP(t); + } + } + if (row > 3) /* Write buffer to image */ + memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image); + for (g=0; g < 4; g++) + brow[(g-1) & 3] = brow[g]; + } + memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image); + memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image); + free (brow[4]); + free (code[0][0]); +} + +/* + Patterned Pixel Grouping Interpolation by Alain Desbiolles +*/ +void CLASS ppg_interpolate() +{ + int dir[5] = { 1, width, -1, -width, 1 }; + int row, col, diff[2], guess[2], c, d, i; + ushort (*pix)[4]; + + border_interpolate(3); + if (verbose) fprintf (stderr,_("PPG interpolation...\n")); + +/* Fill in the green layer with gradients and pattern recognition: */ + for (row=3; row < height-3; row++) + for (col=3+(FC(row,3) & 1), c=FC(row,col); col < width-3; col+=2) { + pix = image + row*width+col; + for (i=0; (d=dir[i]) > 0; i++) { + guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2 + - pix[-2*d][c] - pix[2*d][c]; + diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) + + ABS(pix[ 2*d][c] - pix[ 0][c]) + + ABS(pix[ -d][1] - pix[ d][1]) ) * 3 + + ( ABS(pix[ 3*d][1] - pix[ d][1]) + + ABS(pix[-3*d][1] - pix[-d][1]) ) * 2; + } + d = dir[i = diff[0] > diff[1]]; + pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]); + } +/* Calculate red and blue for each green pixel: */ + for (row=1; row < height-1; row++) + for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < width-1; col+=2) { + pix = image + row*width+col; + for (i=0; (d=dir[i]) > 0; c=2-c, i++) + pix[0][c] = CLIP((pix[-d][c] + pix[d][c] + 2*pix[0][1] + - pix[-d][1] - pix[d][1]) >> 1); + } +/* Calculate blue for red pixels and vice versa: */ + for (row=1; row < height-1; row++) + for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < width-1; col+=2) { + pix = image + row*width+col; + for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) { + diff[i] = ABS(pix[-d][c] - pix[d][c]) + + ABS(pix[-d][1] - pix[0][1]) + + ABS(pix[ d][1] - pix[0][1]); + guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1] + - pix[-d][1] - pix[d][1]; + } + if (diff[0] != diff[1]) + pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1); + else + pix[0][c] = CLIP((guess[0]+guess[1]) >> 2); + } +} + +/* + Adaptive Homogeneity-Directed interpolation is based on + the work of Keigo Hirakawa, Thomas Parks, and Paul Lee. + */ +#define TS 256 /* Tile Size */ + +void CLASS ahd_interpolate() +{ + int i, j, k, top, left, row, col, tr, tc, c, d, val, hm[2]; + ushort (*pix)[4], (*rix)[3]; + static const int dir[4] = { -1, 1, -TS, TS }; + unsigned ldiff[2][4], abdiff[2][4], leps, abeps; + float r, cbrt[0x10000], xyz[3], xyz_cam[3][4]; + ushort (*rgb)[TS][TS][3]; + short (*lab)[TS][TS][3], (*lix)[3]; + char (*homo)[TS][TS], *buffer; + + if (verbose) fprintf (stderr,_("AHD interpolation...\n")); + + for (i=0; i < 0x10000; i++) { + r = i / 65535.0; + cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0; + } + for (i=0; i < 3; i++) + for (j=0; j < colors; j++) + for (xyz_cam[i][j] = k=0; k < 3; k++) + xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i]; + + border_interpolate(5); + buffer = (char *) malloc (26*TS*TS); /* 1664 kB */ + merror (buffer, "ahd_interpolate()"); + rgb = (ushort(*)[TS][TS][3]) buffer; + lab = (short (*)[TS][TS][3])(buffer + 12*TS*TS); + homo = (char (*)[TS][TS]) (buffer + 24*TS*TS); + + for (top=2; top < height-5; top += TS-6) + for (left=2; left < width-5; left += TS-6) { + +/* Interpolate green horizontally and vertically: */ + for (row = top; row < top+TS && row < height-2; row++) { + col = left + (FC(row,left) & 1); + for (c = FC(row,col); col < left+TS && col < width-2; col+=2) { + pix = image + row*width+col; + val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2 + - pix[-2][c] - pix[2][c]) >> 2; + rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]); + val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2 + - pix[-2*width][c] - pix[2*width][c]) >> 2; + rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]); + } + } +/* Interpolate red and blue, and convert to CIELab: */ + for (d=0; d < 2; d++) + for (row=top+1; row < top+TS-1 && row < height-3; row++) + for (col=left+1; col < left+TS-1 && col < width-3; col++) { + pix = image + row*width+col; + rix = &rgb[d][row-top][col-left]; + lix = &lab[d][row-top][col-left]; + if ((c = 2 - FC(row,col)) == 1) { + c = FC(row+1,col); + val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c] + - rix[-1][1] - rix[1][1] ) >> 1); + rix[0][2-c] = CLIP(val); + val = pix[0][1] + (( pix[-width][c] + pix[width][c] + - rix[-TS][1] - rix[TS][1] ) >> 1); + } else + val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c] + + pix[+width-1][c] + pix[+width+1][c] + - rix[-TS-1][1] - rix[-TS+1][1] + - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2); + rix[0][c] = CLIP(val); + c = FC(row,col); + rix[0][c] = pix[0][c]; + xyz[0] = xyz[1] = xyz[2] = 0.5; + FORCC { + xyz[0] += xyz_cam[0][c] * rix[0][c]; + xyz[1] += xyz_cam[1][c] * rix[0][c]; + xyz[2] += xyz_cam[2][c] * rix[0][c]; + } + xyz[0] = cbrt[CLIP((int) xyz[0])]; + xyz[1] = cbrt[CLIP((int) xyz[1])]; + xyz[2] = cbrt[CLIP((int) xyz[2])]; + lix[0][0] = 64 * (116 * xyz[1] - 16); + lix[0][1] = 64 * 500 * (xyz[0] - xyz[1]); + lix[0][2] = 64 * 200 * (xyz[1] - xyz[2]); + } +/* Build homogeneity maps from the CIELab images: */ + memset (homo, 0, 2*TS*TS); + for (row=top+2; row < top+TS-2 && row < height-4; row++) { + tr = row-top; + for (col=left+2; col < left+TS-2 && col < width-4; col++) { + tc = col-left; + for (d=0; d < 2; d++) { + lix = &lab[d][tr][tc]; + for (i=0; i < 4; i++) { + ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]); + abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1]) + + SQR(lix[0][2]-lix[dir[i]][2]); + } + } + leps = MIN(MAX(ldiff[0][0],ldiff[0][1]), + MAX(ldiff[1][2],ldiff[1][3])); + abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]), + MAX(abdiff[1][2],abdiff[1][3])); + for (d=0; d < 2; d++) + for (i=0; i < 4; i++) + if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps) + homo[d][tr][tc]++; + } + } +/* Combine the most homogenous pixels for the final result: */ + for (row=top+3; row < top+TS-3 && row < height-5; row++) { + tr = row-top; + for (col=left+3; col < left+TS-3 && col < width-5; col++) { + tc = col-left; + for (d=0; d < 2; d++) + for (hm[d]=0, i=tr-1; i <= tr+1; i++) + for (j=tc-1; j <= tc+1; j++) + hm[d] += homo[d][i][j]; + if (hm[0] != hm[1]) + FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c]; + else + FORC3 image[row*width+col][c] = + (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1; + } + } + } + free (buffer); +} +#undef TS + +void CLASS median_filter() +{ + ushort (*pix)[4]; + int pass, c, i, j, k, med[9]; + static const uchar opt[] = /* Optimal 9-element median search */ + { 1,2, 4,5, 7,8, 0,1, 3,4, 6,7, 1,2, 4,5, 7,8, + 0,3, 5,8, 4,7, 3,6, 1,4, 2,5, 4,7, 4,2, 6,4, 4,2 }; + + for (pass=1; pass <= med_passes; pass++) { + if (verbose) + fprintf (stderr,_("Median filter pass %d...\n"), pass); + for (c=0; c < 3; c+=2) { + for (pix = image; pix < image+width*height; pix++) + pix[0][3] = pix[0][c]; + for (pix = image+width; pix < image+width*(height-1); pix++) { + if ((pix-image+1) % width < 2) continue; + for (k=0, i = -width; i <= width; i += width) + for (j = i-1; j <= i+1; j++) + med[k++] = pix[j][3] - pix[j][1]; + for (i=0; i < sizeof opt; i+=2) + if (med[opt[i]] > med[opt[i+1]]) + SWAP (med[opt[i]] , med[opt[i+1]]); + pix[0][c] = CLIP(med[4] + pix[0][1]); + } + } + } +} + +void CLASS blend_highlights() +{ + int clip=INT_MAX, row, col, c, i, j; + static const float trans[2][4][4] = + { { { 1,1,1 }, { 1.7320508,-1.7320508,0 }, { -1,-1,2 } }, + { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } }; + static const float itrans[2][4][4] = + { { { 1,0.8660254,-0.5 }, { 1,-0.8660254,-0.5 }, { 1,0,1 } }, + { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } }; + float cam[2][4], lab[2][4], sum[2], chratio; + + if ((unsigned) (colors-3) > 1) return; + if (verbose) fprintf (stderr,_("Blending highlights...\n")); + FORCC if (clip > (i = 65535*pre_mul[c])) clip = i; + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + FORCC if (image[row*width+col][c] > clip) break; + if (c == colors) continue; + FORCC { + cam[0][c] = image[row*width+col][c]; + cam[1][c] = MIN(cam[0][c],clip); + } + for (i=0; i < 2; i++) { + FORCC for (lab[i][c]=j=0; j < colors; j++) + lab[i][c] += trans[colors-3][c][j] * cam[i][j]; + for (sum[i]=0,c=1; c < colors; c++) + sum[i] += SQR(lab[i][c]); + } + chratio = sqrt(sum[1]/sum[0]); + for (c=1; c < colors; c++) + lab[0][c] *= chratio; + FORCC for (cam[0][c]=j=0; j < colors; j++) + cam[0][c] += itrans[colors-3][c][j] * lab[0][j]; + FORCC image[row*width+col][c] = cam[0][c] / colors; + } +} + +#define SCALE (4 >> shrink) +void CLASS recover_highlights() +{ + float *map, sum, wgt, grow; + int hsat[4], count, spread, change, val, i; + unsigned high, wide, mrow, mcol, row, col, kc, c, d, y, x; + ushort *pixel; + static const signed char dir[8][2] = + { {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} }; + + if (verbose) fprintf (stderr,_("Rebuilding highlights...\n")); + + grow = pow (2, 4-highlight); + FORCC hsat[c] = 32000 * pre_mul[c]; + for (kc=0, c=1; c < colors; c++) + if (pre_mul[kc] < pre_mul[c]) kc = c; + high = height / SCALE; + wide = width / SCALE; + map = (float *) calloc (high*wide, sizeof *map); + merror (map, "recover_highlights()"); + FORCC if (c != kc) { + memset (map, 0, high*wide*sizeof *map); + for (mrow=0; mrow < high; mrow++) + for (mcol=0; mcol < wide; mcol++) { + sum = wgt = count = 0; + for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++) + for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) { + pixel = image[row*width+col]; + if (pixel[c] / hsat[c] == 1 && pixel[kc] > 24000) { + sum += pixel[c]; + wgt += pixel[kc]; + count++; + } + } + if (count == SCALE*SCALE) + map[mrow*wide+mcol] = sum / wgt; + } + for (spread = 32/grow; spread--; ) { + for (mrow=0; mrow < high; mrow++) + for (mcol=0; mcol < wide; mcol++) { + if (map[mrow*wide+mcol]) continue; + sum = count = 0; + for (d=0; d < 8; d++) { + y = mrow + dir[d][0]; + x = mcol + dir[d][1]; + if (y < high && x < wide && map[y*wide+x] > 0) { + sum += (1 + (d & 1)) * map[y*wide+x]; + count += 1 + (d & 1); + } + } + if (count > 3) + map[mrow*wide+mcol] = - (sum+grow) / (count+grow); + } + for (change=i=0; i < high*wide; i++) + if (map[i] < 0) { + map[i] = -map[i]; + change = 1; + } + if (!change) break; + } + for (i=0; i < high*wide; i++) + if (map[i] == 0) map[i] = 1; + for (mrow=0; mrow < high; mrow++) + for (mcol=0; mcol < wide; mcol++) { + for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++) + for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) { + pixel = image[row*width+col]; + if (pixel[c] / hsat[c] > 1) { + val = pixel[kc] * map[mrow*wide+mcol]; + if (pixel[c] < val) pixel[c] = CLIP(val); + } + } + } + } + free (map); +} +#undef SCALE + +void CLASS tiff_get (unsigned base, + unsigned *tag, unsigned *type, unsigned *len, unsigned *save) +{ + *tag = get2(); + *type = get2(); + *len = get4(); + *save = ftell(ifp) + 4; + if (*len * ("11124811248488"[*type < 14 ? *type:0]-'0') > 4) + fseek (ifp, get4()+base, SEEK_SET); +} + +void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen) +{ + unsigned entries, tag, type, len, save; + + entries = get2(); + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + if (tag == toff) thumb_offset = get4()+base; + if (tag == tlen) thumb_length = get4(); + fseek (ifp, save, SEEK_SET); + } +} + +int CLASS parse_tiff_ifd (int base); + +void CLASS parse_makernote (int base, int uptag) +{ + static const uchar xlat[2][256] = { + { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d, + 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d, + 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f, + 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f, + 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1, + 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17, + 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89, + 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f, + 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b, + 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb, + 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3, + 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f, + 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35, + 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43, + 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5, + 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 }, + { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c, + 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34, + 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad, + 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05, + 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee, + 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d, + 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b, + 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b, + 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc, + 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33, + 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8, + 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6, + 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c, + 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49, + 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb, + 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } }; + unsigned offset=0, entries, tag, type, len, save, c; + unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0}; + uchar buf97[324], ci, cj, ck; + short sorder=order; + char buf[10]; +/* + The MakerNote might have its own TIFF header (possibly with + its own byte-order!), or it might just be a table. + */ + fread (buf, 1, 10, ifp); + if (!strncmp (buf,"KDK" ,3) || /* these aren't TIFF tables */ + !strncmp (buf,"VER" ,3) || + !strncmp (buf,"IIII",4) || + !strncmp (buf,"MMMM",4)) return; + if (!strncmp (buf,"KC" ,2) || /* Konica KD-400Z, KD-510Z */ + !strncmp (buf,"MLY" ,3)) { /* Minolta DiMAGE G series */ + order = 0x4d4d; + while ((i=ftell(ifp)) < data_offset && i < 16384) { + wb[0] = wb[2]; wb[2] = wb[1]; wb[1] = wb[3]; + wb[3] = get2(); + if (wb[1] == 256 && wb[3] == 256 && + wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640) + FORC4 cam_mul[c] = wb[c]; + } + goto quit; + } + if (!strcmp (buf,"Nikon")) { + base = ftell(ifp); + order = get2(); + if (get2() != 42) goto quit; + offset = get4(); + fseek (ifp, offset-8, SEEK_CUR); + } else if (!strcmp (buf,"OLYMPUS")) { + base = ftell(ifp)-10; + fseek (ifp, -2, SEEK_CUR); + order = get2(); get2(); + } else if (!strncmp (buf,"FUJIFILM",8) || + !strncmp (buf,"SONY",4) || + !strcmp (buf,"Panasonic")) { + order = 0x4949; + fseek (ifp, 2, SEEK_CUR); + } else if (!strcmp (buf,"OLYMP") || + !strcmp (buf,"LEICA") || + !strcmp (buf,"Ricoh") || + !strcmp (buf,"EPSON")) + fseek (ifp, -2, SEEK_CUR); + else if (!strcmp (buf,"AOC") || + !strcmp (buf,"QVC")) + fseek (ifp, -4, SEEK_CUR); + else fseek (ifp, -10, SEEK_CUR); + + entries = get2(); + if (entries > 1000) return; + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + tag |= uptag << 16; + if (tag == 2 && strstr(make,"NIKON")) + iso_speed = (get2(),get2()); + if (tag == 4 && len > 26 && len < 35) { + if ((i=(get4(),get2())) != 0x7fff && !iso_speed) + iso_speed = 50 * pow (2, i/32.0 - 4); + if ((i=(get2(),get2())) != 0x7fff && !aperture) + aperture = pow (2, i/64.0); + if ((i=get2()) != 0xffff && !shutter) + shutter = pow (2, (short) i/-32.0); + wbi = (get2(),get2()); + shot_order = (get2(),get2()); + } + if ((tag == 4 || tag == 0x114) && !strncmp(make,"KONICA",6)) { + fseek (ifp, tag == 4 ? 140:160, SEEK_CUR); + switch (get2()) { + case 72: flip = 0; break; + case 76: flip = 6; break; + case 82: flip = 5; break; + } + } + if (tag == 7 && type == 2 && len > 20) + fgets (model2, 64, ifp); + if (tag == 8 && type == 4) + shot_order = get4(); + if (tag == 9 && !strcmp(make,"Canon")) + fread (artist, 64, 1, ifp); + if (tag == 0xc && len == 4) { + cam_mul[0] = getreal(type); + cam_mul[2] = getreal(type); + } + if (tag == 0x10 && type == 4) + unique_id = get4(); + if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) { + fseek (ifp, get4()+base, SEEK_SET); + parse_tiff_ifd (base); + } + if (tag == 0x14 && len == 2560 && type == 7) { + fseek (ifp, 1248, SEEK_CUR); + goto get2_256; + } + if (tag == 0x15 && type == 2 && is_raw) + fread (model, 64, 1, ifp); + if (strstr(make,"PENTAX")) { + if (tag == 0x1b) tag = 0x1018; + if (tag == 0x1c) tag = 0x1017; + } + if (tag == 0x1d) + while ((c = fgetc(ifp)) && c != EOF) + serial = serial*10 + (isdigit(c) ? c - '0' : c % 10); + if (tag == 0x81 && type == 4) { + data_offset = get4(); + fseek (ifp, data_offset + 41, SEEK_SET); + raw_height = get2() * 2; + raw_width = get2(); + filters = 0x61616161; + } + if (tag == 0x29 && type == 1) { + c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0; + fseek (ifp, 8 + c*32, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4(); + } + if ((tag == 0x81 && type == 7) || + (tag == 0x100 && type == 7) || + (tag == 0x280 && type == 1)) { + thumb_offset = ftell(ifp); + thumb_length = len; + } + if (tag == 0x88 && type == 4 && (thumb_offset = get4())) + thumb_offset += base; + if (tag == 0x89 && type == 4) + thumb_length = get4(); + if (tag == 0x8c || tag == 0x96) + meta_offset = ftell(ifp); + if (tag == 0x97) { + for (i=0; i < 4; i++) + ver97 = ver97 * 10 + fgetc(ifp)-'0'; + switch (ver97) { + case 100: + fseek (ifp, 68, SEEK_CUR); + FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2(); + break; + case 102: + fseek (ifp, 6, SEEK_CUR); + goto get2_rggb; + case 103: + fseek (ifp, 16, SEEK_CUR); + FORC4 cam_mul[c] = get2(); + } + if (ver97 >= 200) { + if (ver97 != 205) fseek (ifp, 280, SEEK_CUR); + fread (buf97, 324, 1, ifp); + } + } + if (tag == 0xa4 && type == 3) { + fseek (ifp, wbi*48, SEEK_CUR); + FORC3 cam_mul[c] = get2(); + } + if (tag == 0xa7 && (unsigned) (ver97-200) < 12 && !cam_mul[0]) { + ci = xlat[0][serial & 0xff]; + cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)]; + ck = 0x60; + for (i=0; i < 324; i++) + buf97[i] ^= (cj += ci * ck++); + i = "66666>666;6A"[ver97-200] - '0'; + FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] = + sget2 (buf97 + (i & -2) + c*2); + } + if (tag == 0x200 && len == 3) + shot_order = (get4(),get4()); + if (tag == 0x200 && len == 4) + black = (get2()+get2()+get2()+get2())/4; + if (tag == 0x201 && len == 4) + goto get2_rggb; + if (tag == 0x220 && len == 53) + meta_offset = ftell(ifp) + 14; + if (tag == 0x401 && type == 4 && len == 4) { + black = (get4()+get4()+get4()+get4())/4; + } + if (tag == 0xe01) { /* Nikon Capture Note */ + type = order; + order = 0x4949; + fseek (ifp, 22, SEEK_CUR); + for (offset=22; offset+22 < len; offset += 22+i) { + tag = get4(); + fseek (ifp, 14, SEEK_CUR); + i = get4()-4; + if (tag == 0x76a43207) flip = get2(); + else fseek (ifp, i, SEEK_CUR); + } + order = type; + } + if (tag == 0xe80 && len == 256 && type == 7) { + fseek (ifp, 48, SEEK_CUR); + cam_mul[0] = get2() * 508 * 1.078 / 0x10000; + cam_mul[2] = get2() * 382 * 1.173 / 0x10000; + } + if (tag == 0xf00 && type == 7) { + if (len == 614) + fseek (ifp, 176, SEEK_CUR); + else if (len == 734 || len == 1502) + fseek (ifp, 148, SEEK_CUR); + else goto next; + goto get2_256; + } + if ((tag == 0x1011 && len == 9) || tag == 0x20400200) + for (i=0; i < 3; i++) + FORC3 cmatrix[i][c] = ((short) get2()) / 256.0; + if ((tag == 0x1012 || tag == 0x20400600) && len == 4) + for (black = i=0; i < 4; i++) + black += get2() << 2; + if (tag == 0x1017 || tag == 0x20400100) + cam_mul[0] = get2() / 256.0; + if (tag == 0x1018 || tag == 0x20400100) + cam_mul[2] = get2() / 256.0; + if (tag == 0x2011 && len == 2) { +get2_256: + order = 0x4d4d; + cam_mul[0] = get2() / 256.0; + cam_mul[2] = get2() / 256.0; + } + if ((tag | 0x70) == 0x2070 && type == 4) + fseek (ifp, get4()+base, SEEK_SET); + if (tag == 0x2010 && type != 7) + load_raw = &CLASS olympus_load_raw; + if (tag == 0x2020) + parse_thumb_note (base, 257, 258); + if (tag == 0x2040) + parse_makernote (base, 0x2040); + if (tag == 0xb028) { + fseek (ifp, get4(), SEEK_SET); + parse_thumb_note (base, 136, 137); + } + if (tag == 0x4001 && len > 500) { + i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126; + fseek (ifp, i, SEEK_CUR); +get2_rggb: + FORC4 cam_mul[c ^ (c >> 1)] = get2(); + fseek (ifp, 22, SEEK_CUR); + FORC4 sraw_mul[c ^ (c >> 1)] = get2(); + } +next: + fseek (ifp, save, SEEK_SET); + } +quit: + order = sorder; +} + +/* + Since the TIFF DateTime string has no timezone information, + assume that the camera's clock was set to Universal Time. + */ +void CLASS get_timestamp (int reversed) +{ + struct tm t; + char str[20]; + int i; + + str[19] = 0; + if (reversed) + for (i=19; i--; ) str[i] = fgetc(ifp); + else + fread (str, 19, 1, ifp); + memset (&t, 0, sizeof t); + if (sscanf (str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon, + &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6) + return; + t.tm_year -= 1900; + t.tm_mon -= 1; + if (mktime(&t) > 0) + timestamp = mktime(&t); +} + +void CLASS parse_exif (int base) +{ + unsigned kodak, entries, tag, type, len, save, c; + double expo; + + kodak = !strncmp(make,"EASTMAN",7); + entries = get2(); + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + switch (tag) { + case 33434: shutter = getreal(type); break; + case 33437: aperture = getreal(type); break; + case 34855: iso_speed = get2(); break; + case 36867: + case 36868: get_timestamp(0); break; + case 37377: if ((expo = -getreal(type)) < 128) + shutter = pow (2, expo); break; + case 37378: aperture = pow (2, getreal(type)/2); break; + case 37386: focal_len = getreal(type); break; + case 37500: parse_makernote (base, 0); break; + case 40962: if (kodak) raw_width = get4(); break; + case 40963: if (kodak) raw_height = get4(); break; + case 41730: + if (get4() == 0x20002) + for (exif_cfa=c=0; c < 8; c+=2) + exif_cfa |= fgetc(ifp) * 0x01010101 << c; + } + fseek (ifp, save, SEEK_SET); + } +} + +void CLASS parse_gps (int base) +{ + unsigned entries, tag, type, len, save, c; + + entries = get2(); + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + switch (tag) { + case 1: case 3: case 5: + gpsdata[29+tag/2] = getc(ifp); break; + case 2: case 4: case 7: + FORC(6) gpsdata[tag/3*6+c] = get4(); break; + case 6: + FORC(2) gpsdata[18+c] = get4(); break; + case 18: case 29: + fgets ((char *) (gpsdata+14+tag/3), MIN(len,12), ifp); + } + fseek (ifp, save, SEEK_SET); + } +} + +void CLASS romm_coeff (float romm_cam[3][3]) +{ + static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */ + { { 2.034193, -0.727420, -0.306766 }, + { -0.228811, 1.231729, -0.002922 }, + { -0.008565, -0.153273, 1.161839 } }; + int i, j, k; + + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + for (cmatrix[i][j] = k=0; k < 3; k++) + cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j]; +} + +void CLASS parse_mos (int offset) +{ + char data[40]; + int skip, from, i, c, neut[4], planes=0, frot=0; + static const char *mod[] = + { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22", + "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65", + "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7" }; + float romm_cam[3][3]; + + fseek (ifp, offset, SEEK_SET); + while (1) { + if (get4() != 0x504b5453) break; + get4(); + fread (data, 1, 40, ifp); + skip = get4(); + from = ftell(ifp); + if (!strcmp(data,"JPEG_preview_data")) { + thumb_offset = from; + thumb_length = skip; + } + if (!strcmp(data,"icc_camera_profile")) { + profile_offset = from; + profile_length = skip; + } + if (!strcmp(data,"ShootObj_back_type")) { + fscanf (ifp, "%d", &i); + if ((unsigned) i < sizeof mod / sizeof (*mod)) + strcpy (model, mod[i]); + } + if (!strcmp(data,"icc_camera_to_tone_matrix")) { + for (i=0; i < 9; i++) + romm_cam[0][i] = int_to_float(get4()); + romm_coeff (romm_cam); + } + if (!strcmp(data,"CaptProf_color_matrix")) { + for (i=0; i < 9; i++) + fscanf (ifp, "%f", &romm_cam[0][i]); + romm_coeff (romm_cam); + } + if (!strcmp(data,"CaptProf_number_of_planes")) + fscanf (ifp, "%d", &planes); + if (!strcmp(data,"CaptProf_raw_data_rotation")) + fscanf (ifp, "%d", &flip); + if (!strcmp(data,"CaptProf_mosaic_pattern")) + FORC4 { + fscanf (ifp, "%d", &i); + if (i == 1) frot = c ^ (c >> 1); + } + if (!strcmp(data,"ImgProf_rotation_angle")) { + fscanf (ifp, "%d", &i); + flip = i - flip; + } + if (!strcmp(data,"NeutObj_neutrals") && !cam_mul[0]) { + FORC4 fscanf (ifp, "%d", neut+c); + FORC3 cam_mul[c] = (float) neut[0] / neut[c+1]; + } + parse_mos (from); + fseek (ifp, skip+from, SEEK_SET); + } + if (planes) + filters = (planes == 1) * 0x01010101 * + (uchar) "\x94\x61\x16\x49"[(flip/90 + frot) & 3]; +} + +void CLASS linear_table (unsigned len) +{ + int i; + if (len > 0x1000) len = 0x1000; + read_shorts (curve, len); + for (i=len; i < 0x1000; i++) + curve[i] = curve[i-1]; + maximum = curve[0xfff]; +} + +void CLASS parse_kodak_ifd (int base) +{ + unsigned entries, tag, type, len, save; + int i, c, wbi=-2, wbtemp=6500; + float mul[3]={1,1,1}, num; + static const int wbtag[]={ 0xfa25,0xfa28,0xfa27,0xfa29,-1,-1,0xfa2a }; + + entries = get2(); + if (entries > 1024) return; + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + if (tag == 1020) wbi = getint(type); + if (tag == 1021 && len == 72) { /* WB set in software */ + fseek (ifp, 40, SEEK_CUR); + FORC3 cam_mul[c] = 2048.0 / get2(); + wbi = -2; + } + if (tag == 2118) wbtemp = getint(type); + if (tag == 2130 + wbi) + FORC3 mul[c] = getreal(type); + if (tag == 2140 + wbi && wbi >= 0) + FORC3 { + for (num=i=0; i < 4; i++) + num += getreal(type) * pow (wbtemp/100.0, i); + cam_mul[c] = 2048 / (num * mul[c]); + } + if (tag == 2317) linear_table (len); + if (tag == 6020) iso_speed = getint(type); + if (tag == 0xfa0d) wbi = fgetc(ifp); + if ((unsigned) wbi < 7 && tag == wbtag[wbi]) + FORC3 cam_mul[c] = get4(); + fseek (ifp, save, SEEK_SET); + } +} + +void CLASS parse_minolta (int base); + +int CLASS parse_tiff_ifd (int base) +{ + unsigned entries, tag, type, len, plen=16, save; + int ifd, use_cm=0, cfa, i, j, c, ima_len=0; + char software[64], *cbuf, *cp; + uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256]; + double dblack, cc[4][4], cm[4][3], cam_xyz[4][3], num; + double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 }; + unsigned sony_curve[] = { 0,0,0,0,0,4095 }; + unsigned *buf, sony_offset=0, sony_length=0, sony_key=0; + struct jhead jh; + FILE *sfp; + + if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0]) + return 1; + ifd = tiff_nifds++; + for (j=0; j < 4; j++) + for (i=0; i < 4; i++) + cc[j][i] = i == j; + entries = get2(); + if (entries > 512) return 1; + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + switch (tag) { + case 17: case 18: + if (type == 3 && len == 1) + cam_mul[(tag-17)*2] = get2() / 256.0; + break; + case 23: + if (type == 3) iso_speed = get2(); + break; + case 36: case 37: case 38: + cam_mul[tag-0x24] = get2(); + break; + case 39: + if (len < 50 || cam_mul[0]) break; + fseek (ifp, 12, SEEK_CUR); + FORC3 cam_mul[c] = get2(); + break; + case 46: + if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break; + thumb_offset = ftell(ifp) - 2; + thumb_length = len; + break; + case 2: case 256: /* ImageWidth */ + tiff_ifd[ifd].width = getint(type); + break; + case 3: case 257: /* ImageHeight */ + tiff_ifd[ifd].height = getint(type); + break; + case 258: /* BitsPerSample */ + tiff_ifd[ifd].samples = len & 7; + tiff_ifd[ifd].bps = get2(); + break; + case 259: /* Compression */ + tiff_ifd[ifd].comp = get2(); + break; + case 262: /* PhotometricInterpretation */ + tiff_ifd[ifd].phint = get2(); + break; + case 270: /* ImageDescription */ + fread (desc, 512, 1, ifp); + break; + case 271: /* Make */ + fgets (make, 64, ifp); + break; + case 272: /* Model */ + fgets (model, 64, ifp); + break; + case 280: /* Panasonic RW2 offset */ + if (type != 4) break; + load_raw = &CLASS panasonic_load_raw; + load_flags = 0x2008; + case 273: /* StripOffset */ + case 513: + tiff_ifd[ifd].offset = get4()+base; + if (!tiff_ifd[ifd].bps) { + fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET); + if (ljpeg_start (&jh, 1)) { + tiff_ifd[ifd].comp = 6; + tiff_ifd[ifd].width = jh.wide << (jh.clrs == 2); + tiff_ifd[ifd].height = jh.high; + tiff_ifd[ifd].bps = jh.bits; + tiff_ifd[ifd].samples = jh.clrs; + } + } + break; + case 274: /* Orientation */ + tiff_ifd[ifd].flip = "50132467"[get2() & 7]-'0'; + break; + case 277: /* SamplesPerPixel */ + tiff_ifd[ifd].samples = getint(type) & 7; + break; + case 279: /* StripByteCounts */ + case 514: + tiff_ifd[ifd].bytes = get4(); + break; + case 305: case 11: /* Software */ + fgets (software, 64, ifp); + if (!strncmp(software,"Adobe",5) || + !strncmp(software,"dcraw",5) || + !strncmp(software,"UFRaw",5) || + !strncmp(software,"Bibble",6) || + !strncmp(software,"Nikon Scan",10) || + !strcmp (software,"Digital Photo Professional")) + is_raw = 0; + break; + case 306: /* DateTime */ + get_timestamp(0); + break; + case 315: /* Artist */ + fread (artist, 64, 1, ifp); + break; + case 322: /* TileWidth */ + tile_width = getint(type); + break; + case 323: /* TileLength */ + tile_length = getint(type); + break; + case 324: /* TileOffsets */ + tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4(); + if (len == 4) { + load_raw = &CLASS sinar_4shot_load_raw; + is_raw = 5; + } + break; + case 330: /* SubIFDs */ + if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) { + load_raw = &CLASS sony_arw_load_raw; + data_offset = get4()+base; + ifd++; break; + } + while (len--) { + i = ftell(ifp); + fseek (ifp, get4()+base, SEEK_SET); + if (parse_tiff_ifd (base)) break; + fseek (ifp, i+4, SEEK_SET); + } + break; + case 400: + strcpy (make, "Sarnoff"); + maximum = 0xfff; + break; + case 28688: + FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff; + for (i=0; i < 5; i++) + for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++) + curve[j] = curve[j-1] + (1 << i); + break; + case 29184: sony_offset = get4(); break; + case 29185: sony_length = get4(); break; + case 29217: sony_key = get4(); break; + case 29264: + parse_minolta (ftell(ifp)); + raw_width = 0; + break; + case 29443: + FORC4 cam_mul[c ^ (c < 2)] = get2(); + break; + case 29459: + FORC4 cam_mul[c ^ (c >> 1)] = get2(); + break; + case 33405: /* Model2 */ + fgets (model2, 64, ifp); + break; + case 33422: /* CFAPattern */ + case 64777: /* Kodak P-series */ + if ((plen=len) > 16) plen = 16; + fread (cfa_pat, 1, plen, ifp); + for (colors=cfa=i=0; i < plen; i++) { + colors += !(cfa & (1 << cfa_pat[i])); + cfa |= 1 << cfa_pat[i]; + } + if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3); /* CMY */ + if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4); /* GMCY */ + goto guess_cfa_pc; + case 33424: + case 65024: + fseek (ifp, get4()+base, SEEK_SET); + parse_kodak_ifd (base); + break; + case 33434: /* ExposureTime */ + shutter = getreal(type); + break; + case 33437: /* FNumber */ + aperture = getreal(type); + break; + case 34306: /* Leaf white balance */ + FORC4 cam_mul[c ^ 1] = 4096.0 / get2(); + break; + case 34307: /* Leaf CatchLight color matrix */ + fread (software, 1, 7, ifp); + if (strncmp(software,"MATRIX",6)) break; + colors = 4; + for (raw_color = i=0; i < 3; i++) { + FORC4 fscanf (ifp, "%f", &rgb_cam[i][c^1]); + if (!use_camera_wb) continue; + num = 0; + FORC4 num += rgb_cam[i][c]; + FORC4 rgb_cam[i][c] /= num; + } + break; + case 34310: /* Leaf metadata */ + parse_mos (ftell(ifp)); + case 34303: + strcpy (make, "Leaf"); + break; + case 34665: /* EXIF tag */ + fseek (ifp, get4()+base, SEEK_SET); + parse_exif (base); + break; + case 34853: /* GPSInfo tag */ + fseek (ifp, get4()+base, SEEK_SET); + parse_gps (base); + break; + case 34675: /* InterColorProfile */ + case 50831: /* AsShotICCProfile */ + profile_offset = ftell(ifp); + profile_length = len; + break; + case 37122: /* CompressedBitsPerPixel */ + kodak_cbpp = get4(); + break; + case 37386: /* FocalLength */ + focal_len = getreal(type); + break; + case 37393: /* ImageNumber */ + shot_order = getint(type); + break; + case 37400: /* old Kodak KDC tag */ + for (raw_color = i=0; i < 3; i++) { + getreal(type); + FORC3 rgb_cam[i][c] = getreal(type); + } + break; + case 46275: /* Imacon tags */ + strcpy (make, "Imacon"); + data_offset = ftell(ifp); + ima_len = len; + break; + case 46279: + if (!ima_len) break; + fseek (ifp, 78, SEEK_CUR); + raw_width = get4(); + raw_height = get4(); + left_margin = get4() & 7; + width = raw_width - left_margin - (get4() & 7); + top_margin = get4() & 7; + height = raw_height - top_margin - (get4() & 7); + if (raw_width == 7262) { + height = 5444; + width = 7244; + left_margin = 7; + } + fseek (ifp, 52, SEEK_CUR); + FORC3 cam_mul[c] = getreal(11); + fseek (ifp, 114, SEEK_CUR); + flip = (get2() >> 7) * 90; + if (width * height * 6 == ima_len) { + if (flip % 180 == 90) SWAP(width,height); + filters = flip = 0; + } + sprintf (model, "Ixpress %d-Mp", height*width/1000000); + load_raw = &CLASS imacon_full_load_raw; + if (filters) { + if (left_margin & 1) filters = 0x61616161; + load_raw = &CLASS unpacked_load_raw; + } + maximum = 0xffff; + break; + case 50454: /* Sinar tag */ + case 50455: + if (!(cbuf = (char *) malloc(len))) break; + fread (cbuf, 1, len, ifp); + for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n')) + if (!strncmp (++cp,"Neutral ",8)) + sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2); + free (cbuf); + break; + case 50458: + if (!make[0]) strcpy (make, "Hasselblad"); + break; + case 50459: /* Hasselblad tag */ + i = order; + j = ftell(ifp); + c = tiff_nifds; + order = get2(); + fseek (ifp, j+(get2(),get4()), SEEK_SET); + parse_tiff_ifd (j); + maximum = 0xffff; + tiff_nifds = c; + order = i; + break; + case 50706: /* DNGVersion */ + FORC4 dng_version = (dng_version << 8) + fgetc(ifp); + if (!make[0]) strcpy (make, "DNG"); + is_raw = 1; + break; + case 50710: /* CFAPlaneColor */ + if (len > 4) len = 4; + colors = len; + fread (cfa_pc, 1, colors, ifp); +guess_cfa_pc: + FORCC tab[cfa_pc[c]] = c; + cdesc[c] = 0; + for (i=16; i--; ) + filters = filters << 2 | tab[cfa_pat[i % plen]]; + break; + case 50711: /* CFALayout */ + if (get2() == 2) { + fuji_width = 1; + filters = 0x49494949; + } + break; + case 291: + case 50712: /* LinearizationTable */ + linear_table (len); + break; + case 50714: /* BlackLevel */ + case 50715: /* BlackLevelDeltaH */ + case 50716: /* BlackLevelDeltaV */ + for (dblack=i=0; i < len; i++) + dblack += getreal(type); + black += dblack/len + 0.5; + break; + case 50717: /* WhiteLevel */ + maximum = getint(type); + break; + case 50718: /* DefaultScale */ + pixel_aspect = getreal(type); + pixel_aspect /= getreal(type); + break; + case 50721: /* ColorMatrix1 */ + case 50722: /* ColorMatrix2 */ + FORCC for (j=0; j < 3; j++) + cm[c][j] = getreal(type); + use_cm = 1; + break; + case 50723: /* CameraCalibration1 */ + case 50724: /* CameraCalibration2 */ + for (i=0; i < colors; i++) + FORCC cc[i][c] = getreal(type); + break; + case 50727: /* AnalogBalance */ + FORCC ab[c] = getreal(type); + break; + case 50728: /* AsShotNeutral */ + FORCC asn[c] = getreal(type); + break; + case 50729: /* AsShotWhiteXY */ + xyz[0] = getreal(type); + xyz[1] = getreal(type); + xyz[2] = 1 - xyz[0] - xyz[1]; + FORC3 xyz[c] /= d65_white[c]; + break; + case 50740: /* DNGPrivateData */ + if (dng_version) break; + parse_minolta (j = get4()+base); + fseek (ifp, j, SEEK_SET); + parse_tiff_ifd (base); + break; + case 50752: + read_shorts (cr2_slice, 3); + break; + case 50829: /* ActiveArea */ + top_margin = getint(type); + left_margin = getint(type); + height = getint(type) - top_margin; + width = getint(type) - left_margin; + break; + case 64772: /* Kodak P-series */ + if (len < 13) break; + fseek (ifp, 16, SEEK_CUR); + data_offset = get4(); + fseek (ifp, 28, SEEK_CUR); + data_offset += get4(); + load_raw = &CLASS packed_load_raw; + break; + case 65026: + if (type == 2) fgets (model2, 64, ifp); + } + fseek (ifp, save, SEEK_SET); + } + if (sony_length && (buf = (unsigned *) malloc(sony_length))) { + fseek (ifp, sony_offset, SEEK_SET); + fread (buf, sony_length, 1, ifp); + sony_decrypt (buf, sony_length/4, 1, sony_key); + sfp = ifp; + if ((ifp = tmpfile())) { + fwrite (buf, sony_length, 1, ifp); + fseek (ifp, 0, SEEK_SET); + parse_tiff_ifd (-sony_offset); + fclose (ifp); + } + ifp = sfp; + free (buf); + } + for (i=0; i < colors; i++) + FORCC cc[i][c] *= ab[i]; + if (use_cm) { + FORCC for (i=0; i < 3; i++) + for (cam_xyz[c][i]=j=0; j < colors; j++) + cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i]; + cam_xyz_coeff (cam_xyz); + } + if (asn[0]) { + cam_mul[3] = 0; + FORCC cam_mul[c] = 1 / asn[c]; + } + if (!use_cm) + FORCC pre_mul[c] /= cc[c][c]; + return 0; +} + +void CLASS parse_tiff (int base) +{ + int doff, max_samp=0, raw=-1, thm=-1, i; + struct jhead jh; + + fseek (ifp, base, SEEK_SET); + order = get2(); + if (order != 0x4949 && order != 0x4d4d) return; + get2(); + memset (tiff_ifd, 0, sizeof tiff_ifd); + tiff_nifds = 0; + while ((doff = get4())) { + fseek (ifp, doff+base, SEEK_SET); + if (parse_tiff_ifd (base)) break; + } + thumb_misc = 16; + if (thumb_offset) { + fseek (ifp, thumb_offset, SEEK_SET); + if (ljpeg_start (&jh, 1)) { + thumb_misc = jh.bits; + thumb_width = jh.wide; + thumb_height = jh.high; + } + } + for (i=0; i < tiff_nifds; i++) { + if (max_samp < tiff_ifd[i].samples) + max_samp = tiff_ifd[i].samples; + if (max_samp > 3) max_samp = 3; + if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) && + (tiff_ifd[i].width | tiff_ifd[i].height) < 0x10000 && + tiff_ifd[i].width*tiff_ifd[i].height > raw_width*raw_height) { + raw_width = tiff_ifd[i].width; + raw_height = tiff_ifd[i].height; + tiff_bps = tiff_ifd[i].bps; + tiff_compress = tiff_ifd[i].comp; + data_offset = tiff_ifd[i].offset; + tiff_flip = tiff_ifd[i].flip; + tiff_samples = tiff_ifd[i].samples; + raw = i; + } + } + fuji_width *= (raw_width+1)/2; + if (tiff_ifd[0].flip) tiff_flip = tiff_ifd[0].flip; + if (raw >= 0 && !load_raw) + switch (tiff_compress) { + case 0: case 1: + switch (tiff_bps) { + case 8: load_raw = &CLASS eight_bit_load_raw; break; + case 12: load_raw = &CLASS packed_load_raw; + if (tiff_ifd[raw].phint == 2) + load_flags = 6; + if (strncmp(make,"PENTAX",6)) break; + case 14: + case 16: load_raw = &CLASS unpacked_load_raw; break; + } + if (tiff_ifd[raw].bytes*5 == raw_width*raw_height*8) { + tiff_bps = 12; + maximum = 0xffff; + load_raw = &CLASS packed_load_raw; + load_flags = 273; + } + break; + case 6: case 7: case 99: + load_raw = &CLASS lossless_jpeg_load_raw; break; + case 262: + load_raw = &CLASS kodak_262_load_raw; break; + case 32767: + if (tiff_ifd[raw].bytes == raw_width*raw_height) { + tiff_bps = 12; + load_raw = &CLASS sony_arw2_load_raw; break; + } + if (tiff_ifd[raw].bytes*8 != raw_width*raw_height*tiff_bps) { + raw_height += 8; + load_raw = &CLASS sony_arw_load_raw; break; + } + load_flags = 79; + case 32769: + load_flags++; + case 32773: + load_raw = &CLASS packed_load_raw; break; + case 34713: + load_raw = &CLASS nikon_compressed_load_raw; break; + case 65535: + load_raw = &CLASS pentax_load_raw; break; + case 65000: + switch (tiff_ifd[raw].phint) { + case 2: load_raw = &CLASS kodak_rgb_load_raw; filters = 0; break; + case 6: load_raw = &CLASS kodak_ycbcr_load_raw; filters = 0; break; + case 32803: load_raw = &CLASS kodak_65000_load_raw; + } + case 32867: break; + default: is_raw = 0; + } + if (!dng_version) + if ( (tiff_samples == 3 && tiff_ifd[raw].bytes && + tiff_bps != 14 && tiff_bps != 2048) + || (tiff_bps == 8 && !strstr(make,"KODAK") && !strstr(make,"Kodak") && + !strstr(model2,"DEBUG RAW"))) + is_raw = 0; + for (i=0; i < tiff_nifds; i++) + if (i != raw && tiff_ifd[i].samples == max_samp && + tiff_ifd[i].width * tiff_ifd[i].height / SQR(tiff_ifd[i].bps+1) > + thumb_width * thumb_height / SQR(thumb_misc+1)) { + thumb_width = tiff_ifd[i].width; + thumb_height = tiff_ifd[i].height; + thumb_offset = tiff_ifd[i].offset; + thumb_length = tiff_ifd[i].bytes; + thumb_misc = tiff_ifd[i].bps; + thm = i; + } + if (thm >= 0) { + thumb_misc |= tiff_ifd[thm].samples << 5; + switch (tiff_ifd[thm].comp) { + case 0: + write_thumb = &CLASS layer_thumb; + break; + case 1: + if (tiff_ifd[thm].bps > 8) + thumb_load_raw = &CLASS kodak_thumb_load_raw; + else + write_thumb = &CLASS ppm_thumb; + break; + case 65000: + thumb_load_raw = tiff_ifd[thm].phint == 6 ? + &CLASS kodak_ycbcr_load_raw : &CLASS kodak_rgb_load_raw; + } + } +} + +void CLASS parse_minolta (int base) +{ + int save, tag, len, offset, high=0, wide=0, i, c; + short sorder=order; + + fseek (ifp, base, SEEK_SET); + if (fgetc(ifp) || fgetc(ifp)-'M' || fgetc(ifp)-'R') return; + order = fgetc(ifp) * 0x101; + offset = base + get4() + 8; + while ((save=ftell(ifp)) < offset) { + for (tag=i=0; i < 4; i++) + tag = tag << 8 | fgetc(ifp); + len = get4(); + switch (tag) { + case 0x505244: /* PRD */ + fseek (ifp, 8, SEEK_CUR); + high = get2(); + wide = get2(); + break; + case 0x574247: /* WBG */ + get4(); + i = strcmp(model,"DiMAGE A200") ? 0:3; + FORC4 cam_mul[c ^ (c >> 1) ^ i] = get2(); + break; + case 0x545457: /* TTW */ + parse_tiff (ftell(ifp)); + data_offset = offset; + } + fseek (ifp, save+len+8, SEEK_SET); + } + raw_height = high; + raw_width = wide; + order = sorder; +} + +/* + Many cameras have a "debug mode" that writes JPEG and raw + at the same time. The raw file has no header, so try to + to open the matching JPEG file and read its metadata. + */ +void CLASS parse_external_jpeg() +{ + const char *file, *ext; + char *jname, *jfile, *jext; + FILE *save=ifp; + + ext = strrchr (ifname, '.'); + file = strrchr (ifname, '/'); + if (!file) file = strrchr (ifname, '\\'); + if (!file) file = ifname-1; + file++; + if (!ext || strlen(ext) != 4 || ext-file != 8) return; + jname = (char *) malloc (strlen(ifname) + 1); + merror (jname, "parse_external_jpeg()"); + strcpy (jname, ifname); + jfile = file - ifname + jname; + jext = ext - ifname + jname; + if (strcasecmp (ext, ".jpg")) { + strcpy (jext, isupper(ext[1]) ? ".JPG":".jpg"); + if (isdigit(*file)) { + memcpy (jfile, file+4, 4); + memcpy (jfile+4, file, 4); + } + } else + while (isdigit(*--jext)) { + if (*jext != '9') { + (*jext)++; + break; + } + *jext = '0'; + } + if (strcmp (jname, ifname)) { + if ((ifp = fopen (jname, "rb"))) { + if (verbose) + fprintf (stderr,_("Reading metadata from %s ...\n"), jname); + parse_tiff (12); + thumb_offset = 0; + is_raw = 1; + fclose (ifp); + } + } + if (!timestamp) + fprintf (stderr,_("Failed to read metadata from %s\n"), jname); + free (jname); + ifp = save; +} + +/* + CIFF block 0x1030 contains an 8x8 white sample. + Load this into white[][] for use in scale_colors(). + */ +void CLASS ciff_block_1030() +{ + static const ushort key[] = { 0x410, 0x45f3 }; + int i, bpp, row, col, vbits=0; + unsigned long bitbuf=0; + + if ((get2(),get4()) != 0x80008 || !get4()) return; + bpp = get2(); + if (bpp != 10 && bpp != 12) return; + for (i=row=0; row < 8; row++) + for (col=0; col < 8; col++) { + if (vbits < bpp) { + bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]); + vbits += 16; + } + white[row][col] = + bitbuf << (LONG_BIT - vbits) >> (LONG_BIT - bpp); + vbits -= bpp; + } +} + +/* + Parse a CIFF file, better known as Canon CRW format. + */ +void CLASS parse_ciff (int offset, int length) +{ + int tboff, nrecs, c, type, len, save, wbi=-1; + ushort key[] = { 0x410, 0x45f3 }; + + fseek (ifp, offset+length-4, SEEK_SET); + tboff = get4() + offset; + fseek (ifp, tboff, SEEK_SET); + nrecs = get2(); + if (nrecs > 100) return; + while (nrecs--) { + type = get2(); + len = get4(); + save = ftell(ifp) + 4; + fseek (ifp, offset+get4(), SEEK_SET); + if ((((type >> 8) + 8) | 8) == 0x38) + parse_ciff (ftell(ifp), len); /* Parse a sub-table */ + + if (type == 0x0810) + fread (artist, 64, 1, ifp); + if (type == 0x080a) { + fread (make, 64, 1, ifp); + fseek (ifp, strlen(make) - 63, SEEK_CUR); + fread (model, 64, 1, ifp); + } + if (type == 0x1810) { + fseek (ifp, 12, SEEK_CUR); + flip = get4(); + } + if (type == 0x1835) /* Get the decoder table */ + tiff_compress = get4(); + if (type == 0x2007) { + thumb_offset = ftell(ifp); + thumb_length = len; + } + if (type == 0x1818) { + shutter = pow (2, -int_to_float((get4(),get4()))); + aperture = pow (2, int_to_float(get4())/2); + } + if (type == 0x102a) { + iso_speed = pow (2, (get4(),get2())/32.0 - 4) * 50; + aperture = pow (2, (get2(),(short)get2())/64.0); + shutter = pow (2,-((short)get2())/32.0); + wbi = (get2(),get2()); + if (wbi > 17) wbi = 0; + fseek (ifp, 32, SEEK_CUR); + if (shutter > 1e6) shutter = get2()/10.0; + } + if (type == 0x102c) { + if (get2() > 512) { /* Pro90, G1 */ + fseek (ifp, 118, SEEK_CUR); + FORC4 cam_mul[c ^ 2] = get2(); + } else { /* G2, S30, S40 */ + fseek (ifp, 98, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2(); + } + } + if (type == 0x0032) { + if (len == 768) { /* EOS D30 */ + fseek (ifp, 72, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1)] = 1024.0 / get2(); + if (!wbi) cam_mul[0] = -1; /* use my auto white balance */ + } else if (!cam_mul[0]) { + if (get2() == key[0]) /* Pro1, G6, S60, S70 */ + c = (strstr(model,"Pro1") ? + "012346000000000000":"01345:000000006008")[wbi]-'0'+ 2; + else { /* G3, G5, S45, S50 */ + c = "023457000000006000"[wbi]-'0'; + key[0] = key[1] = 0; + } + fseek (ifp, 78 + c*8, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2() ^ key[c & 1]; + if (!wbi) cam_mul[0] = -1; + } + } + if (type == 0x10a9) { /* D60, 10D, 300D, and clones */ + if (len > 66) wbi = "0134567028"[wbi]-'0'; + fseek (ifp, 2 + wbi*8, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1)] = get2(); + } + if (type == 0x1030 && (0x18040 >> wbi & 1)) + ciff_block_1030(); /* all that don't have 0x10a9 */ + if (type == 0x1031) { + raw_width = (get2(),get2()); + raw_height = get2(); + } + if (type == 0x5029) { + focal_len = len >> 16; + if ((len & 0xffff) == 2) focal_len /= 32; + } + if (type == 0x5813) flash_used = int_to_float(len); + if (type == 0x5814) canon_ev = int_to_float(len); + if (type == 0x5817) shot_order = len; + if (type == 0x5834) unique_id = len; + if (type == 0x580e) timestamp = len; + if (type == 0x180e) timestamp = get4(); +#ifdef LOCALTIME + if ((type | 0x4000) == 0x580e) + timestamp = mktime (gmtime (×tamp)); +#endif + fseek (ifp, save, SEEK_SET); + } +} + +void CLASS parse_rollei() +{ + char line[128], *val; + struct tm t; + + fseek (ifp, 0, SEEK_SET); + memset (&t, 0, sizeof t); + do { + fgets (line, 128, ifp); + if ((val = strchr(line,'='))) + *val++ = 0; + else + val = line + strlen(line); + if (!strcmp(line,"DAT")) + sscanf (val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year); + if (!strcmp(line,"TIM")) + sscanf (val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec); + if (!strcmp(line,"HDR")) + thumb_offset = atoi(val); + if (!strcmp(line,"X ")) + raw_width = atoi(val); + if (!strcmp(line,"Y ")) + raw_height = atoi(val); + if (!strcmp(line,"TX ")) + thumb_width = atoi(val); + if (!strcmp(line,"TY ")) + thumb_height = atoi(val); + } while (strncmp(line,"EOHD",4)); + data_offset = thumb_offset + thumb_width * thumb_height * 2; + t.tm_year -= 1900; + t.tm_mon -= 1; + if (mktime(&t) > 0) + timestamp = mktime(&t); + strcpy (make, "Rollei"); + strcpy (model,"d530flex"); + write_thumb = &CLASS rollei_thumb; +} + +void CLASS parse_sinar_ia() +{ + int entries, off; + char str[8], *cp; + + order = 0x4949; + fseek (ifp, 4, SEEK_SET); + entries = get4(); + fseek (ifp, get4(), SEEK_SET); + while (entries--) { + off = get4(); get4(); + fread (str, 8, 1, ifp); + if (!strcmp(str,"META")) meta_offset = off; + if (!strcmp(str,"THUMB")) thumb_offset = off; + if (!strcmp(str,"RAW0")) data_offset = off; + } + fseek (ifp, meta_offset+20, SEEK_SET); + fread (make, 64, 1, ifp); + make[63] = 0; + if ((cp = strchr(make,' '))) { + strcpy (model, cp+1); + *cp = 0; + } + raw_width = get2(); + raw_height = get2(); + load_raw = &CLASS unpacked_load_raw; + thumb_width = (get4(),get2()); + thumb_height = get2(); + write_thumb = &CLASS ppm_thumb; + maximum = 0x3fff; +} + +void CLASS parse_phase_one (int base) +{ + unsigned entries, tag, type, len, data, save, i, c; + float romm_cam[3][3]; + char *cp; + + memset (&ph1, 0, sizeof ph1); + fseek (ifp, base, SEEK_SET); + order = get4() & 0xffff; + if (get4() >> 8 != 0x526177) return; /* "Raw" */ + fseek (ifp, get4()+base, SEEK_SET); + entries = get4(); + get4(); + while (entries--) { + tag = get4(); + type = get4(); + len = get4(); + data = get4(); + save = ftell(ifp); + fseek (ifp, base+data, SEEK_SET); + switch (tag) { + case 0x100: flip = "0653"[data & 3]-'0'; break; + case 0x106: + for (i=0; i < 9; i++) + romm_cam[0][i] = getreal(11); + romm_coeff (romm_cam); + break; + case 0x107: + FORC3 cam_mul[c] = getreal(11); + break; + case 0x108: raw_width = data; break; + case 0x109: raw_height = data; break; + case 0x10a: left_margin = data; break; + case 0x10b: top_margin = data; break; + case 0x10c: width = data; break; + case 0x10d: height = data; break; + case 0x10e: ph1.format = data; break; + case 0x10f: data_offset = data+base; break; + case 0x110: meta_offset = data+base; + meta_length = len; break; + case 0x112: ph1.key_off = save - 4; break; + case 0x210: ph1.tag_210 = int_to_float(data); break; + case 0x21a: ph1.tag_21a = data; break; + case 0x21c: strip_offset = data+base; break; + case 0x21d: ph1.black = data; break; + case 0x222: ph1.split_col = data - left_margin; break; + case 0x223: ph1.black_off = data+base; break; + case 0x301: + model[63] = 0; + fread (model, 1, 63, ifp); + if ((cp = strstr(model," camera"))) *cp = 0; + } + fseek (ifp, save, SEEK_SET); + } + load_raw = ph1.format < 3 ? + &CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c; + maximum = 0xffff; + strcpy (make, "Phase One"); + if (model[0]) return; + switch (raw_height) { + case 2060: strcpy (model,"LightPhase"); break; + case 2682: strcpy (model,"H 10"); break; + case 4128: strcpy (model,"H 20"); break; + case 5488: strcpy (model,"H 25"); break; + } +} + +void CLASS parse_fuji (int offset) +{ + unsigned entries, tag, len, save, c; + + fseek (ifp, offset, SEEK_SET); + entries = get4(); + if (entries > 255) return; + while (entries--) { + tag = get2(); + len = get2(); + save = ftell(ifp); + if (tag == 0x100) { + raw_height = get2(); + raw_width = get2(); + } else if (tag == 0x121) { + height = get2(); + if ((width = get2()) == 4284) width += 3; + } else if (tag == 0x130) { + fuji_layout = fgetc(ifp) >> 7; + load_raw = fgetc(ifp) & 8 ? + &CLASS unpacked_load_raw : &CLASS fuji_load_raw; + } + if (tag == 0x2ff0) + FORC4 cam_mul[c ^ 1] = get2(); + fseek (ifp, save+len, SEEK_SET); + } + height <<= fuji_layout; + width >>= fuji_layout; +} + +int CLASS parse_jpeg (int offset) +{ + int len, save, hlen, mark; + + fseek (ifp, offset, SEEK_SET); + if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0; + + while (fgetc(ifp) == 0xff && (mark = fgetc(ifp)) != 0xda) { + order = 0x4d4d; + len = get2() - 2; + save = ftell(ifp); + if (mark == 0xc0 || mark == 0xc3) { + fgetc(ifp); + raw_height = get2(); + raw_width = get2(); + } + order = get2(); + hlen = get4(); + if (get4() == 0x48454150) /* "HEAP" */ + parse_ciff (save+hlen, len-hlen); + parse_tiff (save+6); + fseek (ifp, save+len, SEEK_SET); + } + return 1; +} + +void CLASS parse_riff() +{ + unsigned i, size, end; + char tag[4], date[64], month[64]; + static const char mon[12][4] = + { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" }; + struct tm t; + + order = 0x4949; + fread (tag, 4, 1, ifp); + size = get4(); + end = ftell(ifp) + size; + if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) { + get4(); + while (ftell(ifp)+7 < end) + parse_riff(); + } else if (!memcmp(tag,"nctg",4)) { + while (ftell(ifp)+7 < end) { + i = get2(); + size = get2(); + if ((i+1) >> 1 == 10 && size == 20) + get_timestamp(0); + else fseek (ifp, size, SEEK_CUR); + } + } else if (!memcmp(tag,"IDIT",4) && size < 64) { + fread (date, 64, 1, ifp); + date[size] = 0; + memset (&t, 0, sizeof t); + if (sscanf (date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday, + &t.tm_hour, &t.tm_min, &t.tm_sec, &t.tm_year) == 6) { + for (i=0; i < 12 && strcasecmp(mon[i],month); i++); + t.tm_mon = i; + t.tm_year -= 1900; + if (mktime(&t) > 0) + timestamp = mktime(&t); + } + } else + fseek (ifp, size, SEEK_CUR); +} + +void CLASS parse_smal (int offset, int fsize) +{ + int ver; + + fseek (ifp, offset+2, SEEK_SET); + order = 0x4949; + ver = fgetc(ifp); + if (ver == 6) + fseek (ifp, 5, SEEK_CUR); + if (get4() != fsize) return; + if (ver > 6) data_offset = get4(); + raw_height = height = get2(); + raw_width = width = get2(); + strcpy (make, "SMaL"); + sprintf (model, "v%d %dx%d", ver, width, height); + if (ver == 6) load_raw = &CLASS smal_v6_load_raw; + if (ver == 9) load_raw = &CLASS smal_v9_load_raw; +} + +void CLASS parse_cine() +{ + unsigned off_head, off_setup, off_image, i; + + order = 0x4949; + fseek (ifp, 4, SEEK_SET); + is_raw = get2() == 2; + fseek (ifp, 14, SEEK_CUR); + is_raw *= get4(); + off_head = get4(); + off_setup = get4(); + off_image = get4(); + timestamp = get4(); + if ((i = get4())) timestamp = i; + fseek (ifp, off_head+4, SEEK_SET); + raw_width = get4(); + raw_height = get4(); + switch (get2(),get2()) { + case 8: load_raw = &CLASS eight_bit_load_raw; break; + case 16: load_raw = &CLASS unpacked_load_raw; + } + fseek (ifp, off_setup+792, SEEK_SET); + strcpy (make, "CINE"); + sprintf (model, "%d", get4()); + fseek (ifp, 12, SEEK_CUR); + switch ((i=get4()) & 0xffffff) { + case 3: filters = 0x94949494; break; + case 4: filters = 0x49494949; break; + default: is_raw = 0; + } + fseek (ifp, 72, SEEK_CUR); + switch ((get4()+3600) % 360) { + case 270: flip = 4; break; + case 180: flip = 1; break; + case 90: flip = 7; break; + case 0: flip = 2; + } + cam_mul[0] = getreal(11); + cam_mul[2] = getreal(11); + maximum = ~(-1 << get4()); + fseek (ifp, 668, SEEK_CUR); + shutter = get4()/1000000000.0; + fseek (ifp, off_image, SEEK_SET); + if (shot_select < is_raw) + fseek (ifp, shot_select*8, SEEK_CUR); + data_offset = (INT64) get4() + 8; + data_offset += (INT64) get4() << 32; +} + +char * CLASS foveon_gets (int offset, char *str, int len) +{ + int i; + fseek (ifp, offset, SEEK_SET); + for (i=0; i < len-1; i++) + if ((str[i] = get2()) == 0) break; + str[i] = 0; + return str; +} + +void CLASS parse_foveon() +{ + int entries, img=0, off, len, tag, save, i, wide, high, pent, poff[256][2]; + char name[64], value[64]; + + order = 0x4949; /* Little-endian */ + fseek (ifp, 36, SEEK_SET); + flip = get4(); + fseek (ifp, -4, SEEK_END); + fseek (ifp, get4(), SEEK_SET); + if (get4() != 0x64434553) return; /* SECd */ + entries = (get4(),get4()); + while (entries--) { + off = get4(); + len = get4(); + tag = get4(); + save = ftell(ifp); + fseek (ifp, off, SEEK_SET); + if (get4() != (0x20434553 | (tag << 24))) return; + switch (tag) { + case 0x47414d49: /* IMAG */ + case 0x32414d49: /* IMA2 */ + fseek (ifp, 12, SEEK_CUR); + wide = get4(); + high = get4(); + if (wide > raw_width && high > raw_height) { + raw_width = wide; + raw_height = high; + data_offset = off+24; + } + fseek (ifp, off+28, SEEK_SET); + if (fgetc(ifp) == 0xff && fgetc(ifp) == 0xd8 + && thumb_length < len-28) { + thumb_offset = off+28; + thumb_length = len-28; + write_thumb = &CLASS jpeg_thumb; + } + if (++img == 2 && !thumb_length) { + thumb_offset = off+24; + thumb_width = wide; + thumb_height = high; + write_thumb = &CLASS foveon_thumb; + } + break; + case 0x464d4143: /* CAMF */ + meta_offset = off+24; + meta_length = len-28; + if (meta_length > 0x20000) + meta_length = 0x20000; + break; + case 0x504f5250: /* PROP */ + pent = (get4(),get4()); + fseek (ifp, 12, SEEK_CUR); + off += pent*8 + 24; + if ((unsigned) pent > 256) pent=256; + for (i=0; i < pent*2; i++) + poff[0][i] = off + get4()*2; + for (i=0; i < pent; i++) { + foveon_gets (poff[i][0], name, 64); + foveon_gets (poff[i][1], value, 64); + if (!strcmp (name, "ISO")) + iso_speed = atoi(value); + if (!strcmp (name, "CAMMANUF")) + strcpy (make, value); + if (!strcmp (name, "CAMMODEL")) + strcpy (model, value); + if (!strcmp (name, "WB_DESC")) + strcpy (model2, value); + if (!strcmp (name, "TIME")) + timestamp = atoi(value); + if (!strcmp (name, "EXPTIME")) + shutter = atoi(value) / 1000000.0; + if (!strcmp (name, "APERTURE")) + aperture = atof(value); + if (!strcmp (name, "FLENGTH")) + focal_len = atof(value); + } +#ifdef LOCALTIME + timestamp = mktime (gmtime (×tamp)); +#endif + } + fseek (ifp, save, SEEK_SET); + } + is_foveon = 1; +} + +/* + All matrices are from Adobe DNG Converter unless otherwise noted. + */ +void CLASS adobe_coeff (const char *make, const char *model) +{ + static const struct { + const char *prefix; + short black, maximum, trans[12]; + } table[] = { + { "AGFAPHOTO DC-833m", 0, 0, /* DJC */ + { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } }, + { "Apple QuickTake", 0, 0, /* DJC */ + { 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } }, + { "Canon EOS D2000", 0, 0, + { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } }, + { "Canon EOS D6000", 0, 0, + { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } }, + { "Canon EOS D30", 0, 0, + { 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } }, + { "Canon EOS D60", 0, 0xfa0, + { 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } }, + { "Canon EOS 5D Mark II", 0, 0x3cf0, + { 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } }, + { "Canon EOS 5D", 0, 0xe6c, + { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } }, + { "Canon EOS 7D", 0, 0x3510, + { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } }, + { "Canon EOS 10D", 0, 0xfa0, + { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } }, + { "Canon EOS 20Da", 0, 0, + { 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } }, + { "Canon EOS 20D", 0, 0xfff, + { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } }, + { "Canon EOS 30D", 0, 0, + { 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } }, + { "Canon EOS 40D", 0, 0x3f60, + { 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } }, + { "Canon EOS 50D", 0, 0x3d93, + { 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } }, + { "Canon EOS 300D", 0, 0xfa0, + { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } }, + { "Canon EOS 350D", 0, 0xfff, + { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } }, + { "Canon EOS 400D", 0, 0xe8e, + { 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } }, + { "Canon EOS 450D", 0, 0x390d, + { 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } }, + { "Canon EOS 500D", 0, 0x3479, + { 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } }, + { "Canon EOS 1000D", 0, 0xe43, + { 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } }, + { "Canon EOS-1Ds Mark III", 0, 0x3bb0, + { 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } }, + { "Canon EOS-1Ds Mark II", 0, 0xe80, + { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } }, + { "Canon EOS-1D Mark IV", 0, 0x3bb0, + { 6014,-220,-795,-4109,12014,2361,-561,1824,5787 } }, + { "Canon EOS-1D Mark III", 0, 0x3bb0, + { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } }, + { "Canon EOS-1D Mark II N", 0, 0xe80, + { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } }, + { "Canon EOS-1D Mark II", 0, 0xe80, + { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } }, + { "Canon EOS-1DS", 0, 0xe20, + { 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } }, + { "Canon EOS-1D", 0, 0xe20, + { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } }, + { "Canon EOS", 0, 0, + { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } }, + { "Canon PowerShot A530", 0, 0, + { 0 } }, /* don't want the A5 matrix */ + { "Canon PowerShot A50", 0, 0, + { -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } }, + { "Canon PowerShot A5", 0, 0, + { -4801,9475,1952,2926,1611,4094,-5259,10164,5947,-1554,10883,547 } }, + { "Canon PowerShot G10", 0, 0, + { 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } }, + { "Canon PowerShot G11", 0, 0, + { 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } }, + { "Canon PowerShot G1", 0, 0, + { -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } }, + { "Canon PowerShot G2", 0, 0, + { 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } }, + { "Canon PowerShot G3", 0, 0, + { 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } }, + { "Canon PowerShot G5", 0, 0, + { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } }, + { "Canon PowerShot G6", 0, 0, + { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } }, + { "Canon PowerShot G9", 0, 0, + { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } }, + { "Canon PowerShot Pro1", 0, 0, + { 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } }, + { "Canon PowerShot Pro70", 34, 0, + { -4155,9818,1529,3939,-25,4522,-5521,9870,6610,-2238,10873,1342 } }, + { "Canon PowerShot Pro90", 0, 0, + { -4963,9896,2235,4642,-987,4294,-5162,10011,5859,-1770,11230,577 } }, + { "Canon PowerShot S30", 0, 0, + { 10566,-3652,-1129,-6552,14662,2006,-2197,2581,7670 } }, + { "Canon PowerShot S40", 0, 0, + { 8510,-2487,-940,-6869,14231,2900,-2318,2829,9013 } }, + { "Canon PowerShot S45", 0, 0, + { 8163,-2333,-955,-6682,14174,2751,-2077,2597,8041 } }, + { "Canon PowerShot S50", 0, 0, + { 8882,-2571,-863,-6348,14234,2288,-1516,2172,6569 } }, + { "Canon PowerShot S60", 0, 0, + { 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } }, + { "Canon PowerShot S70", 0, 0, + { 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } }, + { "Canon PowerShot S90", 0, 0, + { 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } }, + { "Canon PowerShot A470", 0, 0, /* DJC */ + { 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } }, + { "Canon PowerShot A610", 0, 0, /* DJC */ + { 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } }, + { "Canon PowerShot A620", 0, 0, /* DJC */ + { 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } }, + { "Canon PowerShot A630", 0, 0, /* DJC */ + { 14201,-5308,-1757,-6087,14472,1617,-2191,3105,5348 } }, + { "Canon PowerShot A640", 0, 0, /* DJC */ + { 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } }, + { "Canon PowerShot A650", 0, 0, /* DJC */ + { 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } }, + { "Canon PowerShot A720", 0, 0, /* DJC */ + { 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } }, + { "Canon PowerShot S3 IS", 0, 0, /* DJC */ + { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } }, + { "Canon PowerShot SX1 IS", 0, 0, + { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } }, + { "Canon PowerShot SX110 IS", 0, 0, /* DJC */ + { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } }, + { "CASIO EX-S20", 0, 0, /* DJC */ + { 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } }, + { "CASIO EX-Z750", 0, 0, /* DJC */ + { 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } }, + { "CINE 650", 0, 0, + { 3390,480,-500,-800,3610,340,-550,2336,1192 } }, + { "CINE 660", 0, 0, + { 3390,480,-500,-800,3610,340,-550,2336,1192 } }, + { "CINE", 0, 0, + { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } }, + { "Contax N Digital", 0, 0xf1e, + { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } }, + { "EPSON R-D1", 0, 0, + { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } }, + { "FUJIFILM FinePix E550", 0, 0, + { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } }, + { "FUJIFILM FinePix E900", 0, 0, + { 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } }, + { "FUJIFILM FinePix F8", 0, 0, + { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } }, + { "FUJIFILM FinePix F7", 0, 0, + { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, + { "FUJIFILM FinePix S100FS", 514, 0, + { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } }, + { "FUJIFILM FinePix S20Pro", 0, 0, + { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, + { "FUJIFILM FinePix S2Pro", 128, 0, + { 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } }, + { "FUJIFILM FinePix S3Pro", 0, 0, + { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } }, + { "FUJIFILM FinePix S5Pro", 0, 0, + { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } }, + { "FUJIFILM FinePix S5000", 0, 0, + { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } }, + { "FUJIFILM FinePix S5100", 0, 0x3e00, + { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } }, + { "FUJIFILM FinePix S5500", 0, 0x3e00, + { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } }, + { "FUJIFILM FinePix S5200", 0, 0, + { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } }, + { "FUJIFILM FinePix S5600", 0, 0, + { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } }, + { "FUJIFILM FinePix S6", 0, 0, + { 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } }, + { "FUJIFILM FinePix S7000", 0, 0, + { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } }, + { "FUJIFILM FinePix S9000", 0, 0, + { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } }, + { "FUJIFILM FinePix S9500", 0, 0, + { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } }, + { "FUJIFILM FinePix S9100", 0, 0, + { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } }, + { "FUJIFILM FinePix S9600", 0, 0, + { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } }, + { "FUJIFILM IS-1", 0, 0, + { 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } }, + { "FUJIFILM IS Pro", 0, 0, + { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } }, + { "Imacon Ixpress", 0, 0, /* DJC */ + { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } }, + { "KODAK NC2000", 0, 0, + { 13891,-6055,-803,-465,9919,642,2121,82,1291 } }, + { "Kodak DCS315C", 8, 0, + { 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } }, + { "Kodak DCS330C", 8, 0, + { 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } }, + { "KODAK DCS420", 0, 0, + { 10868,-1852,-644,-1537,11083,484,2343,628,2216 } }, + { "KODAK DCS460", 0, 0, + { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } }, + { "KODAK EOSDCS1", 0, 0, + { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } }, + { "KODAK EOSDCS3B", 0, 0, + { 9898,-2700,-940,-2478,12219,206,1985,634,1031 } }, + { "Kodak DCS520C", 180, 0, + { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } }, + { "Kodak DCS560C", 188, 0, + { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } }, + { "Kodak DCS620C", 180, 0, + { 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } }, + { "Kodak DCS620X", 185, 0, + { 13095,-6231,154,12221,-21,-2137,895,4602,2258 } }, + { "Kodak DCS660C", 214, 0, + { 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } }, + { "Kodak DCS720X", 0, 0, + { 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } }, + { "Kodak DCS760C", 0, 0, + { 16623,-6309,-1411,-4344,13923,323,2285,274,2926 } }, + { "Kodak DCS Pro SLR", 0, 0, + { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } }, + { "Kodak DCS Pro 14nx", 0, 0, + { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } }, + { "Kodak DCS Pro 14", 0, 0, + { 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 } }, + { "Kodak ProBack645", 0, 0, + { 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } }, + { "Kodak ProBack", 0, 0, + { 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } }, + { "KODAK P712", 0, 0, + { 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } }, + { "KODAK P850", 0, 0xf7c, + { 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } }, + { "KODAK P880", 0, 0xfff, + { 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } }, + { "KODAK EasyShare Z980", 0, 0, + { 11313,-3559,-1101,-3893,11891,2257,-1214,2398,4908 } }, + { "KODAK EASYSHARE Z1015", 0, 0xef1, + { 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } }, + { "Leaf CMost", 0, 0, + { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } }, + { "Leaf Valeo 6", 0, 0, + { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } }, + { "Leaf Aptus 54S", 0, 0, + { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } }, + { "Leaf Aptus 65", 0, 0, + { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } }, + { "Leaf Aptus 75", 0, 0, + { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } }, + { "Leaf", 0, 0, + { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } }, + { "Mamiya ZD", 0, 0, + { 7645,2579,-1363,-8689,16717,2015,-3712,5941,5961 } }, + { "Micron 2010", 110, 0, /* DJC */ + { 16695,-3761,-2151,155,9682,163,3433,951,4904 } }, + { "Minolta DiMAGE 5", 0, 0xf7d, + { 8983,-2942,-963,-6556,14476,2237,-2426,2887,8014 } }, + { "Minolta DiMAGE 7Hi", 0, 0xf7d, + { 11368,-3894,-1242,-6521,14358,2339,-2475,3056,7285 } }, + { "Minolta DiMAGE 7", 0, 0xf7d, + { 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } }, + { "Minolta DiMAGE A1", 0, 0xf8b, + { 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } }, + { "MINOLTA DiMAGE A200", 0, 0, + { 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } }, + { "Minolta DiMAGE A2", 0, 0xf8f, + { 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } }, + { "Minolta DiMAGE Z2", 0, 0, /* DJC */ + { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } }, + { "MINOLTA DYNAX 5", 0, 0xffb, + { 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } }, + { "MINOLTA DYNAX 7", 0, 0xffb, + { 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } }, + { "MOTOROLA PIXL", 0, 0, /* DJC */ + { 8898,-989,-1033,-3292,11619,1674,-661,3178,5216 } }, + { "NIKON D100", 0, 0, + { 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } }, + { "NIKON D1H", 0, 0, + { 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 } }, + { "NIKON D1X", 0, 0, + { 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } }, + { "NIKON D1", 0, 0, /* multiplied by 2.218750, 1.0, 1.148438 */ + { 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } }, + { "NIKON D200", 0, 0xfbc, + { 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } }, + { "NIKON D2H", 0, 0, + { 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } }, + { "NIKON D2X", 0, 0, + { 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } }, + { "NIKON D3000", 0, 0, + { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } }, + { "NIKON D300", 0, 0, + { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } }, + { "NIKON D3X", 0, 0, + { 7171,-1986,-648,-8085,15555,2718,-2170,2512,7457 } }, + { "NIKON D3S", 0, 0, + { 8828,-2406,-694,-4874,12603,2541,-660,1509,7587 } }, + { "NIKON D3", 0, 0, + { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } }, + { "NIKON D40X", 0, 0, + { 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } }, + { "NIKON D40", 0, 0, + { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } }, + { "NIKON D5000", 0, 0xf00, + { 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } }, + { "NIKON D50", 0, 0, + { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, + { "NIKON D60", 0, 0, + { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } }, + { "NIKON D700", 0, 0, + { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } }, + { "NIKON D70", 0, 0, + { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, + { "NIKON D80", 0, 0, + { 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } }, + { "NIKON D90", 0, 0xf00, + { 7309,-1403,-519,-8474,16008,2622,-2434,2826,8064 } }, + { "NIKON E950", 0, 0x3dd, /* DJC */ + { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } }, + { "NIKON E995", 0, 0, /* copied from E5000 */ + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { "NIKON E2100", 0, 0, /* copied from Z2, new white balance */ + { 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711} }, + { "NIKON E2500", 0, 0, + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { "NIKON E4300", 0, 0, /* copied from Minolta DiMAGE Z2 */ + { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } }, + { "NIKON E4500", 0, 0, + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { "NIKON E5000", 0, 0, + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { "NIKON E5400", 0, 0, + { 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 } }, + { "NIKON E5700", 0, 0, + { -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 } }, + { "NIKON E8400", 0, 0, + { 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } }, + { "NIKON E8700", 0, 0, + { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, + { "NIKON E8800", 0, 0, + { 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } }, + { "NIKON COOLPIX P6000", 0, 0, + { 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } }, + { "OLYMPUS C5050", 0, 0, + { 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } }, + { "OLYMPUS C5060", 0, 0, + { 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } }, + { "OLYMPUS C7070", 0, 0, + { 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } }, + { "OLYMPUS C70", 0, 0, + { 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } }, + { "OLYMPUS C80", 0, 0, + { 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } }, + { "OLYMPUS E-10", 0, 0xffc0, + { 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } }, + { "OLYMPUS E-1", 0, 0xfff0, + { 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } }, + { "OLYMPUS E-20", 0, 0xffc0, + { 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } }, + { "OLYMPUS E-300", 0, 0, + { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } }, + { "OLYMPUS E-330", 0, 0, + { 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } }, + { "OLYMPUS E-30", 0, 0xfbc, + { 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } }, + { "OLYMPUS E-3", 0, 0xf99, + { 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } }, + { "OLYMPUS E-400", 0, 0xfff0, + { 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } }, + { "OLYMPUS E-410", 0, 0xf6a, + { 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } }, + { "OLYMPUS E-420", 0, 0xfd7, + { 8746,-2425,-1095,-7594,15612,2073,-1780,2309,7416 } }, + { "OLYMPUS E-450", 0, 0xfd2, + { 8745,-2425,-1095,-7594,15613,2073,-1780,2309,7416 } }, + { "OLYMPUS E-500", 0, 0xfff0, + { 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } }, + { "OLYMPUS E-510", 0, 0xf6a, + { 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } }, + { "OLYMPUS E-520", 0, 0xfd2, + { 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } }, + { "OLYMPUS E-620", 0, 0xfb9, + { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } }, + { "OLYMPUS E-P1", 0, 0xffd, + { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } }, + { "OLYMPUS SP350", 0, 0, + { 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } }, + { "OLYMPUS SP3", 0, 0, + { 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } }, + { "OLYMPUS SP500UZ", 0, 0xfff, + { 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } }, + { "OLYMPUS SP510UZ", 0, 0xffe, + { 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } }, + { "OLYMPUS SP550UZ", 0, 0xffe, + { 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } }, + { "OLYMPUS SP560UZ", 0, 0xff9, + { 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } }, + { "OLYMPUS SP570UZ", 0, 0, + { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } }, + { "PENTAX *ist DL2", 0, 0, + { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, + { "PENTAX *ist DL", 0, 0, + { 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } }, + { "PENTAX *ist DS2", 0, 0, + { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, + { "PENTAX *ist DS", 0, 0, + { 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } }, + { "PENTAX *ist D", 0, 0, + { 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } }, + { "PENTAX K10D", 0, 0, + { 9566,-2863,-803,-7170,15172,2112,-818,803,9705 } }, + { "PENTAX K1", 0, 0, + { 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } }, + { "PENTAX K20D", 0, 0, + { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } }, + { "PENTAX K200D", 0, 0, + { 9186,-2678,-907,-8693,16517,2260,-1129,1094,8524 } }, + { "PENTAX K2000", 0, 0, + { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } }, + { "PENTAX K-m", 0, 0, + { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } }, + { "PENTAX K-x", 0, 0, + { 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } }, + { "PENTAX K-7", 0, 0, + { 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } }, + { "Panasonic DMC-FZ8", 0, 0xf7f0, + { 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } }, + { "Panasonic DMC-FZ18", 0, 0, + { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } }, + { "Panasonic DMC-FZ28", 15, 0xfff, + { 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } }, + { "Panasonic DMC-FZ30", 0, 0xf94c, + { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } }, + { "Panasonic DMC-FZ35", 147, 0xfff, + { 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } }, + { "Panasonic DMC-FZ50", 0, 0xfff0, /* aka "LEICA V-LUX1" */ + { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } }, + { "Panasonic DMC-L10", 15, 0xf96, + { 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } }, + { "Panasonic DMC-L1", 0, 0xf7fc, /* aka "LEICA DIGILUX 3" */ + { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } }, + { "Panasonic DMC-LC1", 0, 0, /* aka "LEICA DIGILUX 2" */ + { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } }, + { "Panasonic DMC-LX1", 0, 0xf7f0, /* aka "LEICA D-LUX2" */ + { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } }, + { "Panasonic DMC-LX2", 0, 0, /* aka "LEICA D-LUX3" */ + { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } }, + { "Panasonic DMC-LX3", 15, 0xfff, /* aka "LEICA D-LUX4" */ + { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } }, + { "Panasonic DMC-FX150", 15, 0xfff, + { 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } }, + { "Panasonic DMC-G1", 15, 0xfff, + { 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } }, + { "Panasonic DMC-GF1", 15, 0xf92, + { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, + { "Panasonic DMC-GH1", 15, 0xf92, + { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } }, + { "Phase One H 20", 0, 0, /* DJC */ + { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } }, + { "Phase One P 2", 0, 0, + { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } }, + { "Phase One P 30", 0, 0, + { 4516,-245,-37,-7020,14976,2173,-3206,4671,7087 } }, + { "Phase One P 45", 0, 0, + { 5053,-24,-117,-5684,14076,1702,-2619,4492,5849 } }, + { "Phase One P65", 0, 0, /* DJC */ + { 8522,1268,-1916,-7706,16350,1358,-2397,4344,4923 } }, + { "SAMSUNG GX-1", 0, 0, + { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, + { "SAMSUNG S85", 0, 0, /* DJC */ + { 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } }, + { "Sinar", 0, 0, /* DJC */ + { 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } }, + { "SONY DSC-F828", 491, 0, + { 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } }, + { "SONY DSC-R1", 512, 0, + { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } }, + { "SONY DSC-V3", 0, 0, + { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } }, + { "SONY DSLR-A100", 0, 0xfeb, + { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } }, + { "SONY DSLR-A200", 0, 0, + { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } }, + { "SONY DSLR-A230", 0, 0, /* copied */ + { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } }, + { "SONY DSLR-A300", 0, 0, + { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } }, + { "SONY DSLR-A330", 0, 0, + { 9847,-3091,-929,-8485,16346,2225,-714,595,7103 } }, + { "SONY DSLR-A350", 0, 0xffc, + { 6038,-1484,-578,-9146,16746,2513,-875,746,7217 } }, + { "SONY DSLR-A380", 0, 0, + { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } }, + { "SONY DSLR-A5", 254, 0x1ffe, + { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } }, + { "SONY DSLR-A700", 254, 0x1ffe, + { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } }, + { "SONY DSLR-A850", 256, 0x1ffe, + { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } }, + { "SONY DSLR-A900", 254, 0x1ffe, + { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } } + }; + double cam_xyz[4][3]; + char name[130]; + int i, j; + + sprintf (name, "%s %s", make, model); + for (i=0; i < sizeof table / sizeof *table; i++) + if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) { + if (table[i].black) black = (ushort) table[i].black; + if (table[i].maximum) maximum = (ushort) table[i].maximum; + if (table[i].trans[0]) { + for (j=0; j < 12; j++) + cam_xyz[0][j] = table[i].trans[j] / 10000.0; + cam_xyz_coeff (cam_xyz); + } + break; + } +} + +void CLASS simple_coeff (int index) +{ + static const float table[][12] = { + /* index 0 -- all Foveon cameras */ + { 1.4032,-0.2231,-0.1016,-0.5263,1.4816,0.017,-0.0112,0.0183,0.9113 }, + /* index 1 -- Kodak DC20 and DC25 */ + { 2.25,0.75,-1.75,-0.25,-0.25,0.75,0.75,-0.25,-0.25,-1.75,0.75,2.25 }, + /* index 2 -- Logitech Fotoman Pixtura */ + { 1.893,-0.418,-0.476,-0.495,1.773,-0.278,-1.017,-0.655,2.672 }, + /* index 3 -- Nikon E880, E900, and E990 */ + { -1.936280, 1.800443, -1.448486, 2.584324, + 1.405365, -0.524955, -0.289090, 0.408680, + -1.204965, 1.082304, 2.941367, -1.818705 } + }; + int i, c; + + for (raw_color = i=0; i < 3; i++) + FORCC rgb_cam[i][c] = table[index][i*colors+c]; +} + +short CLASS guess_byte_order (int words) +{ + uchar test[4][2]; + int t=2, msb; + double diff, sum[2] = {0,0}; + + fread (test[0], 2, 2, ifp); + for (words-=2; words--; ) { + fread (test[t], 2, 1, ifp); + for (msb=0; msb < 2; msb++) { + diff = (test[t^2][msb] << 8 | test[t^2][!msb]) + - (test[t ][msb] << 8 | test[t ][!msb]); + sum[msb] += diff*diff; + } + t = (t+1) & 3; + } + return sum[0] < sum[1] ? 0x4d4d : 0x4949; +} + +float CLASS find_green (int bps, int bite, int off0, int off1) +{ + UINT64 bitbuf=0; + int vbits, col, i, c; + ushort img[2][2064]; + double sum[]={0,0}; + + FORC(2) { + fseek (ifp, c ? off1:off0, SEEK_SET); + for (vbits=col=0; col < width; col++) { + for (vbits -= bps; vbits < 0; vbits += bite) { + bitbuf <<= bite; + for (i=0; i < bite; i+=8) + bitbuf |= (unsigned) (fgetc(ifp) << i); + } + img[c][col] = bitbuf << (64-bps-vbits) >> (64-bps); + } + } + FORC(width-1) { + sum[ c & 1] += ABS(img[0][c]-img[1][c+1]); + sum[~c & 1] += ABS(img[1][c]-img[0][c+1]); + } + return 100 * log(sum[0]/sum[1]); +} + +/* + Identify which camera created this file, and set global variables + accordingly. + */ +void CLASS identify() +{ + char head[32], *cp; + int hlen, fsize, i, c, is_canon; + struct jhead jh; + static const struct { + int fsize; + char make[12], model[19], withjpeg; + } table[] = { + { 62464, "Kodak", "DC20" ,0 }, + { 124928, "Kodak", "DC20" ,0 }, + { 1652736, "Kodak", "DCS200" ,0 }, + { 4159302, "Kodak", "C330" ,0 }, + { 4162462, "Kodak", "C330" ,0 }, + { 460800, "Kodak", "C603v" ,0 }, + { 614400, "Kodak", "C603v" ,0 }, + { 6163328, "Kodak", "C603" ,0 }, + { 6166488, "Kodak", "C603" ,0 }, + { 9116448, "Kodak", "C603y" ,0 }, + { 311696, "ST Micro", "STV680 VGA" ,0 }, /* SPYz */ + { 787456, "Creative", "PC-CAM 600" ,0 }, + { 1138688, "Minolta", "RD175" ,0 }, + { 3840000, "Foculus", "531C" ,0 }, + { 786432, "AVT", "F-080C" ,0 }, + { 1447680, "AVT", "F-145C" ,0 }, + { 1920000, "AVT", "F-201C" ,0 }, + { 5067304, "AVT", "F-510C" ,0 }, + { 10134608, "AVT", "F-510C" ,0 }, + { 16157136, "AVT", "F-810C" ,0 }, + { 1409024, "Sony", "XCD-SX910CR" ,0 }, + { 2818048, "Sony", "XCD-SX910CR" ,0 }, + { 3884928, "Micron", "2010" ,0 }, + { 6624000, "Pixelink", "A782" ,0 }, + { 13248000, "Pixelink", "A782" ,0 }, + { 6291456, "RoverShot","3320AF" ,0 }, + { 6553440, "Canon", "PowerShot A460" ,0 }, + { 6653280, "Canon", "PowerShot A530" ,0 }, + { 6573120, "Canon", "PowerShot A610" ,0 }, + { 9219600, "Canon", "PowerShot A620" ,0 }, + { 9243240, "Canon", "PowerShot A470" ,0 }, + { 10341600, "Canon", "PowerShot A720" ,0 }, + { 10383120, "Canon", "PowerShot A630" ,0 }, + { 12945240, "Canon", "PowerShot A640" ,0 }, + { 15636240, "Canon", "PowerShot A650" ,0 }, + { 5298000, "Canon", "PowerShot SD300" ,0 }, + { 7710960, "Canon", "PowerShot S3 IS" ,0 }, + { 15467760, "Canon", "PowerShot SX110 IS",0 }, + { 5939200, "OLYMPUS", "C770UZ" ,0 }, + { 1581060, "NIKON", "E900" ,1 }, /* or E900s,E910 */ + { 2465792, "NIKON", "E950" ,1 }, /* or E800,E700 */ + { 2940928, "NIKON", "E2100" ,1 }, /* or E2500 */ + { 4771840, "NIKON", "E990" ,1 }, /* or E995, Oly C3030Z */ + { 4775936, "NIKON", "E3700" ,1 }, /* or Optio 33WR */ + { 5869568, "NIKON", "E4300" ,1 }, /* or DiMAGE Z2 */ + { 5865472, "NIKON", "E4500" ,1 }, + { 7438336, "NIKON", "E5000" ,1 }, /* or E5700 */ + { 8998912, "NIKON", "COOLPIX S6" ,1 }, + { 1976352, "CASIO", "QV-2000UX" ,1 }, + { 3217760, "CASIO", "QV-3*00EX" ,1 }, + { 6218368, "CASIO", "QV-5700" ,1 }, + { 6054400, "CASIO", "QV-R41" ,1 }, + { 7530816, "CASIO", "QV-R51" ,1 }, + { 7684000, "CASIO", "QV-4000" ,1 }, + { 2937856, "CASIO", "EX-S20" ,1 }, + { 4948608, "CASIO", "EX-S100" ,1 }, + { 7542528, "CASIO", "EX-Z50" ,1 }, + { 7753344, "CASIO", "EX-Z55" ,1 }, + { 7816704, "CASIO", "EX-Z60" ,1 }, + { 10843712, "CASIO", "EX-Z75" ,1 }, + { 10834368, "CASIO", "EX-Z750" ,1 }, + { 12310144, "CASIO", "EX-Z850" ,1 }, + { 7426656, "CASIO", "EX-P505" ,1 }, + { 9313536, "CASIO", "EX-P600" ,1 }, + { 10979200, "CASIO", "EX-P700" ,1 }, + { 3178560, "PENTAX", "Optio S" ,1 }, + { 4841984, "PENTAX", "Optio S" ,1 }, + { 6114240, "PENTAX", "Optio S4" ,1 }, /* or S4i, CASIO EX-Z4 */ + { 10702848, "PENTAX", "Optio 750Z" ,1 }, + { 15980544, "AGFAPHOTO","DC-833m" ,1 }, + { 16098048, "SAMSUNG", "S85" ,1 }, + { 16215552, "SAMSUNG", "S85" ,1 }, + { 12582980, "Sinar", "" ,0 }, + { 33292868, "Sinar", "" ,0 }, + { 44390468, "Sinar", "" ,0 } }; + static const char *corp[] = + { "Canon", "NIKON", "EPSON", "KODAK", "Kodak", "OLYMPUS", "PENTAX", + "MINOLTA", "Minolta", "Konica", "CASIO", "Sinar", "Phase One", + "SAMSUNG", "Mamiya", "MOTOROLA" }; + + tiff_flip = flip = filters = -1; /* 0 is valid, so -1 is unknown */ + raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0; + maximum = height = width = top_margin = left_margin = 0; + cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0; + iso_speed = shutter = aperture = focal_len = unique_id = 0; + memset (gpsdata, 0, sizeof gpsdata); + memset (white, 0, sizeof white); + thumb_offset = thumb_length = thumb_width = thumb_height = 0; + load_raw = thumb_load_raw = 0; + write_thumb = &CLASS jpeg_thumb; + data_offset = meta_length = tiff_bps = tiff_compress = 0; + kodak_cbpp = zero_after_ff = dng_version = load_flags = 0; + timestamp = shot_order = tiff_samples = black = is_foveon = 0; + mix_green = profile_length = data_error = zero_is_bad = 0; + pixel_aspect = is_raw = raw_color = 1; + tile_width = tile_length = INT_MAX; + for (i=0; i < 4; i++) { + cam_mul[i] = i == 1; + pre_mul[i] = i < 3; + FORC3 cmatrix[c][i] = 0; + FORC3 rgb_cam[c][i] = c == i; + } + colors = 3; + for (i=0; i < 0x4000; i++) curve[i] = i; + + order = get2(); + hlen = get4(); + fseek (ifp, 0, SEEK_SET); + fread (head, 1, 32, ifp); + fseek (ifp, 0, SEEK_END); + fsize = ftell(ifp); + if ((cp = (char *) memmem (head, 32, "MMMM", 4)) || + (cp = (char *) memmem (head, 32, "IIII", 4))) { + parse_phase_one (cp-head); + if (cp-head) parse_tiff(0); + } else if (order == 0x4949 || order == 0x4d4d) { + if (!memcmp (head+6,"HEAPCCDR",8)) { + data_offset = hlen; + parse_ciff (hlen, fsize - hlen); + } else { + parse_tiff(0); + } + } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) && + !memcmp (head+6,"Exif",4)) { + fseek (ifp, 4, SEEK_SET); + data_offset = 4 + get2(); + fseek (ifp, data_offset, SEEK_SET); + if (fgetc(ifp) != 0xff) + parse_tiff(12); + thumb_offset = 0; + } else if (!memcmp (head+25,"ARECOYK",7)) { + strcpy (make, "Contax"); + strcpy (model,"N Digital"); + fseek (ifp, 33, SEEK_SET); + get_timestamp(1); + fseek (ifp, 60, SEEK_SET); + FORC4 cam_mul[c ^ (c >> 1)] = get4(); + } else if (!strcmp (head, "PXN")) { + strcpy (make, "Logitech"); + strcpy (model,"Fotoman Pixtura"); + } else if (!strcmp (head, "qktk")) { + strcpy (make, "Apple"); + strcpy (model,"QuickTake 100"); + } else if (!strcmp (head, "qktn")) { + strcpy (make, "Apple"); + strcpy (model,"QuickTake 150"); + } else if (!memcmp (head,"FUJIFILM",8)) { + fseek (ifp, 84, SEEK_SET); + thumb_offset = get4(); + thumb_length = get4(); + fseek (ifp, 92, SEEK_SET); + parse_fuji (get4()); + if (thumb_offset > 120) { + fseek (ifp, 120, SEEK_SET); + is_raw += (i = get4()) && 1; + if (is_raw == 2 && shot_select) + parse_fuji (i); + } + fseek (ifp, 100, SEEK_SET); + data_offset = get4(); + parse_tiff (thumb_offset+12); + } else if (!memcmp (head,"RIFF",4)) { + fseek (ifp, 0, SEEK_SET); + parse_riff(); + } else if (!memcmp (head,"\0\001\0\001\0@",6)) { + fseek (ifp, 6, SEEK_SET); + fread (make, 1, 8, ifp); + fread (model, 1, 8, ifp); + fread (model2, 1, 16, ifp); + data_offset = get2(); + get2(); + raw_width = get2(); + raw_height = get2(); + load_raw = &CLASS nokia_load_raw; + filters = 0x61616161; + } else if (!memcmp (head,"DSC-Image",9)) + parse_rollei(); + else if (!memcmp (head,"PWAD",4)) + parse_sinar_ia(); + else if (!memcmp (head,"\0MRM",4)) + parse_minolta(0); + else if (!memcmp (head,"FOVb",4)) + parse_foveon(); + else if (!memcmp (head,"CI",2)) + parse_cine(); + else + for (i=0; i < sizeof table / sizeof *table; i++) + if (fsize == table[i].fsize) { + strcpy (make, table[i].make ); + strcpy (model, table[i].model); + if (table[i].withjpeg) + parse_external_jpeg(); + } + if (make[0] == 0) parse_smal (0, fsize); + if (make[0] == 0) parse_jpeg (is_raw = 0); + + for (i=0; i < sizeof corp / sizeof *corp; i++) + if (strstr (make, corp[i])) /* Simplify company names */ + strcpy (make, corp[i]); + if (!strncmp (make,"KODAK",5) && + ((cp = strstr(model," DIGITAL CAMERA")) || + (cp = strstr(model," Digital Camera")) || + (cp = strstr(model,"FILE VERSION")))) + *cp = 0; + cp = make + strlen(make); /* Remove trailing spaces */ + while (*--cp == ' ') *cp = 0; + cp = model + strlen(model); + while (*--cp == ' ') *cp = 0; + i = strlen(make); /* Remove make from model */ + if (!strncasecmp (model, make, i) && model[i++] == ' ') + memmove (model, model+i, 64-i); + if (!strncmp (model,"Digital Camera ",15)) + strcpy (model, model+15); + desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0; + if (!is_raw) goto notraw; + + if (!height) height = raw_height; + if (!width) width = raw_width; + if (fuji_width) { + width = height + fuji_width; + height = width - 1; + pixel_aspect = 1; + } + if (height == 2624 && width == 3936) /* Pentax K10D and Samsung GX10 */ + { height = 2616; width = 3896; } + if (height == 3136 && width == 4864) /* Pentax K20D */ + { height = 3124; width = 4688; } + if (height == 3136 && width == 4736) /* Pentax K-7 */ + { height = 3122; width = 4684; + top_margin = 2; filters = 0x16161616; } + if (height == 3014 && width == 4096) /* Ricoh GX200 */ + width = 4014; + if (dng_version) { + if (filters == UINT_MAX) filters = 0; + if (filters) is_raw = tiff_samples; + else colors = tiff_samples; + if (tiff_compress == 1) + load_raw = &CLASS adobe_dng_load_raw_nc; + if (tiff_compress == 7) + load_raw = &CLASS adobe_dng_load_raw_lj; + goto dng_skip; + } + if ((is_canon = !strcmp(make,"Canon"))) + load_raw = memcmp (head+6,"HEAPCCDR",8) ? + &CLASS lossless_jpeg_load_raw : &CLASS canon_compressed_load_raw; + if (!strcmp(make,"NIKON")) { + if (!load_raw) + load_raw = &CLASS packed_load_raw; + if (model[0] == 'E') + load_flags |= !data_offset << 2 | 2; + } + if (!strcmp(make,"CASIO")) { + load_raw = &CLASS packed_load_raw; + maximum = 0xf7f; + } + +/* Set parameters based on camera name (for non-DNG files). */ + + if (is_foveon) { + if (height*2 < width) pixel_aspect = 0.5; + if (height > width) pixel_aspect = 2; + filters = 0; + load_raw = &CLASS foveon_load_raw; + simple_coeff(0); + } else if (is_canon && tiff_bps == 15) { + switch (width) { + case 3344: width -= 66; + case 3872: width -= 6; + } + filters = 0; + load_raw = &CLASS canon_sraw_load_raw; + } else if (!strcmp(model,"PowerShot 600")) { + height = 613; + width = 854; + raw_width = 896; + pixel_aspect = 607/628.0; + colors = 4; + filters = 0xe1e4e1e4; + load_raw = &CLASS canon_600_load_raw; + } else if (!strcmp(model,"PowerShot A5") || + !strcmp(model,"PowerShot A5 Zoom")) { + height = 773; + width = 960; + raw_width = 992; + pixel_aspect = 256/235.0; + colors = 4; + filters = 0x1e4e1e4e; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A50")) { + height = 968; + width = 1290; + raw_width = 1320; + colors = 4; + filters = 0x1b4e4b1e; + goto canon_a5; + } else if (!strcmp(model,"PowerShot Pro70")) { + height = 1024; + width = 1552; + colors = 4; + filters = 0x1e4b4e1b; + goto canon_a5; + } else if (!strcmp(model,"PowerShot SD300")) { + height = 1752; + width = 2344; + raw_height = 1766; + raw_width = 2400; + top_margin = 12; + left_margin = 12; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A460")) { + height = 1960; + width = 2616; + raw_height = 1968; + raw_width = 2664; + top_margin = 4; + left_margin = 4; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A530")) { + height = 1984; + width = 2620; + raw_height = 1992; + raw_width = 2672; + top_margin = 6; + left_margin = 10; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A610")) { + if (canon_s2is()) strcpy (model+10, "S2 IS"); + height = 1960; + width = 2616; + raw_height = 1968; + raw_width = 2672; + top_margin = 8; + left_margin = 12; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A620")) { + height = 2328; + width = 3112; + raw_height = 2340; + raw_width = 3152; + top_margin = 12; + left_margin = 36; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A470")) { + height = 2328; + width = 3096; + raw_height = 2346; + raw_width = 3152; + top_margin = 6; + left_margin = 12; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A720")) { + height = 2472; + width = 3298; + raw_height = 2480; + raw_width = 3336; + top_margin = 5; + left_margin = 6; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A630")) { + height = 2472; + width = 3288; + raw_height = 2484; + raw_width = 3344; + top_margin = 6; + left_margin = 12; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A640")) { + height = 2760; + width = 3672; + raw_height = 2772; + raw_width = 3736; + top_margin = 6; + left_margin = 12; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A650")) { + height = 3024; + width = 4032; + raw_height = 3048; + raw_width = 4104; + top_margin = 12; + left_margin = 48; + goto canon_a5; + } else if (!strcmp(model,"PowerShot S3 IS")) { + height = 2128; + width = 2840; + raw_height = 2136; + raw_width = 2888; + top_margin = 8; + left_margin = 44; +canon_a5: + tiff_bps = 10; + load_raw = &CLASS packed_load_raw; + load_flags = 40; + if (raw_width > 1600) zero_is_bad = 1; + } else if (!strcmp(model,"PowerShot SX110 IS")) { + height = 2760; + width = 3684; + raw_height = 2772; + raw_width = 3720; + top_margin = 12; + left_margin = 6; + load_raw = &CLASS packed_load_raw; + load_flags = 40; + zero_is_bad = 1; + } else if (!strcmp(model,"PowerShot Pro90 IS")) { + width = 1896; + colors = 4; + filters = 0xb4b4b4b4; + } else if (is_canon && raw_width == 2144) { + height = 1550; + width = 2088; + top_margin = 8; + left_margin = 4; + if (!strcmp(model,"PowerShot G1")) { + colors = 4; + filters = 0xb4b4b4b4; + } + } else if (is_canon && raw_width == 2224) { + height = 1448; + width = 2176; + top_margin = 6; + left_margin = 48; + } else if (is_canon && raw_width == 2376) { + height = 1720; + width = 2312; + top_margin = 6; + left_margin = 12; + } else if (is_canon && raw_width == 2672) { + height = 1960; + width = 2616; + top_margin = 6; + left_margin = 12; + } else if (is_canon && raw_width == 3152) { + height = 2056; + width = 3088; + top_margin = 12; + left_margin = 64; + if (unique_id == 0x80000170) + adobe_coeff ("Canon","EOS 300D"); + } else if (is_canon && raw_width == 3160) { + height = 2328; + width = 3112; + top_margin = 12; + left_margin = 44; + } else if (is_canon && raw_width == 3344) { + height = 2472; + width = 3288; + top_margin = 6; + left_margin = 4; + } else if (!strcmp(model,"EOS D2000C")) { + filters = 0x61616161; + black = curve[200]; + } else if (is_canon && raw_width == 3516) { + top_margin = 14; + left_margin = 42; + if (unique_id == 0x80000189) + adobe_coeff ("Canon","EOS 350D"); + goto canon_cr2; + } else if (is_canon && raw_width == 3596) { + top_margin = 12; + left_margin = 74; + goto canon_cr2; + } else if (is_canon && raw_width == 3744) { + height = 2760; + width = 3684; + top_margin = 16; + left_margin = 8; + } else if (is_canon && raw_width == 3944) { + height = 2602; + width = 3908; + top_margin = 18; + left_margin = 30; + } else if (is_canon && raw_width == 3948) { + top_margin = 18; + left_margin = 42; + height -= 2; + if (unique_id == 0x80000236) + adobe_coeff ("Canon","EOS 400D"); + if (unique_id == 0x80000254) + adobe_coeff ("Canon","EOS 1000D"); + goto canon_cr2; + } else if (is_canon && raw_width == 3984) { + top_margin = 20; + left_margin = 76; + height -= 2; + goto canon_cr2; + } else if (is_canon && raw_width == 4104) { + height = 3024; + width = 4032; + top_margin = 12; + left_margin = 48; + } else if (is_canon && raw_width == 4152) { + top_margin = 12; + left_margin = 192; + goto canon_cr2; + } else if (is_canon && raw_width == 4312) { + top_margin = 18; + left_margin = 22; + height -= 2; + if (unique_id == 0x80000176) + adobe_coeff ("Canon","EOS 450D"); + goto canon_cr2; + } else if (is_canon && raw_width == 4476) { + top_margin = 34; + left_margin = 90; + goto canon_cr2; + } else if (is_canon && raw_width == 4480) { + height = 3326; + width = 4432; + top_margin = 10; + left_margin = 12; + filters = 0x49494949; + } else if (is_canon && raw_width == 1208) { + top_margin = unique_id == 0x80000261 ? 51:26; + left_margin = 62; + raw_width = width *= 4; + if (unique_id == 0x80000252) + adobe_coeff ("Canon","EOS 500D"); + goto canon_cr2; + } else if (is_canon && raw_width == 1280) { + height -= top_margin = 45; + left_margin = 142; + raw_width *= 4; + width = 4916; + } else if (is_canon && raw_width == 1340) { + top_margin = 51; + left_margin = 158; + raw_width = width *= 4; + goto canon_cr2; + } else if (is_canon && raw_width == 1448) { + top_margin = 51; + left_margin = 158; + raw_width = width *= 4; + goto canon_cr2; + } else if (is_canon && raw_width == 5108) { + top_margin = 13; + left_margin = 98; +canon_cr2: + height -= top_margin; + width -= left_margin; + } else if (is_canon && raw_width == 5712) { + height = 3752; + width = 5640; + top_margin = 20; + left_margin = 62; + } else if (!strcmp(model,"D1")) { + cam_mul[0] *= 256/527.0; + cam_mul[2] *= 256/317.0; + } else if (!strcmp(model,"D1X")) { + width -= 4; + pixel_aspect = 0.5; + } else if (!strcmp(model,"D40X") || + !strcmp(model,"D60") || + !strcmp(model,"D80") || + !strcmp(model,"D3000")) { + height -= 3; + width -= 4; + } else if (!strcmp(model,"D3") || + !strcmp(model,"D3S") || + !strcmp(model,"D700")) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"D5000")) { + width -= 42; + } else if (!strncmp(model,"D40",3) || + !strncmp(model,"D50",3) || + !strncmp(model,"D70",3)) { + width--; + } else if (!strcmp(model,"D90")) { + width -= 42; + } else if (!strcmp(model,"D100")) { + if (tiff_compress == 34713 && !nikon_is_compressed()) { + load_raw = &CLASS packed_load_raw; + load_flags |= 1; + raw_width = (width += 3) + 3; + } + } else if (!strcmp(model,"D200")) { + left_margin = 1; + width -= 4; + filters = 0x94949494; + } else if (!strncmp(model,"D2H",3)) { + left_margin = 6; + width -= 14; + } else if (!strncmp(model,"D2X",3)) { + if (width == 3264) width -= 32; + else width -= 8; + } else if (!strncmp(model,"D300",4)) { + width -= 32; + } else if (!strcmp(model,"COOLPIX P6000")) { + load_flags = 24; + filters = 0x94949494; + } else if (fsize == 1581060) { + height = 963; + width = 1287; + raw_width = 1632; + maximum = 0x3f4; + colors = 4; + filters = 0x1e1e1e1e; + simple_coeff(3); + pre_mul[0] = 1.2085; + pre_mul[1] = 1.0943; + pre_mul[3] = 1.1103; + goto e900; + } else if (fsize == 2465792) { + height = 1203; + width = 1616; + raw_width = 2048; + colors = 4; + filters = 0x4b4b4b4b; + adobe_coeff ("NIKON","E950"); +e900: + tiff_bps = 10; + load_raw = &CLASS packed_load_raw; + load_flags = 6; + } else if (fsize == 4771840) { + height = 1540; + width = 2064; + colors = 4; + filters = 0xe1e1e1e1; + load_raw = &CLASS packed_load_raw; + load_flags = 6; + if (!timestamp && nikon_e995()) + strcpy (model, "E995"); + if (strcmp(model,"E995")) { + filters = 0xb4b4b4b4; + simple_coeff(3); + pre_mul[0] = 1.196; + pre_mul[1] = 1.246; + pre_mul[2] = 1.018; + } + } else if (!strcmp(model,"E2100")) { + if (!timestamp && !nikon_e2100()) goto cp_e2500; + height = 1206; + width = 1616; + load_flags = 30; + } else if (!strcmp(model,"E2500")) { +cp_e2500: + strcpy (model, "E2500"); + height = 1204; + width = 1616; + colors = 4; + filters = 0x4b4b4b4b; + } else if (fsize == 4775936) { + height = 1542; + width = 2064; + load_raw = &CLASS packed_load_raw; + load_flags = 30; + if (!timestamp) nikon_3700(); + if (model[0] == 'E' && atoi(model+1) < 3700) + filters = 0x49494949; + if (!strcmp(model,"Optio 33WR")) { + flip = 1; + filters = 0x16161616; + } + if (make[0] == 'O') { + i = find_green (12, 32, 0, fsize/2); + c = find_green (12, 32, 0, 3096); + if (abs(i) < abs(c)) { + SWAP(i,c); + load_flags = 24; + } + if (i < 0) filters = 0x61616161; + } + } else if (fsize == 5869568) { + height = 1710; + width = 2288; + filters = 0x16161616; + if (!timestamp && minolta_z2()) { + strcpy (make, "Minolta"); + strcpy (model,"DiMAGE Z2"); + } + load_raw = &CLASS packed_load_raw; + load_flags = 6 + 24*(make[0] == 'M'); + } else if (!strcmp(model,"E4500")) { + height = 1708; + width = 2288; + colors = 4; + filters = 0xb4b4b4b4; + } else if (fsize == 7438336) { + height = 1924; + width = 2576; + colors = 4; + filters = 0xb4b4b4b4; + } else if (fsize == 8998912) { + height = 2118; + width = 2832; + maximum = 0xf83; + load_raw = &CLASS packed_load_raw; + load_flags = 30; + } else if (!strcmp(make,"FUJIFILM")) { + if (!strcmp(model+7,"S2Pro")) { + strcpy (model+7," S2Pro"); + height = 2144; + width = 2880; + flip = 6; + } else + maximum = 0x3e00; + if (is_raw == 2 && shot_select) + maximum = 0x2f00; + top_margin = (raw_height - height)/2; + left_margin = (raw_width - width )/2; + if (is_raw == 2) + data_offset += (shot_select > 0) * ( fuji_layout ? + (raw_width *= 2) : raw_height*raw_width*2 ); + if (load_raw == &CLASS fuji_load_raw) { + fuji_width = width >> !fuji_layout; + width = (height >> fuji_layout) + fuji_width; + raw_height = height; + height = width - 1; + if (~fuji_width & 1) filters = 0x49494949; + } + } else if (!strcmp(model,"RD175")) { + height = 986; + width = 1534; + data_offset = 513; + filters = 0x61616161; + load_raw = &CLASS minolta_rd175_load_raw; + } else if (!strcmp(model,"KD-400Z")) { + height = 1712; + width = 2312; + raw_width = 2336; + goto konica_400z; + } else if (!strcmp(model,"KD-510Z")) { + goto konica_510z; + } else if (!strcasecmp(make,"MINOLTA")) { + load_raw = &CLASS unpacked_load_raw; + maximum = 0xfff; + if (!strncmp(model,"DiMAGE A",8)) { + if (!strcmp(model,"DiMAGE A200")) + filters = 0x49494949; + tiff_bps = 12; + load_raw = &CLASS packed_load_raw; + } else if (!strncmp(model,"ALPHA",5) || + !strncmp(model,"DYNAX",5) || + !strncmp(model,"MAXXUM",6)) { + sprintf (model+20, "DYNAX %-10s", model+6+(model[0]=='M')); + adobe_coeff (make, model+20); + load_raw = &CLASS packed_load_raw; + } else if (!strncmp(model,"DiMAGE G",8)) { + if (model[8] == '4') { + height = 1716; + width = 2304; + } else if (model[8] == '5') { +konica_510z: + height = 1956; + width = 2607; + raw_width = 2624; + } else if (model[8] == '6') { + height = 2136; + width = 2848; + } + data_offset += 14; + filters = 0x61616161; +konica_400z: + load_raw = &CLASS unpacked_load_raw; + maximum = 0x3df; + order = 0x4d4d; + } + } else if (!strcmp(model,"*ist D")) { + data_error = -1; + } else if (!strcmp(model,"*ist DS")) { + height -= 2; + } else if (!strcmp(model,"K20D")) { + filters = 0x16161616; + } else if (!strcmp(model,"K-x")) { + width = 4309; + filters = 0x16161616; + } else if (!strcmp(model,"Optio S")) { + if (fsize == 3178560) { + height = 1540; + width = 2064; + load_raw = &CLASS eight_bit_load_raw; + cam_mul[0] *= 4; + cam_mul[2] *= 4; + } else { + height = 1544; + width = 2068; + raw_width = 3136; + load_raw = &CLASS packed_load_raw; + maximum = 0xf7c; + } + } else if (fsize == 6114240) { + height = 1737; + width = 2324; + raw_width = 3520; + load_raw = &CLASS packed_load_raw; + maximum = 0xf7a; + } else if (!strcmp(model,"Optio 750Z")) { + height = 2302; + width = 3072; + load_raw = &CLASS packed_load_raw; + load_flags = 30; + } else if (!strcmp(model,"DC-833m")) { + height = 2448; + width = 3264; + order = 0x4949; + filters = 0x61616161; + load_raw = &CLASS unpacked_load_raw; + maximum = 0xfc00; + } else if (!strncmp(model,"S85",3)) { + height = 2448; + width = 3264; + raw_width = fsize/height/2; + order = 0x4d4d; + load_raw = &CLASS unpacked_load_raw; + maximum = 0xffff; + } else if (!strcmp(model,"STV680 VGA")) { + height = 484; + width = 644; + load_raw = &CLASS eight_bit_load_raw; + flip = 2; + filters = 0x16161616; + black = 16; + } else if (!strcmp(model,"N95")) { + height = raw_height - (top_margin = 2); + } else if (!strcmp(model,"531C")) { + height = 1200; + width = 1600; + load_raw = &CLASS unpacked_load_raw; + filters = 0x49494949; + } else if (!strcmp(model,"F-080C")) { + height = 768; + width = 1024; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"F-145C")) { + height = 1040; + width = 1392; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"F-201C")) { + height = 1200; + width = 1600; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"F-510C")) { + height = 1958; + width = 2588; + load_raw = fsize < 7500000 ? + &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw; + maximum = 0xfff0; + } else if (!strcmp(model,"F-810C")) { + height = 2469; + width = 3272; + load_raw = &CLASS unpacked_load_raw; + maximum = 0xfff0; + } else if (!strcmp(model,"XCD-SX910CR")) { + height = 1024; + width = 1375; + raw_width = 1376; + filters = 0x49494949; + maximum = 0x3ff; + load_raw = fsize < 2000000 ? + &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw; + } else if (!strcmp(model,"2010")) { + height = 1207; + width = 1608; + order = 0x4949; + filters = 0x16161616; + data_offset = 3212; + maximum = 0x3ff; + load_raw = &CLASS unpacked_load_raw; + } else if (!strcmp(model,"A782")) { + height = 3000; + width = 2208; + filters = 0x61616161; + load_raw = fsize < 10000000 ? + &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw; + maximum = 0xffc0; + } else if (!strcmp(model,"3320AF")) { + height = 1536; + raw_width = width = 2048; + filters = 0x61616161; + load_raw = &CLASS unpacked_load_raw; + maximum = 0x3ff; + fseek (ifp, 0x300000, SEEK_SET); + if ((order = guess_byte_order(0x10000)) == 0x4d4d) { + height -= (top_margin = 16); + width -= (left_margin = 28); + maximum = 0xf5c0; + strcpy (make, "ISG"); + model[0] = 0; + } + } else if (!strcmp(make,"Hasselblad")) { + if (load_raw == &CLASS lossless_jpeg_load_raw) + load_raw = &CLASS hasselblad_load_raw; + if (raw_width == 7262) { + height = 5444; + width = 7248; + top_margin = 4; + left_margin = 7; + filters = 0x61616161; + } else if (raw_width == 4090) { + strcpy (model, "V96C"); + height -= (top_margin = 6); + width -= (left_margin = 3) + 7; + filters = 0x61616161; + } + } else if (!strcmp(make,"Sinar")) { + if (!memcmp(head,"8BPS",4)) { + fseek (ifp, 14, SEEK_SET); + height = get4(); + width = get4(); + filters = 0x61616161; + data_offset = 68; + } + if (!load_raw) load_raw = &CLASS unpacked_load_raw; + maximum = 0x3fff; + } else if (!strcmp(make,"Leaf")) { + maximum = 0x3fff; + fseek (ifp, data_offset, SEEK_SET); + if (ljpeg_start (&jh, 1) && jh.bits == 15) + maximum = 0x1fff; + if (tiff_samples > 1) filters = 0; + if (tiff_samples > 1 || tile_length < raw_height) + load_raw = &CLASS leaf_hdr_load_raw; + if ((width | height) == 2048) { + if (tiff_samples == 1) { + filters = 1; + strcpy (cdesc, "RBTG"); + strcpy (model, "CatchLight"); + top_margin = 8; left_margin = 18; height = 2032; width = 2016; + } else { + strcpy (model, "DCB2"); + top_margin = 10; left_margin = 16; height = 2028; width = 2022; + } + } else if (width+height == 3144+2060) { + if (!model[0]) strcpy (model, "Cantare"); + if (width > height) { + top_margin = 6; left_margin = 32; height = 2048; width = 3072; + filters = 0x61616161; + } else { + left_margin = 6; top_margin = 32; width = 2048; height = 3072; + filters = 0x16161616; + } + if (!cam_mul[0] || model[0] == 'V') filters = 0; + else is_raw = tiff_samples; + } else if (width == 2116) { + strcpy (model, "Valeo 6"); + height -= 2 * (top_margin = 30); + width -= 2 * (left_margin = 55); + filters = 0x49494949; + } else if (width == 3171) { + strcpy (model, "Valeo 6"); + height -= 2 * (top_margin = 24); + width -= 2 * (left_margin = 24); + filters = 0x16161616; + } + } else if (!strcmp(make,"LEICA") || !strcmp(make,"Panasonic")) { + maximum = 0xfff0; + if ((fsize-data_offset) / (width*8/7) == height) + load_raw = &CLASS panasonic_load_raw; + if (!load_raw) load_raw = &CLASS unpacked_load_raw; + switch (width) { + case 2568: + adobe_coeff ("Panasonic","DMC-LC1"); break; + case 3130: + left_margin = -14; + case 3170: + left_margin += 18; + width = 3096; + if (height > 2326) { + height = 2326; + top_margin = 13; + filters = 0x49494949; + } + zero_is_bad = 1; + adobe_coeff ("Panasonic","DMC-FZ8"); break; + case 3213: + width -= 27; + case 3177: + width -= 10; + filters = 0x49494949; + zero_is_bad = 1; + adobe_coeff ("Panasonic","DMC-L1"); break; + case 3304: + width -= 17; + zero_is_bad = 1; + adobe_coeff ("Panasonic","DMC-FZ30"); break; + case 3330: + width += 43; + left_margin = -6; + maximum = 0xf7f0; + case 3370: + width -= 82; + left_margin += 15; + if (height > 2480) + height = 2480 - (top_margin = 10); + filters = 0x49494949; + zero_is_bad = 1; + adobe_coeff ("Panasonic","DMC-FZ18"); break; + case 3690: + height -= 2; + left_margin = -14; + maximum = 0xf7f0; + case 3770: + width = 3672; + if (--height == 2798 && (height = 2760)) + top_margin = 15; + else filters = 0x49494949; + left_margin += 17; + zero_is_bad = 1; + adobe_coeff ("Panasonic","DMC-FZ50"); break; + case 3710: + width = 3682; + filters = 0x49494949; + adobe_coeff ("Panasonic","DMC-L10"); break; + case 3724: + width -= 14; + if (height == 2450) height -= 2; + case 3836: + width -= 42; +lx3: filters = 0x16161616; + if (make[0] != 'P') + adobe_coeff ("Panasonic","DMC-LX3"); + break; + case 3880: + width -= 22; + left_margin = 6; + zero_is_bad = 1; + adobe_coeff ("Panasonic","DMC-LX1"); break; + case 4060: + width = 3982; + if (height == 2250) goto lx3; + width = 4018; + filters = 0x16161616; + if (!strncmp(model,"DMC-FZ3",7)) { + height -= 2; + adobe_coeff ("Panasonic","DMC-FZ35"); break; + } + filters = 0x49494949; + if (!strcmp(model,"DMC-GH1")) break; + zero_is_bad = 1; + adobe_coeff ("Panasonic","DMC-G1"); break; + case 4172: + case 4396: + width -= 28; + filters = 0x49494949; + adobe_coeff ("Panasonic","DMC-GH1"); break; + case 4290: + height += 38; + left_margin = -14; + filters = 0x49494949; + case 4330: + width = 4248; + if ((height -= 39) == 2400) + top_margin = 15; + left_margin += 17; + adobe_coeff ("Panasonic","DMC-LX2"); break; + case 4508: + height -= 6; + width = 4429; + filters = 0x16161616; + adobe_coeff ("Panasonic","DMC-FX150"); break; + } + } else if (!strcmp(model,"C770UZ")) { + height = 1718; + width = 2304; + filters = 0x16161616; + load_raw = &CLASS packed_load_raw; + load_flags = 30; + } else if (!strcmp(make,"OLYMPUS")) { + height += height & 1; + filters = exif_cfa; + if (width == 4100) width -= 4; + if (load_raw == &CLASS olympus_load_raw) { + tiff_bps = 12; + black >>= 4; + } else if (!strcmp(model,"E-10") || + !strncmp(model,"E-20",4)) { + black <<= 2; + } else if (!strcmp(model,"E-300") || + !strcmp(model,"E-500")) { + width -= 20; + if (load_raw == &CLASS unpacked_load_raw) { + maximum = 0xfc30; + black = 0; + } + } else if (!strcmp(model,"E-330")) { + width -= 30; + if (load_raw == &CLASS unpacked_load_raw) + maximum = 0xf790; + } else if (!strcmp(model,"SP550UZ")) { + thumb_length = fsize - (thumb_offset = 0xa39800); + thumb_height = 480; + thumb_width = 640; + } + } else if (!strcmp(model,"N Digital")) { + height = 2047; + width = 3072; + filters = 0x61616161; + data_offset = 0x1a00; + load_raw = &CLASS packed_load_raw; + } else if (!strcmp(model,"DSC-F828")) { + width = 3288; + left_margin = 5; + data_offset = 862144; + load_raw = &CLASS sony_load_raw; + filters = 0x9c9c9c9c; + colors = 4; + strcpy (cdesc, "RGBE"); + } else if (!strcmp(model,"DSC-V3")) { + width = 3109; + left_margin = 59; + data_offset = 787392; + load_raw = &CLASS sony_load_raw; + } else if (!strcmp(make,"SONY") && raw_width == 3984) { + adobe_coeff ("SONY","DSC-R1"); + width = 3925; + order = 0x4d4d; + } else if (!strcmp(model,"DSLR-A100")) { + height--; + width = ++raw_width; + filters = 0x61616161; + } else if (!strcmp(model,"DSLR-A350")) { + height -= 4; + } else if (!strcmp(model,"PIXL")) { + height -= top_margin = 4; + width -= left_margin = 32; + gamma_curve (0, 7, 1, 255); + } else if (!strcmp(model,"C603v")) { + height = 480; + width = 640; + if (fsize < 614400 || find_green (16, 16, 3840, 5120) < 25) goto c603v; + strcpy (model,"KAI-0340"); + height -= 3; + data_offset = 3840; + order = 0x4949; + load_raw = &CLASS unpacked_load_raw; + } else if (!strcmp(model,"C603y")) { + height = 2134; + width = 2848; +c603v: + filters = 0; + load_raw = &CLASS kodak_yrgb_load_raw; + gamma_curve (0, 3.875, 1, 255); + } else if (!strcmp(model,"C603")) { + raw_height = height = 2152; + raw_width = width = 2864; + goto c603; + } else if (!strcmp(model,"C330")) { + height = 1744; + width = 2336; + raw_height = 1779; + raw_width = 2338; + top_margin = 33; + left_margin = 1; +c603: + order = 0x4949; + if ((data_offset = fsize - raw_height*raw_width)) { + fseek (ifp, 168, SEEK_SET); + read_shorts (curve, 256); + } else gamma_curve (0, 3.875, 1, 255); + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"EASYSHARE Z1015 IS")) { + height = 2742; + width = 3664; + goto ezshare; + } else if (!strcmp(model,"EasyShare Z980")) { + height = 3006; + width = 4016; +ezshare: + data_offset = 0x15000; + load_raw = &CLASS packed_load_raw; + } else if (!strcasecmp(make,"KODAK")) { + if (filters == UINT_MAX) filters = 0x61616161; + if (!strncmp(model,"NC2000",6)) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"EOSDCS3B")) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"EOSDCS1")) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"DCS420")) { + width -= 4; + left_margin = 2; + } else if (!strncmp(model,"DCS460 ",7)) { + model[6] = 0; + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"DCS460A")) { + width -= 4; + left_margin = 2; + colors = 1; + filters = 0; + } else if (!strcmp(model,"DCS660M")) { + black = 214; + colors = 1; + filters = 0; + } else if (!strcmp(model,"DCS760M")) { + colors = 1; + filters = 0; + } + if (!strcmp(model+4,"20X")) + strcpy (cdesc, "MYCY"); + if (strstr(model,"DC25")) { + strcpy (model, "DC25"); + data_offset = 15424; + } + if (!strncmp(model,"DC2",3)) { + height = 242; + if (fsize < 100000) { + raw_width = 256; width = 249; + pixel_aspect = (4.0*height) / (3.0*width); + } else { + raw_width = 512; width = 501; + pixel_aspect = (493.0*height) / (373.0*width); + } + data_offset += raw_width + 1; + colors = 4; + filters = 0x8d8d8d8d; + simple_coeff(1); + pre_mul[1] = 1.179; + pre_mul[2] = 1.209; + pre_mul[3] = 1.036; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"40")) { + strcpy (model, "DC40"); + height = 512; + width = 768; + data_offset = 1152; + load_raw = &CLASS kodak_radc_load_raw; + } else if (strstr(model,"DC50")) { + strcpy (model, "DC50"); + height = 512; + width = 768; + data_offset = 19712; + load_raw = &CLASS kodak_radc_load_raw; + } else if (strstr(model,"DC120")) { + strcpy (model, "DC120"); + height = 976; + width = 848; + pixel_aspect = height/0.75/width; + load_raw = tiff_compress == 7 ? + &CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw; + } else if (!strcmp(model,"DCS200")) { + thumb_height = 128; + thumb_width = 192; + thumb_offset = 6144; + thumb_misc = 360; + write_thumb = &CLASS layer_thumb; + height = 1024; + width = 1536; + data_offset = 79872; + load_raw = &CLASS eight_bit_load_raw; + black = 17; + } + } else if (!strcmp(model,"Fotoman Pixtura")) { + height = 512; + width = 768; + data_offset = 3632; + load_raw = &CLASS kodak_radc_load_raw; + filters = 0x61616161; + simple_coeff(2); + } else if (!strcmp(model,"QuickTake 100")) { + fseek (ifp, 544, SEEK_SET); + height = get2(); + width = get2(); + data_offset = (get4(),get2()) == 30 ? 738:736; + if (height > width) { + SWAP(height,width); + fseek (ifp, data_offset-6, SEEK_SET); + flip = ~get2() & 3 ? 5:6; + } + load_raw = &CLASS quicktake_100_load_raw; + filters = 0x61616161; + } else if (!strcmp(model,"QuickTake 150")) { + data_offset = 738 - head[5]; + if (head[5]) strcpy (model+10, "200"); + load_raw = &CLASS kodak_radc_load_raw; + height = 480; + width = 640; + filters = 0x61616161; + } else if (!strcmp(make,"Rollei") && !load_raw) { + switch (raw_width) { + case 1316: + height = 1030; + width = 1300; + top_margin = 1; + left_margin = 6; + break; + case 2568: + height = 1960; + width = 2560; + top_margin = 2; + left_margin = 8; + } + filters = 0x16161616; + load_raw = &CLASS rollei_load_raw; + } else if (!strcmp(model,"PC-CAM 600")) { + height = 768; + data_offset = width = 1024; + filters = 0x49494949; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"QV-2000UX")) { + height = 1208; + width = 1632; + data_offset = width * 2; + load_raw = &CLASS eight_bit_load_raw; + } else if (fsize == 3217760) { + height = 1546; + width = 2070; + raw_width = 2080; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"QV-4000")) { + height = 1700; + width = 2260; + load_raw = &CLASS unpacked_load_raw; + maximum = 0xffff; + } else if (!strcmp(model,"QV-5700")) { + height = 1924; + width = 2576; + raw_width = 3232; + tiff_bps = 10; + } else if (!strcmp(model,"QV-R41")) { + height = 1720; + width = 2312; + raw_width = 3520; + left_margin = 2; + } else if (!strcmp(model,"QV-R51")) { + height = 1926; + width = 2580; + raw_width = 3904; + } else if (!strcmp(model,"EX-S20")) { + height = 1208; + width = 1620; + raw_width = 2432; + flip = 3; + } else if (!strcmp(model,"EX-S100")) { + height = 1544; + width = 2058; + raw_width = 3136; + } else if (!strcmp(model,"EX-Z50")) { + height = 1931; + width = 2570; + raw_width = 3904; + } else if (!strcmp(model,"EX-Z55")) { + height = 1960; + width = 2570; + raw_width = 3904; + } else if (!strcmp(model,"EX-Z60")) { + height = 2145; + width = 2833; + raw_width = 3584; + filters = 0x16161616; + tiff_bps = 10; + } else if (!strcmp(model,"EX-Z75")) { + height = 2321; + width = 3089; + raw_width = 4672; + maximum = 0xfff; + } else if (!strcmp(model,"EX-Z750")) { + height = 2319; + width = 3087; + raw_width = 4672; + maximum = 0xfff; + } else if (!strcmp(model,"EX-Z850")) { + height = 2468; + width = 3279; + raw_width = 4928; + maximum = 0xfff; + } else if (!strcmp(model,"EX-P505")) { + height = 1928; + width = 2568; + raw_width = 3852; + maximum = 0xfff; + } else if (fsize == 9313536) { /* EX-P600 or QV-R61 */ + height = 2142; + width = 2844; + raw_width = 4288; + } else if (!strcmp(model,"EX-P700")) { + height = 2318; + width = 3082; + raw_width = 4672; + } + if (!model[0]) + sprintf (model, "%dx%d", width, height); + if (filters == UINT_MAX) filters = 0x94949494; + if (raw_color) adobe_coeff (make, model); + if (load_raw == &CLASS kodak_radc_load_raw) + if (raw_color) adobe_coeff ("Apple","Quicktake"); + if (thumb_offset && !thumb_height) { + fseek (ifp, thumb_offset, SEEK_SET); + if (ljpeg_start (&jh, 1)) { + thumb_width = jh.wide; + thumb_height = jh.high; + } + } +dng_skip: + if (!tiff_bps) tiff_bps = 12; + if (!maximum) maximum = (1 << tiff_bps) - 1; + if (!load_raw || height < 22) is_raw = 0; +#ifdef NO_JPEG + if (load_raw == &CLASS kodak_jpeg_load_raw) { + fprintf (stderr,_("%s: You must link dcraw with libjpeg!!\n"), ifname); + is_raw = 0; + } +#endif + if (!cdesc[0]) + strcpy (cdesc, colors == 3 ? "RGB":"GMCY"); + if (!raw_height) raw_height = height; + if (!raw_width ) raw_width = width; + if (filters && colors == 3) + for (i=0; i < 32; i+=4) { + if ((filters >> i & 15) == 9) + filters |= 2 << i; + if ((filters >> i & 15) == 6) + filters |= 8 << i; + } +notraw: + if (flip == -1) flip = tiff_flip; + if (flip == -1) flip = 0; +} + +#ifndef NO_LCMS +void CLASS apply_profile (const char *input, const char *output) +{ + char *prof; + cmsHPROFILE hInProfile=0, hOutProfile=0; + cmsHTRANSFORM hTransform; + FILE *fp; + unsigned size; + + cmsErrorAction (LCMS_ERROR_SHOW); + if (strcmp (input, "embed")) + hInProfile = cmsOpenProfileFromFile (input, "r"); + else if (profile_length) { + prof = (char *) malloc (profile_length); + merror (prof, "apply_profile()"); + fseek (ifp, profile_offset, SEEK_SET); + fread (prof, 1, profile_length, ifp); + hInProfile = cmsOpenProfileFromMem (prof, profile_length); + free (prof); + } else + fprintf (stderr,_("%s has no embedded profile.\n"), ifname); + if (!hInProfile) return; + if (!output) + hOutProfile = cmsCreate_sRGBProfile(); + else if ((fp = fopen (output, "rb"))) { + fread (&size, 4, 1, fp); + fseek (fp, 0, SEEK_SET); + oprof = (unsigned *) malloc (size = ntohl(size)); + merror (oprof, "apply_profile()"); + fread (oprof, 1, size, fp); + fclose (fp); + if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) { + free (oprof); + oprof = 0; + } + } else + fprintf (stderr,_("Cannot open file %s!\n"), output); + if (!hOutProfile) goto quit; + if (verbose) + fprintf (stderr,_("Applying color profile...\n")); + hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16, + hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0); + cmsDoTransform (hTransform, image, image, width*height); + raw_color = 1; /* Don't use rgb_cam with a profile */ + cmsDeleteTransform (hTransform); + cmsCloseProfile (hOutProfile); +quit: + cmsCloseProfile (hInProfile); +} +#endif + +void CLASS convert_to_rgb() +{ + int row, col, c, i, j, k; + ushort *img; + float out[3], out_cam[3][4]; + double num, inverse[3][3]; + static const double xyzd50_srgb[3][3] = + { { 0.436083, 0.385083, 0.143055 }, + { 0.222507, 0.716888, 0.060608 }, + { 0.013930, 0.097097, 0.714022 } }; + static const double rgb_rgb[3][3] = + { { 1,0,0 }, { 0,1,0 }, { 0,0,1 } }; + static const double adobe_rgb[3][3] = + { { 0.715146, 0.284856, 0.000000 }, + { 0.000000, 1.000000, 0.000000 }, + { 0.000000, 0.041166, 0.958839 } }; + static const double wide_rgb[3][3] = + { { 0.593087, 0.404710, 0.002206 }, + { 0.095413, 0.843149, 0.061439 }, + { 0.011621, 0.069091, 0.919288 } }; + static const double prophoto_rgb[3][3] = + { { 0.529317, 0.330092, 0.140588 }, + { 0.098368, 0.873465, 0.028169 }, + { 0.016879, 0.117663, 0.865457 } }; + static const double (*out_rgb[])[3] = + { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb }; + static const char *name[] = + { "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ" }; + static const unsigned phead[] = + { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0, + 0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d }; + unsigned pbody[] = + { 10, 0x63707274, 0, 36, /* cprt */ + 0x64657363, 0, 40, /* desc */ + 0x77747074, 0, 20, /* wtpt */ + 0x626b7074, 0, 20, /* bkpt */ + 0x72545243, 0, 14, /* rTRC */ + 0x67545243, 0, 14, /* gTRC */ + 0x62545243, 0, 14, /* bTRC */ + 0x7258595a, 0, 20, /* rXYZ */ + 0x6758595a, 0, 20, /* gXYZ */ + 0x6258595a, 0, 20 }; /* bXYZ */ + static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc }; + unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 }; + + gamma_curve (gamm[0], gamm[1], 0, 0); + memcpy (out_cam, rgb_cam, sizeof out_cam); + raw_color |= colors == 1 || document_mode || + output_color < 1 || output_color > 5; + if (!raw_color) { + oprof = (unsigned *) calloc (phead[0], 1); + merror (oprof, "convert_to_rgb()"); + memcpy (oprof, phead, sizeof phead); + if (output_color == 5) oprof[4] = oprof[5]; + oprof[0] = 132 + 12*pbody[0]; + for (i=0; i < pbody[0]; i++) { + oprof[oprof[0]/4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874; + pbody[i*3+2] = oprof[0]; + oprof[0] += (pbody[i*3+3] + 3) & -4; + } + memcpy (oprof+32, pbody, sizeof pbody); + oprof[pbody[5]/4+2] = strlen(name[output_color-1]) + 1; + memcpy ((char *)oprof+pbody[8]+8, pwhite, sizeof pwhite); + pcurve[3] = (short)(256/gamm[5]+0.5) << 16; + for (i=4; i < 7; i++) + memcpy ((char *)oprof+pbody[i*3+2], pcurve, sizeof pcurve); + pseudoinverse ((double (*)[3]) out_rgb[output_color-1], inverse, 3); + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) { + for (num = k=0; k < 3; k++) + num += xyzd50_srgb[i][k] * inverse[j][k]; + oprof[pbody[j*3+23]/4+i+2] = num * 0x10000 + 0.5; + } + for (i=0; i < phead[0]/4; i++) + oprof[i] = htonl(oprof[i]); + strcpy ((char *)oprof+pbody[2]+8, "auto-generated by dcraw"); + strcpy ((char *)oprof+pbody[5]+12, name[output_color-1]); + for (i=0; i < 3; i++) + for (j=0; j < colors; j++) + for (out_cam[i][j] = k=0; k < 3; k++) + out_cam[i][j] += out_rgb[output_color-1][i][k] * rgb_cam[k][j]; + } + if (verbose) + fprintf (stderr, raw_color ? _("Building histograms...\n") : + _("Converting to %s colorspace...\n"), name[output_color-1]); + + memset (histogram, 0, sizeof histogram); + for (img=image[0], row=0; row < height; row++) + for (col=0; col < width; col++, img+=4) { + if (!raw_color) { + out[0] = out[1] = out[2] = 0; + FORCC { + out[0] += out_cam[0][c] * img[c]; + out[1] += out_cam[1][c] * img[c]; + out[2] += out_cam[2][c] * img[c]; + } + FORC3 img[c] = CLIP((int) out[c]); + } + else if (document_mode) + img[0] = img[FC(row,col)]; + FORCC histogram[c][img[c] >> 3]++; + } + if (colors == 4 && output_color) colors = 3; + if (document_mode && filters) colors = 1; +} + +void CLASS fuji_rotate() +{ + int i, row, col; + double step; + float r, c, fr, fc; + unsigned ur, uc; + ushort wide, high, (*img)[4], (*pix)[4]; + + if (!fuji_width) return; + if (verbose) + fprintf (stderr,_("Rotating image 45 degrees...\n")); + fuji_width = (fuji_width - 1 + shrink) >> shrink; + step = sqrt(0.5); + wide = fuji_width / step; + high = (height - fuji_width) / step; + img = (ushort (*)[4]) calloc (wide*high, sizeof *img); + merror (img, "fuji_rotate()"); + + for (row=0; row < high; row++) + for (col=0; col < wide; col++) { + ur = r = fuji_width + (row-col)*step; + uc = c = (row+col)*step; + if (ur > height-2 || uc > width-2) continue; + fr = r - ur; + fc = c - uc; + pix = image + ur*width + uc; + for (i=0; i < colors; i++) + img[row*wide+col][i] = + (pix[ 0][i]*(1-fc) + pix[ 1][i]*fc) * (1-fr) + + (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr; + } + free (image); + width = wide; + height = high; + image = img; + fuji_width = 0; +} + +void CLASS stretch() +{ + ushort newdim, (*img)[4], *pix0, *pix1; + int row, col, c; + double rc, frac; + + if (pixel_aspect == 1) return; + if (verbose) fprintf (stderr,_("Stretching the image...\n")); + if (pixel_aspect < 1) { + newdim = height / pixel_aspect + 0.5; + img = (ushort (*)[4]) calloc (width*newdim, sizeof *img); + merror (img, "stretch()"); + for (rc=row=0; row < newdim; row++, rc+=pixel_aspect) { + frac = rc - (c = rc); + pix0 = pix1 = image[c*width]; + if (c+1 < height) pix1 += width*4; + for (col=0; col < width; col++, pix0+=4, pix1+=4) + FORCC img[row*width+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5; + } + height = newdim; + } else { + newdim = width * pixel_aspect + 0.5; + img = (ushort (*)[4]) calloc (height*newdim, sizeof *img); + merror (img, "stretch()"); + for (rc=col=0; col < newdim; col++, rc+=1/pixel_aspect) { + frac = rc - (c = rc); + pix0 = pix1 = image[c]; + if (c+1 < width) pix1 += 4; + for (row=0; row < height; row++, pix0+=width*4, pix1+=width*4) + FORCC img[row*newdim+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5; + } + width = newdim; + } + free (image); + image = img; +} + +int CLASS flip_index (int row, int col) +{ + if (flip & 4) SWAP(row,col); + if (flip & 2) row = iheight - 1 - row; + if (flip & 1) col = iwidth - 1 - col; + return row * iwidth + col; +} + +struct tiff_tag { + ushort tag, type; + int count; + union { char c[4]; short s[2]; int i; } val; +}; + +struct tiff_hdr { + ushort order, magic; + int ifd; + ushort pad, ntag; + struct tiff_tag tag[23]; + int nextifd; + ushort pad2, nexif; + struct tiff_tag exif[4]; + ushort pad3, ngps; + struct tiff_tag gpst[10]; + short bps[4]; + int rat[10]; + unsigned gps[26]; + char desc[512], make[64], model[64], soft[32], date[20], artist[64]; +}; + +void CLASS tiff_set (ushort *ntag, + ushort tag, ushort type, int count, int val) +{ + struct tiff_tag *tt; + int c; + + tt = (struct tiff_tag *)(ntag+1) + (*ntag)++; + tt->tag = tag; + tt->type = type; + tt->count = count; + if (type < 3 && count <= 4) + FORC(4) tt->val.c[c] = val >> (c << 3); + else if (type == 3 && count <= 2) + FORC(2) tt->val.s[c] = val >> (c << 4); + else tt->val.i = val; +} + +#define TOFF(ptr) ((char *)(&(ptr)) - (char *)th) + +void CLASS tiff_head (struct tiff_hdr *th, int full) +{ + int c, psize=0; + struct tm *t; + + memset (th, 0, sizeof *th); + th->order = htonl(0x4d4d4949) >> 16; + th->magic = 42; + th->ifd = 10; + if (full) { + tiff_set (&th->ntag, 254, 4, 1, 0); + tiff_set (&th->ntag, 256, 4, 1, width); + tiff_set (&th->ntag, 257, 4, 1, height); + tiff_set (&th->ntag, 258, 3, colors, output_bps); + if (colors > 2) + th->tag[th->ntag-1].val.i = TOFF(th->bps); + FORC4 th->bps[c] = output_bps; + tiff_set (&th->ntag, 259, 3, 1, 1); + tiff_set (&th->ntag, 262, 3, 1, 1 + (colors > 1)); + } + tiff_set (&th->ntag, 270, 2, 512, TOFF(th->desc)); + tiff_set (&th->ntag, 271, 2, 64, TOFF(th->make)); + tiff_set (&th->ntag, 272, 2, 64, TOFF(th->model)); + if (full) { + if (oprof) psize = ntohl(oprof[0]); + tiff_set (&th->ntag, 273, 4, 1, sizeof *th + psize); + tiff_set (&th->ntag, 277, 3, 1, colors); + tiff_set (&th->ntag, 278, 4, 1, height); + tiff_set (&th->ntag, 279, 4, 1, height*width*colors*output_bps/8); + } else + tiff_set (&th->ntag, 274, 3, 1, "12435867"[flip]-'0'); + tiff_set (&th->ntag, 282, 5, 1, TOFF(th->rat[0])); + tiff_set (&th->ntag, 283, 5, 1, TOFF(th->rat[2])); + tiff_set (&th->ntag, 284, 3, 1, 1); + tiff_set (&th->ntag, 296, 3, 1, 2); + tiff_set (&th->ntag, 305, 2, 32, TOFF(th->soft)); + tiff_set (&th->ntag, 306, 2, 20, TOFF(th->date)); + tiff_set (&th->ntag, 315, 2, 64, TOFF(th->artist)); + tiff_set (&th->ntag, 34665, 4, 1, TOFF(th->nexif)); + if (psize) tiff_set (&th->ntag, 34675, 7, psize, sizeof *th); + tiff_set (&th->nexif, 33434, 5, 1, TOFF(th->rat[4])); + tiff_set (&th->nexif, 33437, 5, 1, TOFF(th->rat[6])); + tiff_set (&th->nexif, 34855, 3, 1, iso_speed); + tiff_set (&th->nexif, 37386, 5, 1, TOFF(th->rat[8])); + if (gpsdata[1]) { + tiff_set (&th->ntag, 34853, 4, 1, TOFF(th->ngps)); + tiff_set (&th->ngps, 0, 1, 4, 0x202); + tiff_set (&th->ngps, 1, 2, 2, gpsdata[29]); + tiff_set (&th->ngps, 2, 5, 3, TOFF(th->gps[0])); + tiff_set (&th->ngps, 3, 2, 2, gpsdata[30]); + tiff_set (&th->ngps, 4, 5, 3, TOFF(th->gps[6])); + tiff_set (&th->ngps, 5, 1, 1, gpsdata[31]); + tiff_set (&th->ngps, 6, 5, 1, TOFF(th->gps[18])); + tiff_set (&th->ngps, 7, 5, 3, TOFF(th->gps[12])); + tiff_set (&th->ngps, 18, 2, 12, TOFF(th->gps[20])); + tiff_set (&th->ngps, 29, 2, 12, TOFF(th->gps[23])); + memcpy (th->gps, gpsdata, sizeof th->gps); + } + th->rat[0] = th->rat[2] = 300; + th->rat[1] = th->rat[3] = 1; + FORC(6) th->rat[4+c] = 1000000; + th->rat[4] *= shutter; + th->rat[6] *= aperture; + th->rat[8] *= focal_len; + strncpy (th->desc, desc, 512); + strncpy (th->make, make, 64); + strncpy (th->model, model, 64); + strcpy (th->soft, "dcraw v"VERSION); + t = gmtime (×tamp); + sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d", + t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec); + strncpy (th->artist, artist, 64); +} + +void CLASS jpeg_thumb() +{ + char *thumb; + ushort exif[5]; + struct tiff_hdr th; + + thumb = (char *) malloc (thumb_length); + merror (thumb, "jpeg_thumb()"); + fread (thumb, 1, thumb_length, ifp); + fputc (0xff, ofp); + fputc (0xd8, ofp); + if (strcmp (thumb+6, "Exif")) { + memcpy (exif, "\xff\xe1 Exif\0\0", 10); + exif[1] = htons (8 + sizeof th); + fwrite (exif, 1, sizeof exif, ofp); + tiff_head (&th, 0); + fwrite (&th, 1, sizeof th, ofp); + } + fwrite (thumb+2, 1, thumb_length-2, ofp); + free (thumb); +} + +void CLASS write_ppm_tiff() +{ + struct tiff_hdr th; + uchar *ppm; + ushort *ppm2; + int c, row, col, soff, rstep, cstep; + int perc, val, total, white=0x2000; + + perc = width * height * 0.01; /* 99th percentile white level */ + if (fuji_width) perc /= 2; + if (!((highlight & ~2) || no_auto_bright)) + for (white=c=0; c < colors; c++) { + for (val=0x2000, total=0; --val > 32; ) + if ((total += histogram[c][val]) > perc) break; + if (white < val) white = val; + } + gamma_curve (gamm[0], gamm[1], 2, (white << 3)/bright); + iheight = height; + iwidth = width; + if (flip & 4) SWAP(height,width); + ppm = (uchar *) calloc (width, colors*output_bps/8); + ppm2 = (ushort *) ppm; + merror (ppm, "write_ppm_tiff()"); + if (output_tiff) { + tiff_head (&th, 1); + fwrite (&th, sizeof th, 1, ofp); + if (oprof) + fwrite (oprof, ntohl(oprof[0]), 1, ofp); + } else if (colors > 3) + fprintf (ofp, + "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n", + width, height, colors, (1 << output_bps)-1, cdesc); + else + fprintf (ofp, "P%d\n%d %d\n%d\n", + colors/2+5, width, height, (1 << output_bps)-1); + soff = flip_index (0, 0); + cstep = flip_index (0, 1) - soff; + rstep = flip_index (1, 0) - flip_index (0, width); + for (row=0; row < height; row++, soff += rstep) { + for (col=0; col < width; col++, soff += cstep) + if (output_bps == 8) + FORCC ppm [col*colors+c] = curve[image[soff][c]] >> 8; + else FORCC ppm2[col*colors+c] = curve[image[soff][c]]; + if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa) + swab (ppm2, ppm2, width*colors*2); + fwrite (ppm, colors*output_bps/8, width, ofp); + } + free (ppm); +} + +int CLASS main (int argc, const char **argv) +{ + int arg, status=0; + int timestamp_only=0, thumbnail_only=0, identify_only=0; + int user_qual=-1, user_black=-1, user_sat=-1, user_flip=-1; + int use_fuji_rotate=1, write_to_stdout=0, quality, i, c; + const char *sp, *bpfile=0, *dark_frame=0, *write_ext; + char opm, opt, *ofname, *cp; + struct utimbuf ut; +#ifndef NO_LCMS + const char *cam_profile=0, *out_profile=0; +#endif + +#ifndef LOCALTIME + putenv ((char *) "TZ=UTC"); +#endif +#ifdef LOCALEDIR + setlocale (LC_CTYPE, ""); + setlocale (LC_MESSAGES, ""); + bindtextdomain ("dcraw", LOCALEDIR); + textdomain ("dcraw"); +#endif + + if (argc == 1) { + printf(_("\nRaw photo decoder \"dcraw\" v%s"), VERSION); + printf(_("\nby Dave Coffin, dcoffin a cybercom o net\n")); + printf(_("\nUsage: %s [OPTION]... [FILE]...\n\n"), argv[0]); + puts(_("-v Print verbose messages")); + puts(_("-c Write image data to standard output")); + puts(_("-e Extract embedded thumbnail image")); + puts(_("-i Identify files without decoding them")); + puts(_("-i -v Identify files and show metadata")); + puts(_("-z Change file dates to camera timestamp")); + puts(_("-w Use camera white balance, if possible")); + puts(_("-a Average the whole image for white balance")); + puts(_("-A Average a grey box for white balance")); + puts(_("-r Set custom white balance")); + puts(_("+M/-M Use/don't use an embedded color matrix")); + puts(_("-C Correct chromatic aberration")); + puts(_("-P Fix the dead pixels listed in this file")); + puts(_("-K Subtract dark frame (16-bit raw PGM)")); + puts(_("-k Set the darkness level")); + puts(_("-S Set the saturation level")); + puts(_("-n Set threshold for wavelet denoising")); + puts(_("-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)")); + puts(_("-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)")); + puts(_("-o [0-5] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ)")); +#ifndef NO_LCMS + puts(_("-o Apply output ICC profile from file")); + puts(_("-p Apply camera ICC profile from file or \"embed\"")); +#endif + puts(_("-d Document mode (no color, no interpolation)")); + puts(_("-D Document mode without scaling (totally raw)")); + puts(_("-j Don't stretch or rotate raw pixels")); + puts(_("-W Don't automatically brighten the image")); + puts(_("-b Adjust brightness (default = 1.0)")); + puts(_("-g

Set custom gamma curve (default = 2.222 4.5)")); + puts(_("-q [0-3] Set the interpolation quality")); + puts(_("-h Half-size color image (twice as fast as \"-q 0\")")); + puts(_("-f Interpolate RGGB as four colors")); + puts(_("-m Apply a 3x3 median filter to R-G and B-G")); + puts(_("-s [0..N-1] Select one raw image or \"all\" from each file")); + puts(_("-6 Write 16-bit instead of 8-bit")); + puts(_("-4 Linear 16-bit, same as \"-6 -W -g 1 1\"")); + puts(_("-T Write TIFF instead of PPM")); + puts(""); + return 1; + } + argv[argc] = ""; + for (arg=1; (((opm = argv[arg][0]) - 2) | 2) == '+'; ) { + opt = argv[arg++][1]; + if ((cp = (char *) strchr (sp="nbrkStqmHACg", opt))) + for (i=0; i < "114111111422"[cp-sp]-'0'; i++) + if (!isdigit(argv[arg+i][0])) { + fprintf (stderr,_("Non-numeric argument to \"-%c\"\n"), opt); + return 1; + } + switch (opt) { + case 'n': threshold = atof(argv[arg++]); break; + case 'b': bright = atof(argv[arg++]); break; + case 'r': + FORC4 user_mul[c] = atof(argv[arg++]); break; + case 'C': aber[0] = 1 / atof(argv[arg++]); + aber[2] = 1 / atof(argv[arg++]); break; + case 'g': gamm[0] = atof(argv[arg++]); + gamm[1] = atof(argv[arg++]); + if (gamm[0]) gamm[0] = 1/gamm[0]; break; + case 'k': user_black = atoi(argv[arg++]); break; + case 'S': user_sat = atoi(argv[arg++]); break; + case 't': user_flip = atoi(argv[arg++]); break; + case 'q': user_qual = atoi(argv[arg++]); break; + case 'm': med_passes = atoi(argv[arg++]); break; + case 'H': highlight = atoi(argv[arg++]); break; + case 's': + shot_select = abs(atoi(argv[arg])); + multi_out = !strcmp(argv[arg++],"all"); + break; + case 'o': + if (isdigit(argv[arg][0]) && !argv[arg][1]) + output_color = atoi(argv[arg++]); +#ifndef NO_LCMS + else out_profile = argv[arg++]; + break; + case 'p': cam_profile = argv[arg++]; +#endif + break; + case 'P': bpfile = argv[arg++]; break; + case 'K': dark_frame = argv[arg++]; break; + case 'z': timestamp_only = 1; break; + case 'e': thumbnail_only = 1; break; + case 'i': identify_only = 1; break; + case 'c': write_to_stdout = 1; break; + case 'v': verbose = 1; break; + case 'h': half_size = 1; /* "-h" implies "-f" */ + case 'f': four_color_rgb = 1; break; + case 'A': FORC4 greybox[c] = atoi(argv[arg++]); + case 'a': use_auto_wb = 1; break; + case 'w': use_camera_wb = 1; break; + case 'M': use_camera_matrix = (opm == '+'); break; + case 'D': + case 'd': document_mode = 1 + (opt == 'D'); + case 'j': use_fuji_rotate = 0; break; + case 'W': no_auto_bright = 1; break; + case 'T': output_tiff = 1; break; + case '4': gamm[0] = gamm[1] = + no_auto_bright = 1; + case '6': output_bps = 16; break; + default: + fprintf (stderr,_("Unknown option \"-%c\".\n"), opt); + return 1; + } + } + if (use_camera_matrix < 0) + use_camera_matrix = use_camera_wb; + if (arg == argc) { + fprintf (stderr,_("No files to process.\n")); + return 1; + } + if (write_to_stdout) { + if (isatty(1)) { + fprintf (stderr,_("Will not write an image to the terminal!\n")); + return 1; + } +#if defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__) + if (setmode(1,O_BINARY) < 0) { + perror ("setmode()"); + return 1; + } +#endif + } + for ( ; arg < argc; arg++) { + status = 1; + image = 0; + oprof = 0; + meta_data = ofname = 0; + ofp = stdout; + if (setjmp (failure)) { + if (fileno(ifp) > 2) fclose(ifp); + if (fileno(ofp) > 2) fclose(ofp); + status = 1; + goto cleanup; + } + ifname = argv[arg]; + if (!(ifp = fopen (ifname, "rb"))) { + perror (ifname); + continue; + } + status = (identify(),!is_raw); + if (user_flip >= 0) + flip = user_flip; + switch ((flip+3600) % 360) { + case 270: flip = 5; break; + case 180: flip = 3; break; + case 90: flip = 6; + } + if (timestamp_only) { + if ((status = !timestamp)) + fprintf (stderr,_("%s has no timestamp.\n"), ifname); + else if (identify_only) + printf ("%10ld%10d %s\n", (long) timestamp, shot_order, ifname); + else { + if (verbose) + fprintf (stderr,_("%s time set to %d.\n"), ifname, (int) timestamp); + ut.actime = ut.modtime = timestamp; + utime (ifname, &ut); + } + goto next; + } + write_fun = &CLASS write_ppm_tiff; + if (thumbnail_only) { + if ((status = !thumb_offset)) { + fprintf (stderr,_("%s has no thumbnail.\n"), ifname); + goto next; + } else if (thumb_load_raw) { + load_raw = thumb_load_raw; + data_offset = thumb_offset; + height = thumb_height; + width = thumb_width; + filters = 0; + } else { + fseek (ifp, thumb_offset, SEEK_SET); + write_fun = write_thumb; + goto thumbnail; + } + } + if (load_raw == &CLASS kodak_ycbcr_load_raw) { + height += height & 1; + width += width & 1; + } + if (identify_only && verbose && make[0]) { + printf (_("\nFilename: %s\n"), ifname); + printf (_("Timestamp: %s"), ctime(×tamp)); + printf (_("Camera: %s %s\n"), make, model); + if (artist[0]) + printf (_("Owner: %s\n"), artist); + if (dng_version) { + printf (_("DNG Version: ")); + for (i=24; i >= 0; i -= 8) + printf ("%d%c", dng_version >> i & 255, i ? '.':'\n'); + } + printf (_("ISO speed: %d\n"), (int) iso_speed); + printf (_("Shutter: ")); + if (shutter > 0 && shutter < 1) + shutter = (printf ("1/"), 1 / shutter); + printf (_("%0.1f sec\n"), shutter); + printf (_("Aperture: f/%0.1f\n"), aperture); + printf (_("Focal length: %0.1f mm\n"), focal_len); + printf (_("Embedded ICC profile: %s\n"), profile_length ? _("yes"):_("no")); + printf (_("Number of raw images: %d\n"), is_raw); + if (pixel_aspect != 1) + printf (_("Pixel Aspect Ratio: %0.6f\n"), pixel_aspect); + if (thumb_offset) + printf (_("Thumb size: %4d x %d\n"), thumb_width, thumb_height); + printf (_("Full size: %4d x %d\n"), raw_width, raw_height); + } else if (!is_raw) + fprintf (stderr,_("Cannot decode file %s\n"), ifname); + if (!is_raw) goto next; + shrink = filters && + (half_size || threshold || aber[0] != 1 || aber[2] != 1); + iheight = (height + shrink) >> shrink; + iwidth = (width + shrink) >> shrink; + if (identify_only) { + if (verbose) { + if (use_fuji_rotate) { + if (fuji_width) { + fuji_width = (fuji_width - 1 + shrink) >> shrink; + iwidth = fuji_width / sqrt(0.5); + iheight = (iheight - fuji_width) / sqrt(0.5); + } else { + if (pixel_aspect < 1) iheight = iheight / pixel_aspect + 0.5; + if (pixel_aspect > 1) iwidth = iwidth * pixel_aspect + 0.5; + } + } + if (flip & 4) + SWAP(iheight,iwidth); + printf (_("Image size: %4d x %d\n"), width, height); + printf (_("Output size: %4d x %d\n"), iwidth, iheight); + printf (_("Raw colors: %d"), colors); + if (filters) { + printf (_("\nFilter pattern: ")); + if (!cdesc[3]) cdesc[3] = 'G'; + for (i=0; i < 16; i++) + putchar (cdesc[fc(i >> 1,i & 1)]); + } + printf (_("\nDaylight multipliers:")); + FORCC printf (" %f", pre_mul[c]); + if (cam_mul[0] > 0) { + printf (_("\nCamera multipliers:")); + FORC4 printf (" %f", cam_mul[c]); + } + putchar ('\n'); + } else + printf (_("%s is a %s %s image.\n"), ifname, make, model); +next: + fclose(ifp); + continue; + } + if (use_camera_matrix && cmatrix[0][0] > 0.25) { + memcpy (rgb_cam, cmatrix, sizeof cmatrix); + raw_color = 0; + } + image = (ushort (*)[4]) calloc (iheight*iwidth, sizeof *image); + merror (image, "main()"); + if (meta_length) { + meta_data = (char *) malloc (meta_length); + merror (meta_data, "main()"); + } + if (verbose) + fprintf (stderr,_("Loading %s %s image from %s ...\n"), + make, model, ifname); + if (shot_select >= is_raw) + fprintf (stderr,_("%s: \"-s %d\" requests a nonexistent image!\n"), + ifname, shot_select); + fseeko (ifp, data_offset, SEEK_SET); + (*load_raw)(); + if (zero_is_bad) remove_zeroes(); + bad_pixels (bpfile); + if (dark_frame) subtract (dark_frame); + quality = 2 + !fuji_width; + if (user_qual >= 0) quality = user_qual; + if (user_black >= 0) black = user_black; + if (user_sat > 0) maximum = user_sat; +#ifdef COLORCHECK + colorcheck(); +#endif + if (is_foveon && !document_mode) foveon_interpolate(); + if (!is_foveon && document_mode < 2) scale_colors(); + pre_interpolate(); + if (filters && !document_mode) { + if (quality == 0) + lin_interpolate(); + else if (quality == 1 || colors > 3) + vng_interpolate(); + else if (quality == 2) + ppg_interpolate(); + else ahd_interpolate(); + } + if (mix_green) + for (colors=3, i=0; i < height*width; i++) + image[i][1] = (image[i][1] + image[i][3]) >> 1; + if (!is_foveon && colors == 3) median_filter(); + if (!is_foveon && highlight == 2) blend_highlights(); + if (!is_foveon && highlight > 2) recover_highlights(); + if (use_fuji_rotate) fuji_rotate(); +#ifndef NO_LCMS + if (cam_profile) apply_profile (cam_profile, out_profile); +#endif + convert_to_rgb(); + if (use_fuji_rotate) stretch(); +thumbnail: + if (write_fun == &CLASS jpeg_thumb) + write_ext = ".jpg"; + else if (output_tiff && write_fun == &CLASS write_ppm_tiff) + write_ext = ".tiff"; + else + write_ext = ".pgm\0.ppm\0.ppm\0.pam" + colors*5-5; + ofname = (char *) malloc (strlen(ifname) + 64); + merror (ofname, "main()"); + if (write_to_stdout) + strcpy (ofname,_("standard output")); + else { + strcpy (ofname, ifname); + if ((cp = strrchr (ofname, '.'))) *cp = 0; + if (multi_out) + sprintf (ofname+strlen(ofname), "_%0*d", + snprintf(0,0,"%d",is_raw-1), shot_select); + if (thumbnail_only) + strcat (ofname, ".thumb"); + strcat (ofname, write_ext); + ofp = fopen (ofname, "wb"); + if (!ofp) { + status = 1; + perror (ofname); + goto cleanup; + } + } + if (verbose) + fprintf (stderr,_("Writing data to %s ...\n"), ofname); + (*write_fun)(); + fclose(ifp); + if (ofp != stdout) fclose(ofp); +cleanup: + if (meta_data) free (meta_data); + if (ofname) free (ofname); + if (oprof) free (oprof); + if (image) free (image); + if (multi_out) { + if (++shot_select < is_raw) arg--; + else shot_select = 0; + } + } + return status; +} diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc new file mode 100644 index 000000000..1270dc376 --- /dev/null +++ b/rtengine/dcraw.cc @@ -0,0 +1,9619 @@ +/* + * This file is part of RawTherapee. + * + * The functions defined after the original "main" are copyrighted + * by Gabor Horvath and protected by the GNU + * General Public License. + * The original copyright notice of Dave Coffin is valid for everything + * before that point (see below). + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +/*RT*/#include +/*RT*/#include +/*RT*/int ciff_base, ciff_len, exif_base, pre_filters; +/*RT*/#undef MAX +/*RT*/#undef MIN +/*RT*/#undef ABS +/*RT*/#define NO_LCMS +/*RT*/#define NO_JPEG +/*RT*/#define LOCALTIME +/*RT*/#define DJGPP +/*RT*/#include + +#include "myfile.h" + +/* + dcraw.c -- Dave Coffin's raw photo decoder + Copyright 1997-2009 by Dave Coffin, dcoffin a cybercom o net + + This is a command-line ANSI C program to convert raw photos from + any digital camera on any computer running any operating system. + + No license is required to download and use dcraw.c. However, + to lawfully redistribute dcraw, you must either (a) offer, at + no extra charge, full source code* for all executable files + containing RESTRICTED functions, (b) distribute this code under + the GPL Version 2 or later, (c) remove all RESTRICTED functions, + re-implement them, or copy them from an earlier, unrestricted + Revision of dcraw.c, or (d) purchase a license from the author. + + The functions that process Foveon images have been RESTRICTED + since Revision 1.237. All other code remains free for all uses. + + *If you have not modified dcraw.c in any way, a link to my + homepage qualifies as "full source code". + + $Revision: 1.432 $ + $Date: 2009/12/25 18:51:16 $ + */ + +#define VERSION "8.99" + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* + NO_JPEG disables decoding of compressed Kodak DC120 files. + NO_LCMS disables the "-p" option. + */ +#ifndef NO_JPEG +/*RT*/extern "C" { +/*RT*/#include +/*RT*/} +#endif +#ifndef NO_LCMS +#include +#endif +#ifdef LOCALEDIR +#include +#define _(String) gettext(String) +#else +#define _(String) (String) +#endif +#ifdef DJGPP +#define fseeko fseek +#define ftello ftell +#else +#define fgetc getc_unlocked +#endif +#ifdef __CYGWIN__ +#include +#endif +#ifdef WIN32 +#include +#include +#pragma comment(lib, "ws2_32.lib") +#define snprintf _snprintf +#define strcasecmp stricmp +#define strncasecmp strnicmp +typedef __int64 INT64; +typedef unsigned __int64 UINT64; +#else +#include +#include +#include +typedef long long INT64; +typedef unsigned long long UINT64; +#endif + +#ifdef LJPEG_DECODE +#error Please compile dcraw.c by itself. +#error Do not link it with ljpeg_decode. +#endif + +#ifndef LONG_BIT +#define LONG_BIT (8 * sizeof (long)) +#endif + +#define ushort UshORt +typedef unsigned char uchar; +typedef unsigned short ushort; + +/* + All global variables are defined here, and all functions that + access them are prefixed with "CLASS". Note that a thread-safe + C++ class cannot have non-const static local variables. + */ +/*RT*/IMFILE *ifp; +FILE * ofp; +short order; +const char *ifname; +char *meta_data; +char cdesc[5], desc[512], make[64], model[64], model2[64], artist[64]; +float flash_used, canon_ev, iso_speed, shutter, aperture, focal_len; +time_t timestamp; +unsigned shot_order, kodak_cbpp, filters, exif_cfa, unique_id; +off_t strip_offset, data_offset; +off_t thumb_offset, meta_offset, profile_offset; +unsigned thumb_length, meta_length, profile_length; +unsigned thumb_misc, *oprof, fuji_layout, shot_select=0, multi_out=0; +unsigned tiff_nifds, tiff_samples, tiff_bps, tiff_compress; +unsigned black, maximum, mix_green, raw_color, zero_is_bad; +unsigned zero_after_ff, is_raw, dng_version, is_foveon, data_error; +unsigned tile_width, tile_length, gpsdata[32], load_flags; +ushort raw_height, raw_width, height, width, top_margin, left_margin; +ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height; +int flip, tiff_flip, colors; +double pixel_aspect, aber[4]={1,1,1,1}, gamm[6]={ 0.45,4.5,0,0,0,0 }; +ushort (*image)[4], white[8][8], curve[0x10000], cr2_slice[3], sraw_mul[4]; +float bright=1, user_mul[4]={0,0,0,0}, threshold=0; +int half_size=0, four_color_rgb=0, document_mode=0, highlight=0; +int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_matrix=-1; +int output_color=1, output_bps=8, output_tiff=0, med_passes=0; +int no_auto_bright=0; +unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX }; +float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4]; +const double xyz_rgb[3][3] = { /* XYZ from RGB */ + { 0.412453, 0.357580, 0.180423 }, + { 0.212671, 0.715160, 0.072169 }, + { 0.019334, 0.119193, 0.950227 } }; +const float d65_white[3] = { 0.950456, 1, 1.088754 }; +int histogram[4][0x2000]; +void (*write_thumb)(), (*write_fun)(); +void (*load_raw)(), (*thumb_load_raw)(); +jmp_buf failure; + +struct decode { + struct decode *branch[2]; + int leaf; +} first_decode[2048], *second_decode, *free_decode; + +struct tiff_ifd { + int width, height, bps, comp, phint, offset, flip, samples, bytes; +} tiff_ifd[10]; + +struct ph1 { + int format, key_off, black, black_off, split_col, tag_21a; + float tag_210; +} ph1; + +#define CLASS + +#define FORC(cnt) for (c=0; c < cnt; c++) +#define FORC3 FORC(3) +#define FORC4 FORC(4) +#define FORCC FORC(colors) + +#define SQR(x) ((x)*(x)) +#define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define LIM(x,min,max) MAX(min,MIN(x,max)) +#define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y)) +#define CLIP(x) LIM(x,0,65535) +#define SWAP(a,b) { a ^= b; a ^= (b ^= a); } + +/* + In order to inline this calculation, I make the risky + assumption that all filter patterns can be described + by a repeating pattern of eight rows and two columns + + Do not use the FC or BAYER macros with the Leaf CatchLight, + because its pattern is 16x16, not 2x8. + + Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2 + + PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1 + 0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4: + + 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 + 0 G M G M G M 0 C Y C Y C Y 0 Y C Y C Y C 0 G M G M G M + 1 C Y C Y C Y 1 M G M G M G 1 M G M G M G 1 Y C Y C Y C + 2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y + 3 C Y C Y C Y 3 G M G M G M 3 G M G M G M + 4 C Y C Y C Y 4 Y C Y C Y C + PowerShot A5 5 G M G M G M 5 G M G M G M + 0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y + 7 M G M G M G 7 M G M G M G + 0 1 2 3 4 5 + 0 C Y C Y C Y + 1 G M G M G M + 2 C Y C Y C Y + 3 M G M G M G + + All RGB cameras use one of these Bayer grids: + + 0x16161616: 0x61616161: 0x49494949: 0x94949494: + + 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 + 0 B G B G B G 0 G R G R G R 0 G B G B G B 0 R G R G R G + 1 G R G R G R 1 B G B G B G 1 R G R G R G 1 G B G B G B + 2 B G B G B G 2 G R G R G R 2 G B G B G B 2 R G R G R G + 3 G R G R G R 3 B G B G B G 3 R G R G R G 3 G B G B G B + */ + +#define FC(row,col) \ + (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) + +#define BAYER(row,col) \ + image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)] + +#define BAYER2(row,col) \ + image[((row) >> shrink)*iwidth + ((col) >> shrink)][fc(row,col)] + +int CLASS fc (int row, int col) +{ + static const char filter[16][16] = + { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 }, + { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 }, + { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 }, + { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 }, + { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 }, + { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 }, + { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 }, + { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 }, + { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 }, + { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 }, + { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 }, + { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 }, + { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 }, + { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 }, + { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 }, + { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } }; + + if (filters != 1) return FC(row,col); + return filter[(row+top_margin) & 15][(col+left_margin) & 15]; +} + +#ifndef __GLIBC__ +char *my_memmem (char *haystack, size_t haystacklen, + char *needle, size_t needlelen) +{ + char *c; + for (c = haystack; c <= haystack + haystacklen - needlelen; c++) + if (!memcmp (c, needle, needlelen)) + return c; + return 0; +} +#define memmem my_memmem +#endif + +void CLASS merror (void *ptr, const char *where) +{ + if (ptr) return; + fprintf (stderr,_("%s: Out of memory in %s\n"), ifname, where); + longjmp (failure, 1); +} + +void CLASS derror() +{ + if (!data_error) { + fprintf (stderr, "%s: ", ifname); + if (feof(ifp)) + fprintf (stderr,_("Unexpected end of file\n")); + else + fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp)); + } + data_error++; + /*RT*/ longjmp (failure, 1); +} + +ushort CLASS sget2 (uchar *s) +{ + if (order == 0x4949) /* "II" means little-endian */ + return s[0] | s[1] << 8; + else /* "MM" means big-endian */ + return s[0] << 8 | s[1]; +} + +ushort CLASS get2() +{ + uchar str[2] = { 0xff,0xff }; + fread (str, 1, 2, ifp); + return sget2(str); +} + +unsigned CLASS sget4 (uchar *s) +{ + if (order == 0x4949) + return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; + else + return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; +} +#define sget4(s) sget4((uchar *)s) + +unsigned CLASS get4() +{ + uchar str[4] = { 0xff,0xff,0xff,0xff }; + fread (str, 1, 4, ifp); + return sget4(str); +} + +unsigned CLASS getint (int type) +{ + return type == 3 ? get2() : get4(); +} + +float CLASS int_to_float (int i) +{ + union { int i; float f; } u; + u.i = i; + return u.f; +} + +double CLASS getreal (int type) +{ + union { char c[8]; double d; } u; + int i, rev; + + switch (type) { + case 3: return (unsigned short) get2(); + case 4: return (unsigned int) get4(); + case 5: u.d = (unsigned int) get4(); + return u.d / (unsigned int) get4(); + case 8: return (signed short) get2(); + case 9: return (signed int) get4(); + case 10: u.d = (signed int) get4(); + return u.d / (signed int) get4(); + case 11: return int_to_float (get4()); + case 12: + rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234)); + for (i=0; i < 8; i++) + u.c[i ^ rev] = fgetc(ifp); + return u.d; + default: return fgetc(ifp); + } +} + +void CLASS read_shorts (ushort *pixel, int count) +{ + if (fread (pixel, 2, count, ifp) < count) derror(); + if ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) + swab ((char*)pixel, (char*)pixel, count*2); +} + +void CLASS canon_black (double dark[2], int nblack) +{ + int c, diff, row, col; + + if (!nblack) return; + FORC(2) dark[c] /= nblack >> 1; + if ((diff = dark[0] - dark[1])) + for (row=0; row < height; row++) + for (col=1; col < width; col+=2) + BAYER(row,col) += diff; + dark[1] += diff; + black = (dark[0] + dark[1] + 1) / 2; +} + +void CLASS canon_600_fixed_wb (int temp) +{ + static const short mul[4][5] = { + { 667, 358,397,565,452 }, + { 731, 390,367,499,517 }, + { 1119, 396,348,448,537 }, + { 1399, 485,431,508,688 } }; + int lo, hi, i; + float frac=0; + + for (lo=4; --lo; ) + if (*mul[lo] <= temp) break; + for (hi=0; hi < 3; hi++) + if (*mul[hi] >= temp) break; + if (lo != hi) + frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]); + for (i=1; i < 5; i++) + pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]); +} + +/* Return values: 0 = white 1 = near white 2 = not white */ +int CLASS canon_600_color (int ratio[2], int mar) +{ + int clipped=0, target, miss; + + if (flash_used) { + if (ratio[1] < -104) + { ratio[1] = -104; clipped = 1; } + if (ratio[1] > 12) + { ratio[1] = 12; clipped = 1; } + } else { + if (ratio[1] < -264 || ratio[1] > 461) return 2; + if (ratio[1] < -50) + { ratio[1] = -50; clipped = 1; } + if (ratio[1] > 307) + { ratio[1] = 307; clipped = 1; } + } + target = flash_used || ratio[1] < 197 + ? -38 - (398 * ratio[1] >> 10) + : -123 + (48 * ratio[1] >> 10); + if (target - mar <= ratio[0] && + target + 20 >= ratio[0] && !clipped) return 0; + miss = target - ratio[0]; + if (abs(miss) >= mar*4) return 2; + if (miss < -20) miss = -20; + if (miss > mar) miss = mar; + ratio[0] = target - miss; + return 1; +} + +void CLASS canon_600_auto_wb() +{ + int mar, row, col, i, j, st, count[] = { 0,0 }; + int test[8], total[2][8], ratio[2][2], stat[2]; + + memset (&total, 0, sizeof total); + i = canon_ev + 0.5; + if (i < 10) mar = 150; + else if (i > 12) mar = 20; + else mar = 280 - 20 * i; + if (flash_used) mar = 80; + for (row=14; row < height-14; row+=4) + for (col=10; col < width; col+=2) { + for (i=0; i < 8; i++) + test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] = + BAYER(row+(i >> 1),col+(i & 1)); + for (i=0; i < 8; i++) + if (test[i] < 150 || test[i] > 1500) goto next; + for (i=0; i < 4; i++) + if (abs(test[i] - test[i+4]) > 50) goto next; + for (i=0; i < 2; i++) { + for (j=0; j < 4; j+=2) + ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j]; + stat[i] = canon_600_color (ratio[i], mar); + } + if ((st = stat[0] | stat[1]) > 1) goto next; + for (i=0; i < 2; i++) + if (stat[i]) + for (j=0; j < 2; j++) + test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10; + for (i=0; i < 8; i++) + total[st][i] += test[i]; + count[st]++; +next: ; + } + if (count[0] | count[1]) { + st = count[0]*200 < count[1]; + for (i=0; i < 4; i++) + pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]); + } +} + +void CLASS canon_600_coeff() +{ + static const short table[6][12] = { + { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 }, + { -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 }, + { -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 }, + { -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 }, + { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 }, + { -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } }; + int t=0, i, c; + float mc, yc; + + mc = pre_mul[1] / pre_mul[2]; + yc = pre_mul[3] / pre_mul[2]; + if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1; + if (mc > 1.28 && mc <= 2) { + if (yc < 0.8789) t=3; + else if (yc <= 2) t=4; + } + if (flash_used) t=5; + for (raw_color = i=0; i < 3; i++) + FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0; +} + +void CLASS canon_600_load_raw() +{ + uchar data[1120], *dp; + ushort pixel[896], *pix; + int irow, row, col, val; + static const short mul[4][2] = + { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } }; + + for (irow=row=0; irow < height; irow++) { + if (fread (data, 1, raw_width*5/4, ifp) < raw_width*5/4) derror(); + for (dp=data, pix=pixel; dp < data+1120; dp+=10, pix+=8) { + pix[0] = (dp[0] << 2) + (dp[1] >> 6 ); + pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3); + pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3); + pix[3] = (dp[4] << 2) + (dp[1] & 3); + pix[4] = (dp[5] << 2) + (dp[9] & 3); + pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3); + pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3); + pix[7] = (dp[8] << 2) + (dp[9] >> 6 ); + } + for (col=0; col < width; col++) + BAYER(row,col) = pixel[col]; + for (col=width; col < raw_width; col++) + black += pixel[col]; + if ((row+=2) > height) row = 1; + } + if (raw_width > width) + black = black / ((raw_width - width) * height) - 4; + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + if ((val = BAYER(row,col) - black) < 0) val = 0; + val = val * mul[row & 3][col & 1] >> 9; + BAYER(row,col) = val; + } + canon_600_fixed_wb(1311); + canon_600_auto_wb(); + canon_600_coeff(); + maximum = (0x3ff - black) * 1109 >> 9; + black = 0; +} + +void CLASS remove_zeroes() +{ + unsigned row, col, tot, n, r, c; + + for (row=0; row < height; row++) + for (col=0; col < width; col++) + if (BAYER(row,col) == 0) { + tot = n = 0; + for (r = row-2; r <= row+2; r++) + for (c = col-2; c <= col+2; c++) + if (r < height && c < width && + FC(r,c) == FC(row,col) && BAYER(r,c)) + tot += (n++,BAYER(r,c)); + if (n) BAYER(row,col) = tot/n; + } +} + +int CLASS canon_s2is() +{ + unsigned row; + + for (row=0; row < 100; row++) { + fseek (ifp, row*3340 + 3284, SEEK_SET); + if (getc(ifp) > 15) return 1; + } + return 0; +} + +/* + getbits(-1) initializes the buffer + getbits(n) where 0 <= n <= 25 returns an n-bit integer + */ +unsigned CLASS getbithuff (int nbits, ushort *huff) +{ + static unsigned bitbuf=0; + static int vbits=0, reset=0; + unsigned c; + + if (nbits == -1) + return bitbuf = vbits = reset = 0; + if (nbits == 0 || vbits < 0) return 0; + while (!reset && vbits < nbits && (c = fgetc(ifp)) != EOF && + !(reset = zero_after_ff && c == 0xff && fgetc(ifp))) { + bitbuf = (bitbuf << 8) + (uchar) c; + vbits += 8; + } + c = bitbuf << (32-vbits) >> (32-nbits); + if (huff) { + vbits -= huff[c] >> 8; + c = (uchar) huff[c]; + } else + vbits -= nbits; + if (vbits < 0) derror(); + return c; +} + +#define getbits(n) getbithuff(n,0) +#define gethuff(h) getbithuff(*h,h+1) + +/* + Construct a decode tree according the specification in *source. + The first 16 bytes specify how many codes should be 1-bit, 2-bit + 3-bit, etc. Bytes after that are the leaf values. + + For example, if the source is + + { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, + 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff }, + + then the code is + + 00 0x04 + 010 0x03 + 011 0x05 + 100 0x06 + 101 0x02 + 1100 0x07 + 1101 0x01 + 11100 0x08 + 11101 0x09 + 11110 0x00 + 111110 0x0a + 1111110 0x0b + 1111111 0xff + */ +ushort * CLASS make_decoder_ref (const uchar **source) +{ + int max, len, h, i, j; + const uchar *count; + ushort *huff; + + count = (*source += 16) - 17; + for (max=16; max && !count[max]; max--); + huff = (ushort *) calloc (1 + (1 << max), sizeof *huff); + merror (huff, "make_decoder()"); + huff[0] = max; + for (h=len=1; len <= max; len++) + for (i=0; i < count[len]; i++, ++*source) + for (j=0; j < 1 << (max-len); j++) + if (h <= 1 << max) + huff[h++] = len << 8 | **source; + return huff; +} + +ushort * CLASS make_decoder (const uchar *source) +{ + return make_decoder_ref (&source); +} + +void CLASS crw_init_tables (unsigned table, ushort *huff[2]) +{ + static const uchar first_tree[3][29] = { + { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, + 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff }, + { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0, + 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff }, + { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0, + 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff }, + }; + static const uchar second_tree[3][180] = { + { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139, + 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08, + 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0, + 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42, + 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57, + 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9, + 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98, + 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6, + 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4, + 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7, + 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1, + 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64, + 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba, + 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4, + 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff }, + { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140, + 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06, + 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32, + 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51, + 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26, + 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59, + 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9, + 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99, + 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85, + 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8, + 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a, + 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9, + 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8, + 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8, + 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff }, + { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117, + 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08, + 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22, + 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34, + 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41, + 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48, + 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69, + 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8, + 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94, + 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a, + 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6, + 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62, + 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5, + 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3, + 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff } + }; + if (table > 2) table = 2; + huff[0] = make_decoder ( first_tree[table]); + huff[1] = make_decoder (second_tree[table]); +} + +/* + Return 0 if the image starts with compressed data, + 1 if it starts with uncompressed low-order bits. + + In Canon compressed data, 0xff is always followed by 0x00. + */ +int CLASS canon_has_lowbits() +{ + uchar test[0x4000]; + int ret=1, i; + + fseek (ifp, 0, SEEK_SET); + fread (test, 1, sizeof test, ifp); + for (i=540; i < sizeof test - 1; i++) + if (test[i] == 0xff) { + if (test[i+1]) return 1; + ret=0; + } + return ret; +} + +void CLASS canon_compressed_load_raw() +{ + ushort *pixel, *prow, *huff[2]; + int nblocks, lowbits, i, c, row, r, col, save, val, nblack=0; + unsigned irow, icol; + int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2]; + double dark[2] = { 0,0 }; + + crw_init_tables (tiff_compress, huff); + pixel = (ushort *) calloc (raw_width*8, sizeof *pixel); + merror (pixel, "canon_compressed_load_raw()"); + lowbits = canon_has_lowbits(); + if (!lowbits) maximum = 0x3ff; + fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET); + zero_after_ff = 1; + getbits(-1); + for (row=0; row < raw_height; row+=8) { + nblocks = MIN (8, raw_height-row) * raw_width >> 6; + for (block=0; block < nblocks; block++) { + memset (diffbuf, 0, sizeof diffbuf); + for (i=0; i < 64; i++ ) { + leaf = gethuff(huff[i > 0]); + if (leaf == 0 && i) break; + if (leaf == 0xff) continue; + i += leaf >> 4; + len = leaf & 15; + if (len == 0) continue; + diff = getbits(len); + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + if (i < 64) diffbuf[i] = diff; + } + diffbuf[0] += carry; + carry = diffbuf[0]; + for (i=0; i < 64; i++ ) { + if (pnum++ % raw_width == 0) + base[0] = base[1] = 512; + if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10) + derror(); + } + } + if (lowbits) { + save = ftell(ifp); + fseek (ifp, 26 + row*raw_width/4, SEEK_SET); + for (prow=pixel, i=0; i < raw_width*2; i++) { + c = fgetc(ifp); + for (r=0; r < 8; r+=2, prow++) { + val = (*prow << 2) + ((c >> r) & 3); + if (raw_width == 2672 && val < 512) val += 2; + *prow = val; + } + } + fseek (ifp, save, SEEK_SET); + } + for (r=0; r < 8; r++) { + irow = row - top_margin + r; + if (irow >= height) continue; + for (col=0; col < raw_width; col++) { + icol = col - left_margin; + if (icol < width) + BAYER(irow,icol) = pixel[r*raw_width+col]; + else if (col > 1 && (unsigned) (col-left_margin+2) > width+3) + dark[icol & 1] += (nblack++,pixel[r*raw_width+col]); + } + } + } + free (pixel); + FORC(2) free (huff[c]); + canon_black (dark, nblack); +} + +/* + Not a full implementation of Lossless JPEG, just + enough to decode Canon, Kodak and Adobe DNG images. + */ +struct jhead { + int bits, high, wide, clrs, sraw, psv, restart, vpred[6]; + ushort *huff[6], *free[4], *row; +}; + +int CLASS ljpeg_start (struct jhead *jh, int info_only) +{ + int c, tag, len; + uchar data[0x10000]; + const uchar *dp; + + memset (jh, 0, sizeof *jh); + jh->restart = INT_MAX; + fread (data, 2, 1, ifp); + if (data[1] != 0xd8) return 0; + do { + fread (data, 2, 2, ifp); + tag = data[0] << 8 | data[1]; + len = (data[2] << 8 | data[3]) - 2; + if (tag <= 0xff00) return 0; + fread (data, 1, len, ifp); + switch (tag) { + case 0xffc3: + jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3; + case 0xffc0: + jh->bits = data[0]; + jh->high = data[1] << 8 | data[2]; + jh->wide = data[3] << 8 | data[4]; + jh->clrs = data[5] + jh->sraw; + if (len == 9 && !dng_version) getc(ifp); + break; + case 0xffc4: + if (info_only) break; + for (dp = data; dp < data+len && (c = *dp++) < 4; ) + jh->free[c] = jh->huff[c] = make_decoder_ref (&dp); + break; + case 0xffda: + jh->psv = data[1+data[0]*2]; + jh->bits -= data[3+data[0]*2] & 15; + break; + case 0xffdd: + jh->restart = data[0] << 8 | data[1]; + } + } while (tag != 0xffda); + if (info_only) return 1; + FORC(5) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c]; + if (jh->sraw) { + FORC(4) jh->huff[2+c] = jh->huff[1]; + FORC(jh->sraw) jh->huff[1+c] = jh->huff[0]; + } + jh->row = (ushort *) calloc (jh->wide*jh->clrs, 4); + merror (jh->row, "ljpeg_start()"); + return zero_after_ff = 1; +} + +void CLASS ljpeg_end (struct jhead *jh) +{ + int c; + FORC4 if (jh->free[c]) free (jh->free[c]); + free (jh->row); +} + +int CLASS ljpeg_diff (ushort *huff) +{ + int len, diff; + + len = gethuff(huff); + if (len == 16 && (!dng_version || dng_version >= 0x1010000)) + return -32768; + diff = getbits(len); + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + return diff; +} + +ushort * CLASS ljpeg_row (int jrow, struct jhead *jh) +{ + int col, c, diff, pred, spred=0; + ushort mark=0, *row[3]; + + if (jrow * jh->wide % jh->restart == 0) { + FORC(6) jh->vpred[c] = 1 << (jh->bits-1); + if (jrow) { + fseek (ifp, -2, SEEK_CUR); + do mark = (mark << 8) + (c = fgetc(ifp)); + while (c != EOF && mark >> 4 != 0xffd); + } + getbits(-1); + } + FORC3 row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1); + for (col=0; col < jh->wide; col++) + FORC(jh->clrs) { + diff = ljpeg_diff (jh->huff[c]); + if (jh->sraw && c <= jh->sraw && (col | c)) + pred = spred; + else if (col) pred = row[0][-jh->clrs]; + else pred = (jh->vpred[c] += diff) - diff; + if (jrow && col) switch (jh->psv) { + case 1: break; + case 2: pred = row[1][0]; break; + case 3: pred = row[1][-jh->clrs]; break; + case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break; + case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break; + case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break; + case 7: pred = (pred + row[1][0]) >> 1; break; + default: pred = 0; + } + if ((**row = pred + diff) >> jh->bits) derror(); + if (c <= jh->sraw) spred = **row; + row[0]++; row[1]++; + } + return row[2]; +} + +void CLASS lossless_jpeg_load_raw() +{ + int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0, nblack=0; + double dark[2] = { 0,0 }; + struct jhead jh; + int min=INT_MAX; + ushort *rp; + + if (!ljpeg_start (&jh, 0)) return; + jwide = jh.wide * jh.clrs; + + for (jrow=0; jrow < jh.high; jrow++) { + rp = ljpeg_row (jrow, &jh); + for (jcol=0; jcol < jwide; jcol++) { + val = *rp++; + if (jh.bits <= 12) + val = curve[val & 0xfff]; + if (cr2_slice[0]) { + jidx = jrow*jwide + jcol; + i = jidx / (cr2_slice[1]*jh.high); + if ((j = i >= cr2_slice[0])) + i = cr2_slice[0]; + jidx -= i * (cr2_slice[1]*jh.high); + row = jidx / cr2_slice[1+j]; + col = jidx % cr2_slice[1+j] + i*cr2_slice[1]; + } + if (raw_width == 3984 && (col -= 2) < 0) + col += (row--,raw_width); + if ((unsigned) (row-top_margin) < height) { + if ((unsigned) (col-left_margin) < width) { + BAYER(row-top_margin,col-left_margin) = val; + if (min > val) min = val; + } else if (col > 1 && (unsigned) (col-left_margin+2) > width+3) + dark[(col-left_margin) & 1] += (nblack++,val); + } + if (++col >= raw_width) + col = (row++,0); + } + } + ljpeg_end (&jh); + canon_black (dark, nblack); + if (!strcasecmp(make,"KODAK")) + black = min; +} + +void CLASS canon_sraw_load_raw() +{ + struct jhead jh; + short *rp=0, (*ip)[4]; + int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c; + int v[3]={0,0,0}, ver, hue; + char *cp; + + if (!ljpeg_start (&jh, 0)) return; + jwide = (jh.wide >>= 1) * jh.clrs; + + for (ecol=slice=0; slice <= cr2_slice[0]; slice++) { + scol = ecol; + ecol += cr2_slice[1] * 2 / jh.clrs; + if (!cr2_slice[0] || ecol > raw_width-1) ecol = raw_width & -2; + for (row=0; row < height; row += (jh.clrs >> 1) - 1) { + ip = (short (*)[4]) image + row*width; + for (col=scol; col < ecol; col+=2, jcol+=jh.clrs) { + if ((jcol %= jwide) == 0) + rp = (short *) ljpeg_row (jrow++, &jh); + if (col >= width) continue; + FORC (jh.clrs-2) + ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c]; + ip[col][1] = rp[jcol+jh.clrs-2] - 16384; + ip[col][2] = rp[jcol+jh.clrs-1] - 16384; + } + } + } + for (cp=model2; *cp && !isdigit(*cp); cp++); + sscanf (cp, "%d.%d.%d", v, v+1, v+2); + ver = (v[0]*1000 + v[1])*1000 + v[2]; + hue = (jh.sraw+1) << 2; + if (unique_id == 0x80000218 && ver > 1000006 && ver < 3000000) + hue = jh.sraw << 1; + ip = (short (*)[4]) image; + rp = ip[0]; + for (row=0; row < height; row++, ip+=width) { + if (row & (jh.sraw >> 1)) + for (col=0; col < width; col+=2) + for (c=1; c < 3; c++) + if (row == height-1) + ip[col][c] = ip[col-width][c]; + else ip[col][c] = (ip[col-width][c] + ip[col+width][c] + 1) >> 1; + for (col=1; col < width; col+=2) + for (c=1; c < 3; c++) + if (col == width-1) + ip[col][c] = ip[col-1][c]; + else ip[col][c] = (ip[col-1][c] + ip[col+1][c] + 1) >> 1; + } + for ( ; rp < ip[0]; rp+=4) { + if (unique_id < 0x80000218) { + pix[0] = rp[0] + rp[2] - 512; + pix[2] = rp[0] + rp[1] - 512; + pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12) - 512; + } else { + rp[1] = (rp[1] << 2) + hue; + rp[2] = (rp[2] << 2) + hue; + pix[0] = rp[0] + (( 200*rp[1] + 22929*rp[2]) >> 14); + pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14); + pix[2] = rp[0] + ((29040*rp[1] - 101*rp[2]) >> 14); + } + FORC3 rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10); + } + ljpeg_end (&jh); + maximum = 0x3fff; +} + +void CLASS adobe_copy_pixel (int row, int col, ushort **rp) +{ + unsigned r, c; + + r = row -= top_margin; + c = col -= left_margin; + if (is_raw == 2 && shot_select) (*rp)++; + if (filters) { + if (fuji_width) { + r = row + fuji_width - 1 - (col >> 1); + c = row + ((col+1) >> 1); + } + if (r < height && c < width) + BAYER(r,c) = **rp < 0x1000 ? curve[**rp] : **rp; + *rp += is_raw; + } else { + if (r < height && c < width) + FORC(tiff_samples) + image[row*width+col][c] = (*rp)[c] < 0x1000 ? curve[(*rp)[c]]:(*rp)[c]; + *rp += tiff_samples; + } + if (is_raw == 2 && shot_select) (*rp)--; +} + +void CLASS adobe_dng_load_raw_lj() +{ + unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col; + struct jhead jh; + ushort *rp; + + while (trow < raw_height) { + save = ftell(ifp); + if (tile_length < INT_MAX) + fseek (ifp, get4(), SEEK_SET); + if (!ljpeg_start (&jh, 0)) break; + jwide = jh.wide; + if (filters) jwide *= jh.clrs; + jwide /= is_raw; + for (row=col=jrow=0; jrow < jh.high; jrow++) { + rp = ljpeg_row (jrow, &jh); + for (jcol=0; jcol < jwide; jcol++) { + adobe_copy_pixel (trow+row, tcol+col, &rp); + if (++col >= tile_width || col >= raw_width) + row += 1 + (col = 0); + } + } + fseek (ifp, save+4, SEEK_SET); + if ((tcol += tile_width) >= raw_width) + trow += tile_length + (tcol = 0); + ljpeg_end (&jh); + } +} + +void CLASS adobe_dng_load_raw_nc() +{ + ushort *pixel, *rp; + int row, col; + + pixel = (ushort *) calloc (raw_width * tiff_samples, sizeof *pixel); + merror (pixel, "adobe_dng_load_raw_nc()"); + for (row=0; row < raw_height; row++) { + if (tiff_bps == 16) + read_shorts (pixel, raw_width * tiff_samples); + else { + getbits(-1); + for (col=0; col < raw_width * tiff_samples; col++) + pixel[col] = getbits(tiff_bps); + } + for (rp=pixel, col=0; col < raw_width; col++) + adobe_copy_pixel (row, col, &rp); + } + free (pixel); +} + +void CLASS pentax_load_raw() +{ + ushort bit[2][13], huff[4097]; + int row, col, diff, c, i; + ushort vpred[2][2] = {{0,0},{0,0}}, hpred[2]; + + fseek (ifp, meta_offset, SEEK_SET); + FORC(13) bit[0][c] = get2(); + FORC(13) bit[1][c] = fgetc(ifp); + FORC(13) + for (i=bit[0][c]; i <= ((bit[0][c]+(4096 >> bit[1][c])-1) & 4095); ) + huff[++i] = bit[1][c] << 8 | c; + huff[0] = 12; + fseek (ifp, data_offset, SEEK_SET); + getbits(-1); + for (row=0; row < raw_height; row++) + for (col=0; col < raw_width; col++) { + diff = ljpeg_diff (huff); + if (col < 2) hpred[col] = vpred[row & 1][col] += diff; + else hpred[col & 1] += diff; + if ((unsigned) (row-top_margin) < height && col < width) + BAYER(row-top_margin,col) = hpred[col & 1]; + if (hpred[col & 1] >> 12) derror(); + } +} + +void CLASS nikon_compressed_load_raw() +{ + static const uchar nikon_tree[][32] = { + { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy */ + 5,4,3,6,2,7,1,0,8,9,11,10,12 }, + { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy after split */ + 0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 }, + { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, /* 12-bit lossless */ + 5,4,6,3,7,2,8,1,9,0,10,11,12 }, + { 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0, /* 14-bit lossy */ + 5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 }, + { 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0, /* 14-bit lossy after split */ + 8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 }, + { 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0, /* 14-bit lossless */ + 7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 } }; + ushort *huff, ver0, ver1, vpred[2][2], hpred[2], csize; + int i, min, max, step=0, tree=0, split=0, row, col, len, shl, diff; + + fseek (ifp, meta_offset, SEEK_SET); + ver0 = fgetc(ifp); + ver1 = fgetc(ifp); + if (ver0 == 0x49 || ver1 == 0x58) + fseek (ifp, 2110, SEEK_CUR); + if (ver0 == 0x46) tree = 2; + if (tiff_bps == 14) tree += 3; + read_shorts (vpred[0], 4); + max = 1 << tiff_bps & 0x7fff; + if ((csize = get2()) > 1) + step = max / (csize-1); + if (ver0 == 0x44 && ver1 == 0x20 && step > 0) { + for (i=0; i < csize; i++) + curve[i*step] = get2(); + for (i=0; i < max; i++) + curve[i] = ( curve[i-i%step]*(step-i%step) + + curve[i-i%step+step]*(i%step) ) / step; + fseek (ifp, meta_offset+562, SEEK_SET); + split = get2(); + } else if (ver0 != 0x46 && csize <= 0x4001) + read_shorts (curve, max=csize); + while (curve[max-2] == curve[max-1]) max--; + huff = make_decoder (nikon_tree[tree]); + fseek (ifp, data_offset, SEEK_SET); + getbits(-1); + for (min=row=0; row < height; row++) { + if (split && row == split) { + free (huff); + huff = make_decoder (nikon_tree[tree+1]); + max += (min = 16) << 1; + } + for (col=0; col < raw_width; col++) { + i = gethuff(huff); + len = i & 15; + shl = i >> 4; + diff = ((getbits(len-shl) << 1) + 1) << shl >> 1; + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - !shl; + if (col < 2) hpred[col] = vpred[row & 1][col] += diff; + else hpred[col & 1] += diff; + if ((ushort)(hpred[col & 1] + min) >= max) derror(); + if ((unsigned) (col-left_margin) < width) + BAYER(row,col-left_margin) = curve[LIM((short)hpred[col & 1],0,0x3fff)]; + } + } + free (huff); +} + +/* + Figure out if a NEF file is compressed. These fancy heuristics + are only needed for the D100, thanks to a bug in some cameras + that tags all images as "compressed". + */ +int CLASS nikon_is_compressed() +{ + uchar test[256]; + int i; + + fseek (ifp, data_offset, SEEK_SET); + fread (test, 1, 256, ifp); + for (i=15; i < 256; i+=16) + if (test[i]) return 1; + return 0; +} + +/* + Returns 1 for a Coolpix 995, 0 for anything else. + */ +int CLASS nikon_e995() +{ + int i, histo[256]; + const uchar often[] = { 0x00, 0x55, 0xaa, 0xff }; + + memset (histo, 0, sizeof histo); + fseek (ifp, -2000, SEEK_END); + for (i=0; i < 2000; i++) + histo[fgetc(ifp)]++; + for (i=0; i < 4; i++) + if (histo[often[i]] < 200) + return 0; + return 1; +} + +/* + Returns 1 for a Coolpix 2100, 0 for anything else. + */ +int CLASS nikon_e2100() +{ + uchar t[12]; + int i; + + fseek (ifp, 0, SEEK_SET); + for (i=0; i < 1024; i++) { + fread (t, 1, 12, ifp); + if (((t[2] & t[4] & t[7] & t[9]) >> 4 + & t[1] & t[6] & t[8] & t[11] & 3) != 3) + return 0; + } + return 1; +} + +void CLASS nikon_3700() +{ + int bits, i; + uchar dp[24]; + static const struct { + int bits; + char make[12], model[15]; + } table[] = { + { 0x00, "PENTAX", "Optio 33WR" }, + { 0x03, "NIKON", "E3200" }, + { 0x32, "NIKON", "E3700" }, + { 0x33, "OLYMPUS", "C740UZ" } }; + + fseek (ifp, 3072, SEEK_SET); + fread (dp, 1, 24, ifp); + bits = (dp[8] & 3) << 4 | (dp[20] & 3); + for (i=0; i < sizeof table / sizeof *table; i++) + if (bits == table[i].bits) { + strcpy (make, table[i].make ); + strcpy (model, table[i].model); + } +} + +/* + Separates a Minolta DiMAGE Z2 from a Nikon E4300. + */ +int CLASS minolta_z2() +{ + int i, nz; + char tail[424]; + + fseek (ifp, -sizeof tail, SEEK_END); + fread (tail, 1, sizeof tail, ifp); + for (nz=i=0; i < sizeof tail; i++) + if (tail[i]) nz++; + return nz > 20; +} + +/* + The Fuji Super CCD is just a Bayer grid rotated 45 degrees. + */ +void CLASS fuji_load_raw() +{ + ushort *pixel; + int wide, row, col, r, c; + + fseek (ifp, (top_margin*raw_width + left_margin) * 2, SEEK_CUR); + wide = fuji_width << !fuji_layout; + pixel = (ushort *) calloc (wide, sizeof *pixel); + merror (pixel, "fuji_load_raw()"); + for (row=0; row < raw_height; row++) { + read_shorts (pixel, wide); + fseek (ifp, 2*(raw_width - wide), SEEK_CUR); + for (col=0; col < wide; col++) { + if (fuji_layout) { + r = fuji_width - 1 - col + (row >> 1); + c = col + ((row+1) >> 1); + } else { + r = fuji_width - 1 + row - (col >> 1); + c = row + ((col+1) >> 1); + } + BAYER(r,c) = pixel[col]; + } + } + free (pixel); +} + +void CLASS jpeg_thumb(); + +void CLASS ppm_thumb() +{ + char *thumb; + thumb_length = thumb_width*thumb_height*3; + thumb = (char *) malloc (thumb_length); + merror (thumb, "ppm_thumb()"); + fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); + fread (thumb, 1, thumb_length, ifp); + fwrite (thumb, 1, thumb_length, ofp); + free (thumb); +} + +void CLASS layer_thumb() +{ + int i, c; + char *thumb, map[][4] = { "012","102" }; + + colors = thumb_misc >> 5 & 7; + thumb_length = thumb_width*thumb_height; + thumb = (char *) calloc (colors, thumb_length); + merror (thumb, "layer_thumb()"); + fprintf (ofp, "P%d\n%d %d\n255\n", + 5 + (colors >> 1), thumb_width, thumb_height); + fread (thumb, thumb_length, colors, ifp); + for (i=0; i < thumb_length; i++) + FORCC putc (thumb[i+thumb_length*(map[thumb_misc >> 8][c]-'0')], ofp); + free (thumb); +} + +void CLASS rollei_thumb() +{ + unsigned i; + ushort *thumb; + + thumb_length = thumb_width * thumb_height; + thumb = (ushort *) calloc (thumb_length, 2); + merror (thumb, "rollei_thumb()"); + fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); + read_shorts (thumb, thumb_length); + for (i=0; i < thumb_length; i++) { + putc (thumb[i] << 3, ofp); + putc (thumb[i] >> 5 << 2, ofp); + putc (thumb[i] >> 11 << 3, ofp); + } + free (thumb); +} + +void CLASS rollei_load_raw() +{ + uchar pixel[10]; + unsigned iten=0, isix, i, buffer=0, row, col, todo[16]; + + isix = raw_width * raw_height * 5 / 8; + while (fread (pixel, 1, 10, ifp) == 10) { + for (i=0; i < 10; i+=2) { + todo[i] = iten++; + todo[i+1] = pixel[i] << 8 | pixel[i+1]; + buffer = pixel[i] >> 2 | buffer << 6; + } + for ( ; i < 16; i+=2) { + todo[i] = isix++; + todo[i+1] = buffer >> (14-i)*5; + } + for (i=0; i < 16; i+=2) { + row = todo[i] / raw_width - top_margin; + col = todo[i] % raw_width - left_margin; + if (row < height && col < width) + BAYER(row,col) = (todo[i+1] & 0x3ff); + } + } + maximum = 0x3ff; +} + +int CLASS bayer (unsigned row, unsigned col) +{ + return (row < height && col < width) ? BAYER(row,col) : 0; +} + +void CLASS phase_one_flat_field (int is_float, int nc) +{ + ushort head[8]; + unsigned wide, y, x, c, rend, cend, row, col; + float *mrow, num, mult[4]; + + read_shorts (head, 8); + wide = head[2] / head[4]; + mrow = (float *) calloc (nc*wide, sizeof *mrow); + merror (mrow, "phase_one_flat_field()"); + for (y=0; y < head[3] / head[5]; y++) { + for (x=0; x < wide; x++) + for (c=0; c < nc; c+=2) { + num = is_float ? getreal(11) : get2()/32768.0; + if (y==0) mrow[c*wide+x] = num; + else mrow[(c+1)*wide+x] = (num - mrow[c*wide+x]) / head[5]; + } + if (y==0) continue; + rend = head[1]-top_margin + y*head[5]; + for (row = rend-head[5]; row < height && row < rend; row++) { + for (x=1; x < wide; x++) { + for (c=0; c < nc; c+=2) { + mult[c] = mrow[c*wide+x-1]; + mult[c+1] = (mrow[c*wide+x] - mult[c]) / head[4]; + } + cend = head[0]-left_margin + x*head[4]; + for (col = cend-head[4]; col < width && col < cend; col++) { + c = nc > 2 ? FC(row,col) : 0; + if (!(c & 1)) { + c = BAYER(row,col) * mult[c]; + BAYER(row,col) = LIM(c,0,65535); + } + for (c=0; c < nc; c+=2) + mult[c] += mult[c+1]; + } + } + for (x=0; x < wide; x++) + for (c=0; c < nc; c+=2) + mrow[c*wide+x] += mrow[(c+1)*wide+x]; + } + } + free (mrow); +} + +void CLASS phase_one_correct() +{ + unsigned entries, tag, data, save, col, row, type; + int len, i, j, k, cip, val[4], dev[4], sum, max; + int head[9], diff, mindiff=INT_MAX, off_412=0; + static const signed char dir[12][2] = + { {-1,-1}, {-1,1}, {1,-1}, {1,1}, {-2,0}, {0,-2}, {0,2}, {2,0}, + {-2,-2}, {-2,2}, {2,-2}, {2,2} }; + float poly[8], num, cfrac, frac, mult[2], *yval[2]; + ushort *xval[2]; + + if (half_size || !meta_length) return; + if (verbose) fprintf (stderr,_("Phase One correction...\n")); + fseek (ifp, meta_offset, SEEK_SET); + order = get2(); + fseek (ifp, 6, SEEK_CUR); + fseek (ifp, meta_offset+get4(), SEEK_SET); + entries = get4(); get4(); + while (entries--) { + tag = get4(); + len = get4(); + data = get4(); + save = ftell(ifp); + fseek (ifp, meta_offset+data, SEEK_SET); + if (tag == 0x419) { /* Polynomial curve */ + for (get4(), i=0; i < 8; i++) + poly[i] = getreal(11); + poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1; + for (i=0; i < 0x10000; i++) { + num = (poly[5]*i + poly[3])*i + poly[1]; + curve[i] = LIM(num,0,65535); + } goto apply; /* apply to right half */ + } else if (tag == 0x41a) { /* Polynomial curve */ + for (i=0; i < 4; i++) + poly[i] = getreal(11); + for (i=0; i < 0x10000; i++) { + for (num=0, j=4; j--; ) + num = num * i + poly[j]; + curve[i] = LIM(num+i,0,65535); + } apply: /* apply to whole image */ + for (row=0; row < height; row++) + for (col = (tag & 1)*ph1.split_col; col < width; col++) + BAYER(row,col) = curve[BAYER(row,col)]; + } else if (tag == 0x400) { /* Sensor defects */ + while ((len -= 8) >= 0) { + col = get2() - left_margin; + row = get2() - top_margin; + type = get2(); get2(); + if (col >= width) continue; + if (type == 131) /* Bad column */ + for (row=0; row < height; row++) + if (FC(row,col) == 1) { + for (sum=i=0; i < 4; i++) + sum += val[i] = bayer (row+dir[i][0], col+dir[i][1]); + for (max=i=0; i < 4; i++) { + dev[i] = abs((val[i] << 2) - sum); + if (dev[max] < dev[i]) max = i; + } + BAYER(row,col) = (sum - val[max])/3.0 + 0.5; + } else { + for (sum=0, i=8; i < 12; i++) + sum += bayer (row+dir[i][0], col+dir[i][1]); + BAYER(row,col) = 0.5 + sum * 0.0732233 + + (bayer(row,col-2) + bayer(row,col+2)) * 0.3535534; + } + else if (type == 129) { /* Bad pixel */ + if (row >= height) continue; + j = (FC(row,col) != 1) * 4; + for (sum=0, i=j; i < j+8; i++) + sum += bayer (row+dir[i][0], col+dir[i][1]); + BAYER(row,col) = (sum + 4) >> 3; + } + } + } else if (tag == 0x401) { /* All-color flat fields */ + phase_one_flat_field (1, 2); + } else if (tag == 0x416 || tag == 0x410) { + phase_one_flat_field (0, 2); + } else if (tag == 0x40b) { /* Red+blue flat field */ + phase_one_flat_field (0, 4); + } else if (tag == 0x412) { + fseek (ifp, 36, SEEK_CUR); + diff = abs (get2() - ph1.tag_21a); + if (mindiff > diff) { + mindiff = diff; + off_412 = ftell(ifp) - 38; + } + } + fseek (ifp, save, SEEK_SET); + } + if (off_412) { + fseek (ifp, off_412, SEEK_SET); + for (i=0; i < 9; i++) head[i] = get4() & 0x7fff; + yval[0] = (float *) calloc (head[1]*head[3] + head[2]*head[4], 6); + merror (yval[0], "phase_one_correct()"); + yval[1] = (float *) (yval[0] + head[1]*head[3]); + xval[0] = (ushort *) (yval[1] + head[2]*head[4]); + xval[1] = (ushort *) (xval[0] + head[1]*head[3]); + get2(); + for (i=0; i < 2; i++) + for (j=0; j < head[i+1]*head[i+3]; j++) + yval[i][j] = getreal(11); + for (i=0; i < 2; i++) + for (j=0; j < head[i+1]*head[i+3]; j++) + xval[i][j] = get2(); + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + cfrac = (float) col * head[3] / raw_width; + cfrac -= cip = cfrac; + num = BAYER(row,col) * 0.5; + for (i=cip; i < cip+2; i++) { + for (k=j=0; j < head[1]; j++) + if (num < xval[0][k = head[1]*i+j]) break; + frac = (j == 0 || j == head[1]) ? 0 : + (xval[0][k] - num) / (xval[0][k] - xval[0][k-1]); + mult[i-cip] = yval[0][k-1] * frac + yval[0][k] * (1-frac); + } + i = ((mult[0] * (1-cfrac) + mult[1] * cfrac) + * (row + top_margin) + num) * 2; + BAYER(row,col) = LIM(i,0,65535); + } + free (yval[0]); + } +} + +void CLASS phase_one_load_raw() +{ + int row, col, a, b; + ushort *pixel, akey, bkey, mask; + + fseek (ifp, ph1.key_off, SEEK_SET); + akey = get2(); + bkey = get2(); + mask = ph1.format == 1 ? 0x5555:0x1354; + fseek (ifp, data_offset + top_margin*raw_width*2, SEEK_SET); + pixel = (ushort *) calloc (raw_width, sizeof *pixel); + merror (pixel, "phase_one_load_raw()"); + for (row=0; row < height; row++) { + read_shorts (pixel, raw_width); + for (col=0; col < raw_width; col+=2) { + a = pixel[col+0] ^ akey; + b = pixel[col+1] ^ bkey; + pixel[col+0] = (a & mask) | (b & ~mask); + pixel[col+1] = (b & mask) | (a & ~mask); + } + for (col=0; col < width; col++) + BAYER(row,col) = pixel[col+left_margin]; + } + free (pixel); + phase_one_correct(); +} + +unsigned CLASS ph1_bithuff (int nbits, ushort *huff) +{ + static UINT64 bitbuf=0; + static int vbits=0; + unsigned c; + + if (nbits == -1) + return bitbuf = vbits = 0; + if (nbits == 0) return 0; + if (vbits < nbits) { + bitbuf = bitbuf << 32 | get4(); + vbits += 32; + } + c = bitbuf << (64-vbits) >> (64-nbits); + if (huff) { + vbits -= huff[c] >> 8; + return (uchar) huff[c]; + } + vbits -= nbits; + return c; +} +#define ph1_bits(n) ph1_bithuff(n,0) +#define ph1_huff(h) ph1_bithuff(*h,h+1) + +void CLASS phase_one_load_raw_c() +{ + static const int length[] = { 8,7,6,9,11,10,5,12,14,13 }; + int *offset, len[2], pred[2], row, col, i, j; + ushort *pixel; + short (*black)[2]; + + pixel = (ushort *) calloc (raw_width + raw_height*4, 2); + merror (pixel, "phase_one_load_raw_c()"); + offset = (int *) (pixel + raw_width); + fseek (ifp, strip_offset, SEEK_SET); + for (row=0; row < raw_height; row++) + offset[row] = get4(); + black = (short (*)[2]) offset + raw_height; + fseek (ifp, ph1.black_off, SEEK_SET); + if (ph1.black_off) + read_shorts ((ushort *) black[0], raw_height*2); + for (i=0; i < 256; i++) + curve[i] = i*i / 3.969 + 0.5; + for (row=0; row < raw_height; row++) { + fseek (ifp, data_offset + offset[row], SEEK_SET); + ph1_bits(-1); + pred[0] = pred[1] = 0; + for (col=0; col < raw_width; col++) { + if (col >= (raw_width & -8)) + len[0] = len[1] = 14; + else if ((col & 7) == 0) + for (i=0; i < 2; i++) { + for (j=0; j < 5 && !ph1_bits(1); j++); + if (j--) len[i] = length[j*2 + ph1_bits(1)]; + } + if ((i = len[col & 1]) == 14) + pixel[col] = pred[col & 1] = ph1_bits(16); + else + pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1)); + if (pred[col & 1] >> 16) derror(); + if (ph1.format == 5 && pixel[col] < 256) + pixel[col] = curve[pixel[col]]; + } + if ((unsigned) (row-top_margin) < height) + for (col=0; col < width; col++) { + i = (pixel[col+left_margin] << 2) + - ph1.black + black[row][col >= ph1.split_col]; + if (i > 0) BAYER(row-top_margin,col) = i; + } + } + free (pixel); + phase_one_correct(); + maximum = 0xfffc - ph1.black; +} + +void CLASS hasselblad_load_raw() +{ + struct jhead jh; + int row, col, pred[2], len[2], diff, c; + + if (!ljpeg_start (&jh, 0)) return; + order = 0x4949; + ph1_bits(-1); + for (row=-top_margin; row < height; row++) { + pred[0] = pred[1] = 0x8000; + for (col=-left_margin; col < raw_width-left_margin; col+=2) { + FORC(2) len[c] = ph1_huff(jh.huff[0]); + FORC(2) { + diff = ph1_bits(len[c]); + if ((diff & (1 << (len[c]-1))) == 0) + diff -= (1 << len[c]) - 1; + if (diff == 65535) diff = -32768; + pred[c] += diff; + if (row >= 0 && (unsigned)(col+c) < width) + BAYER(row,col+c) = pred[c]; + } + } + } + ljpeg_end (&jh); + maximum = 0xffff; +} + +void CLASS leaf_hdr_load_raw() +{ + ushort *pixel; + unsigned tile=0, r, c, row, col; + + pixel = (ushort *) calloc (raw_width, sizeof *pixel); + merror (pixel, "leaf_hdr_load_raw()"); + FORC(tiff_samples) + for (r=0; r < raw_height; r++) { + if (r % tile_length == 0) { + fseek (ifp, data_offset + 4*tile++, SEEK_SET); + fseek (ifp, get4() + 2*left_margin, SEEK_SET); + } + if (filters && c != shot_select) continue; + read_shorts (pixel, raw_width); + if ((row = r - top_margin) >= height) continue; + for (col=0; col < width; col++) + if (filters) BAYER(row,col) = pixel[col]; + else image[row*width+col][c] = pixel[col]; + } + free (pixel); + if (!filters) { + maximum = 0xffff; + raw_color = 1; + } +} + +void CLASS unpacked_load_raw(); + +void CLASS sinar_4shot_load_raw() +{ + ushort *pixel; + unsigned shot, row, col, r, c; + + if ((shot = shot_select) || half_size) { + if (shot) shot--; + if (shot > 3) shot = 3; + fseek (ifp, data_offset + shot*4, SEEK_SET); + fseek (ifp, get4(), SEEK_SET); + unpacked_load_raw(); + return; + } + free (image); + image = (ushort (*)[4]) + calloc ((iheight=height)*(iwidth=width), sizeof *image); + merror (image, "sinar_4shot_load_raw()"); + pixel = (ushort *) calloc (raw_width, sizeof *pixel); + merror (pixel, "sinar_4shot_load_raw()"); + for (shot=0; shot < 4; shot++) { + fseek (ifp, data_offset + shot*4, SEEK_SET); + fseek (ifp, get4(), SEEK_SET); + for (row=0; row < raw_height; row++) { + read_shorts (pixel, raw_width); + if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue; + for (col=0; col < raw_width; col++) { + if ((c = col-left_margin - (shot & 1)) >= width) continue; + image[r*width+c][FC(row,col)] = pixel[col]; + } + } + } + free (pixel); + shrink = filters = 0; +} + +void CLASS imacon_full_load_raw() +{ + int row, col; + + for (row=0; row < height; row++) + for (col=0; col < width; col++) + read_shorts (image[row*width+col], 3); +} + +void CLASS packed_load_raw() +{ + int vbits=0, bwide, pwide, rbits, bite, half, irow, row, col, val, i; + UINT64 bitbuf=0; + + if (raw_width * 8 >= width * tiff_bps) /* Is raw_width in bytes? */ + pwide = (bwide = raw_width) * 8 / tiff_bps; + else bwide = (pwide = raw_width) * tiff_bps / 8; + rbits = bwide * 8 - pwide * tiff_bps; + if (load_flags & 1) bwide = bwide * 16 / 15; + fseek (ifp, top_margin*bwide, SEEK_CUR); + bite = 8 + (load_flags & 24); + half = (height+1) >> 1; + for (irow=0; irow < height; irow++) { + row = irow; + if (load_flags & 2 && + (row = irow % half * 2 + irow / half) == 1 && + load_flags & 4) { + if (vbits=0, tiff_compress) + fseek (ifp, data_offset - (-half*bwide & -2048), SEEK_SET); + else { + fseek (ifp, 0, SEEK_END); + fseek (ifp, ftell(ifp) >> 3 << 2, SEEK_SET); + } + } + for (col=0; col < pwide; col++) { + for (vbits -= tiff_bps; vbits < 0; vbits += bite) { + bitbuf <<= bite; + for (i=0; i < bite; i+=8) + bitbuf |= (unsigned) (fgetc(ifp) << i); + } + val = bitbuf << (64-tiff_bps-vbits) >> (64-tiff_bps); + i = (col ^ (bite == 24)) - left_margin; + if ((unsigned) i < width) + BAYER(row,i) = val << (load_flags >> 6); + else if (load_flags & 32) + black += val; + if (load_flags & 1 && (col % 10) == 9 && + fgetc(ifp) && col < width+left_margin) derror(); + } + vbits -= rbits; + } + if (load_flags & 32 && pwide > width) + black /= (pwide - width) * height; +} + +void CLASS unpacked_load_raw() +{ + ushort *pixel; + int row, col, bits=0; + + while (1 << ++bits < maximum); + fseek (ifp, (top_margin*raw_width + left_margin) * 2, SEEK_CUR); + pixel = (ushort *) calloc (width, sizeof *pixel); + merror (pixel, "unpacked_load_raw()"); + for (row=0; row < height; row++) { + read_shorts (pixel, width); + fseek (ifp, 2*(raw_width - width), SEEK_CUR); + for (col=0; col < width; col++) + if ((BAYER2(row,col) = pixel[col]) >> bits) derror(); + } + free (pixel); +} + +void CLASS nokia_load_raw() +{ + uchar *data, *dp; + ushort *pixel, *pix; + int dwide, row, c; + + dwide = raw_width * 5 / 4; + data = (uchar *) malloc (dwide + raw_width*2); + merror (data, "nokia_load_raw()"); + pixel = (ushort *) (data + dwide); + for (row=0; row < raw_height; row++) { + if (fread (data, 1, dwide, ifp) < dwide) derror(); + for (dp=data, pix=pixel; pix < pixel+raw_width; dp+=5, pix+=4) + FORC4 pix[c] = (dp[c] << 2) | (dp[4] >> (c << 1) & 3); + if (row < top_margin) + FORC(width) black += pixel[c]; + else + FORC(width) BAYER(row-top_margin,c) = pixel[c]; + } + free (data); + if (top_margin) black /= top_margin * width; + maximum = 0x3ff; +} + +unsigned CLASS pana_bits (int nbits) +{ + static uchar buf[0x4000]; + static int vbits; + int byte; + + if (!nbits) return vbits=0; + if (!vbits) { + fread (buf+load_flags, 1, 0x4000-load_flags, ifp); + fread (buf, 1, load_flags, ifp); + } + vbits = (vbits - nbits) & 0x1ffff; + byte = vbits >> 3 ^ 0x3ff0; + return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits); +} + +void CLASS panasonic_load_raw() +{ + int row, col, i, j, sh=0, pred[2], nonz[2]; + + pana_bits(0); + for (row=0; row < height; row++) + for (col=0; col < raw_width; col++) { + if ((i = col % 14) == 0) + pred[0] = pred[1] = nonz[0] = nonz[1] = 0; + if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2)); + if (nonz[i & 1]) { + if ((j = pana_bits(8))) { + if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4) + pred[i & 1] &= ~(-1 << sh); + pred[i & 1] += j << sh; + } + } else if ((nonz[i & 1] = pana_bits(8)) || i > 11) + pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4); + if (col < width) + if ((BAYER(row,col) = pred[col & 1]) > 4098) derror(); + } +} + +void CLASS olympus_load_raw() +{ + ushort huff[4096]; + int row, col, nbits, sign, low, high, i, c, w, n, nw; + int acarry[2][3], *carry, pred, diff; + + huff[n=0] = 0xc0c; + for (i=12; i--; ) + FORC(2048 >> i) huff[++n] = (i+1) << 8 | i; + fseek (ifp, 7, SEEK_CUR); + getbits(-1); + for (row=0; row < height; row++) { + memset (acarry, 0, sizeof acarry); + for (col=0; col < raw_width; col++) { + carry = acarry[col & 1]; + i = 2 * (carry[2] < 3); + for (nbits=2+i; (ushort) carry[0] >> (nbits+i); nbits++); + low = (sign = getbits(3)) & 3; + sign = sign << 29 >> 31; + if ((high = getbithuff(12,huff)) == 12) + high = getbits(16-nbits) >> 1; + carry[0] = (high << nbits) | getbits(nbits); + diff = (carry[0] ^ sign) + carry[1]; + carry[1] = (diff*3 + carry[1]) >> 5; + carry[2] = carry[0] > 16 ? 0 : carry[2]+1; + if (col >= width) continue; + if (row < 2 && col < 2) pred = 0; + else if (row < 2) pred = BAYER(row,col-2); + else if (col < 2) pred = BAYER(row-2,col); + else { + w = BAYER(row,col-2); + n = BAYER(row-2,col); + nw = BAYER(row-2,col-2); + if ((w < nw && nw < n) || (n < nw && nw < w)) { + if (ABS(w-nw) > 32 || ABS(n-nw) > 32) + pred = w + n - nw; + else pred = (w + n) >> 1; + } else pred = ABS(w-nw) > ABS(n-nw) ? w : n; + } + if ((BAYER(row,col) = pred + ((diff << 2) | low)) >> 12) derror(); + } + } +} + +void CLASS minolta_rd175_load_raw() +{ + uchar pixel[768]; + unsigned irow, box, row, col; + + for (irow=0; irow < 1481; irow++) { + if (fread (pixel, 1, 768, ifp) < 768) derror(); + box = irow / 82; + row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2); + switch (irow) { + case 1477: case 1479: continue; + case 1476: row = 984; break; + case 1480: row = 985; break; + case 1478: row = 985; box = 1; + } + if ((box < 12) && (box & 1)) { + for (col=0; col < 1533; col++, row ^= 1) + if (col != 1) BAYER(row,col) = (col+1) & 2 ? + pixel[col/2-1] + pixel[col/2+1] : pixel[col/2] << 1; + BAYER(row,1) = pixel[1] << 1; + BAYER(row,1533) = pixel[765] << 1; + } else + for (col=row & 1; col < 1534; col+=2) + BAYER(row,col) = pixel[col/2] << 1; + } + maximum = 0xff << 1; +} + +void CLASS quicktake_100_load_raw() +{ + uchar pixel[484][644]; + static const short gstep[16] = + { -89,-60,-44,-32,-22,-15,-8,-2,2,8,15,22,32,44,60,89 }; + static const short rstep[6][4] = + { { -3,-1,1,3 }, { -5,-1,1,5 }, { -8,-2,2,8 }, + { -13,-3,3,13 }, { -19,-4,4,19 }, { -28,-6,6,28 } }; + static const short curve[256] = + { 0,1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27, + 28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,53, + 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,74,75,76,77,78, + 79,80,81,82,83,84,86,88,90,92,94,97,99,101,103,105,107,110,112,114,116, + 118,120,123,125,127,129,131,134,136,138,140,142,144,147,149,151,153,155, + 158,160,162,164,166,168,171,173,175,177,179,181,184,186,188,190,192,195, + 197,199,201,203,205,208,210,212,214,216,218,221,223,226,230,235,239,244, + 248,252,257,261,265,270,274,278,283,287,291,296,300,305,309,313,318,322, + 326,331,335,339,344,348,352,357,361,365,370,374,379,383,387,392,396,400, + 405,409,413,418,422,426,431,435,440,444,448,453,457,461,466,470,474,479, + 483,487,492,496,500,508,519,531,542,553,564,575,587,598,609,620,631,643, + 654,665,676,687,698,710,721,732,743,754,766,777,788,799,810,822,833,844, + 855,866,878,889,900,911,922,933,945,956,967,978,989,1001,1012,1023 }; + int rb, row, col, sharp, val=0; + + getbits(-1); + memset (pixel, 0x80, sizeof pixel); + for (row=2; row < height+2; row++) { + for (col=2+(row & 1); col < width+2; col+=2) { + val = ((pixel[row-1][col-1] + 2*pixel[row-1][col+1] + + pixel[row][col-2]) >> 2) + gstep[getbits(4)]; + pixel[row][col] = val = LIM(val,0,255); + if (col < 4) + pixel[row][col-2] = pixel[row+1][~row & 1] = val; + if (row == 2) + pixel[row-1][col+1] = pixel[row-1][col+3] = val; + } + pixel[row][col] = val; + } + for (rb=0; rb < 2; rb++) + for (row=2+rb; row < height+2; row+=2) + for (col=3-(row & 1); col < width+2; col+=2) { + if (row < 4 || col < 4) sharp = 2; + else { + val = ABS(pixel[row-2][col] - pixel[row][col-2]) + + ABS(pixel[row-2][col] - pixel[row-2][col-2]) + + ABS(pixel[row][col-2] - pixel[row-2][col-2]); + sharp = val < 4 ? 0 : val < 8 ? 1 : val < 16 ? 2 : + val < 32 ? 3 : val < 48 ? 4 : 5; + } + val = ((pixel[row-2][col] + pixel[row][col-2]) >> 1) + + rstep[sharp][getbits(2)]; + pixel[row][col] = val = LIM(val,0,255); + if (row < 4) pixel[row-2][col+2] = val; + if (col < 4) pixel[row+2][col-2] = val; + } + for (row=2; row < height+2; row++) + for (col=3-(row & 1); col < width+2; col+=2) { + val = ((pixel[row][col-1] + (pixel[row][col] << 2) + + pixel[row][col+1]) >> 1) - 0x100; + pixel[row][col] = LIM(val,0,255); + } + for (row=0; row < height; row++) + for (col=0; col < width; col++) + BAYER(row,col) = curve[pixel[row+2][col+2]]; + maximum = 0x3ff; +} + +#define radc_token(tree) ((signed char) getbithuff(8,huff[tree])) + +#define FORYX for (y=1; y < 3; y++) for (x=col+1; x >= col; x--) + +#define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \ +: (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4) + +void CLASS kodak_radc_load_raw() +{ + static const char src[] = { + 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8, + 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8, + 2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8, + 2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8, + 2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8, + 2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8, + 2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8, + 2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8, + 2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4, + 2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8, + 1,0, 2,2, 2,-2, + 1,-3, 1,3, + 2,-17, 2,-5, 2,5, 2,17, + 2,-7, 2,2, 2,9, 2,18, + 2,-18, 2,-9, 2,-2, 2,7, + 2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79, + 2,-1, 2,13, 2,26, 3,39, 4,-16, 5,55, 6,-37, 6,76, + 2,-26, 2,-13, 2,1, 3,-39, 4,16, 5,-55, 6,-76, 6,37 + }; + ushort huff[19][256]; + int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val; + short last[3] = { 16,16,16 }, mul[3], buf[3][3][386]; + static const ushort pt[] = + { 0,0, 1280,1344, 2320,3616, 3328,8000, 4095,16383, 65535,16383 }; + + for (i=2; i < 12; i+=2) + for (c=pt[i-2]; c <= pt[i]; c++) + curve[c] = (float) + (c-pt[i-2]) / (pt[i]-pt[i-2]) * (pt[i+1]-pt[i-1]) + pt[i-1] + 0.5; + for (s=i=0; i < sizeof src; i+=2) + FORC(256 >> src[i]) + huff[0][s++] = src[i] << 8 | (uchar) src[i+1]; + s = kodak_cbpp == 243 ? 2 : 3; + FORC(256) huff[18][c] = (8-s) << 8 | c >> s << s | 1 << (s-1); + getbits(-1); + for (i=0; i < sizeof(buf)/sizeof(short); i++) + buf[0][0][i] = 2048; + for (row=0; row < height; row+=4) { + FORC3 mul[c] = getbits(6); + FORC3 { + val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c]; + s = val > 65564 ? 10:12; + x = ~(-1 << (s-1)); + val <<= 12-s; + for (i=0; i < sizeof(buf[0])/sizeof(short); i++) + buf[c][0][i] = (buf[c][0][i] * val + x) >> s; + last[c] = mul[c]; + for (r=0; r <= !c; r++) { + buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7; + for (tree=1, col=width/2; col > 0; ) { + if ((tree = radc_token(tree))) { + col -= 2; + if (tree == 8) + FORYX buf[c][y][x] = (uchar) radc_token(18) * mul[c]; + else + FORYX buf[c][y][x] = radc_token(tree+10) * 16 + PREDICTOR; + } else + do { + nreps = (col > 2) ? radc_token(9) + 1 : 1; + for (rep=0; rep < 8 && rep < nreps && col > 0; rep++) { + col -= 2; + FORYX buf[c][y][x] = PREDICTOR; + if (rep & 1) { + step = radc_token(10) << 4; + FORYX buf[c][y][x] += step; + } + } + } while (nreps == 9); + } + for (y=0; y < 2; y++) + for (x=0; x < width/2; x++) { + val = (buf[c][y+1][x] << 4) / mul[c]; + if (val < 0) val = 0; + if (c) BAYER(row+y*2+c-1,x*2+2-c) = val; + else BAYER(row+r*2+y,x*2+y) = val; + } + memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c); + } + } + for (y=row; y < row+4; y++) + for (x=0; x < width; x++) + if ((x+y) & 1) { + r = x ? x-1 : x+1; + s = x+1 < width ? x+1 : x-1; + val = (BAYER(y,x)-2048)*2 + (BAYER(y,r)+BAYER(y,s))/2; + if (val < 0) val = 0; + BAYER(y,x) = val; + } + } + for (i=0; i < iheight*iwidth*4; i++) + image[0][i] = curve[image[0][i]]; + maximum = 0x3fff; +} + +#undef FORYX +#undef PREDICTOR + +#ifdef NO_JPEG +void CLASS kodak_jpeg_load_raw() {} +#else + +METHODDEF(boolean) +fill_input_buffer (j_decompress_ptr cinfo) +{ + static uchar jpeg_buffer[4096]; + size_t nbytes; + + nbytes = fread (jpeg_buffer, 1, 4096, ifp); + swab ((char*)jpeg_buffer, (char*)jpeg_buffer, nbytes); + cinfo->src->next_input_byte = jpeg_buffer; + cinfo->src->bytes_in_buffer = nbytes; + return TRUE; +} + +void CLASS kodak_jpeg_load_raw() +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + JSAMPARRAY buf; + JSAMPLE (*pixel)[3]; + int row, col; + + cinfo.err = jpeg_std_error (&jerr); + jpeg_create_decompress (&cinfo); + jpeg_stdio_src (&cinfo, ifp); + cinfo.src->fill_input_buffer = fill_input_buffer; + jpeg_read_header (&cinfo, TRUE); + jpeg_start_decompress (&cinfo); + if ((cinfo.output_width != width ) || + (cinfo.output_height*2 != height ) || + (cinfo.output_components != 3 )) { + fprintf (stderr,_("%s: incorrect JPEG dimensions\n"), ifname); + jpeg_destroy_decompress (&cinfo); + longjmp (failure, 3); + } + buf = (*cinfo.mem->alloc_sarray) + ((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1); + + while (cinfo.output_scanline < cinfo.output_height) { + row = cinfo.output_scanline * 2; + jpeg_read_scanlines (&cinfo, buf, 1); + pixel = (JSAMPLE (*)[3]) buf[0]; + for (col=0; col < width; col+=2) { + BAYER(row+0,col+0) = pixel[col+0][1] << 1; + BAYER(row+1,col+1) = pixel[col+1][1] << 1; + BAYER(row+0,col+1) = pixel[col][0] + pixel[col+1][0]; + BAYER(row+1,col+0) = pixel[col][2] + pixel[col+1][2]; + } + } + jpeg_finish_decompress (&cinfo); + jpeg_destroy_decompress (&cinfo); + maximum = 0xff << 1; +} +#endif + +void CLASS kodak_dc120_load_raw() +{ + static const int mul[4] = { 162, 192, 187, 92 }; + static const int add[4] = { 0, 636, 424, 212 }; + uchar pixel[848]; + int row, shift, col; + + for (row=0; row < height; row++) { + if (fread (pixel, 1, 848, ifp) < 848) derror(); + shift = row * mul[row & 3] + add[row & 3]; + for (col=0; col < width; col++) + BAYER(row,col) = (ushort) pixel[(col + shift) % 848]; + } + maximum = 0xff; +} + +void CLASS eight_bit_load_raw() +{ + uchar *pixel; + unsigned row, col, val, lblack=0; + + pixel = (uchar *) calloc (raw_width, sizeof *pixel); + merror (pixel, "eight_bit_load_raw()"); + fseek (ifp, top_margin*raw_width, SEEK_CUR); + for (row=0; row < height; row++) { + if (fread (pixel, 1, raw_width, ifp) < raw_width) derror(); + for (col=0; col < raw_width; col++) { + val = curve[pixel[col]]; + if ((unsigned) (col-left_margin) < width) + BAYER(row,col-left_margin) = val; + else lblack += val; + } + } + free (pixel); + if (raw_width > width+1) + black = lblack / ((raw_width - width) * height); + if (!strncmp(model,"DC2",3)) + black = 0; + maximum = curve[0xff]; +} + +void CLASS kodak_yrgb_load_raw() +{ + uchar *pixel; + int row, col, y, cb, cr, rgb[3], c; + + pixel = (uchar *) calloc (raw_width, 3*sizeof *pixel); + merror (pixel, "kodak_yrgb_load_raw()"); + for (row=0; row < height; row++) { + if (~row & 1) + if (fread (pixel, raw_width, 3, ifp) < 3) derror(); + for (col=0; col < raw_width; col++) { + y = pixel[width*2*(row & 1) + col]; + cb = pixel[width + (col & -2)] - 128; + cr = pixel[width + (col & -2)+1] - 128; + rgb[1] = y-((cb + cr + 2) >> 2); + rgb[2] = rgb[1] + cb; + rgb[0] = rgb[1] + cr; + FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)]; + } + } + free (pixel); + maximum = curve[0xff]; +} + +void CLASS kodak_262_load_raw() +{ + static const uchar kodak_tree[2][26] = + { { 0,1,5,1,1,2,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9 }, + { 0,3,1,1,1,1,1,2,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9 } }; + ushort *huff[2]; + uchar *pixel; + int *strip, ns, c, row, col, chess, pi=0, pi1, pi2, pred, val; + + FORC(2) huff[c] = make_decoder (kodak_tree[c]); + ns = (raw_height+63) >> 5; + pixel = (uchar *) malloc (raw_width*32 + ns*4); + merror (pixel, "kodak_262_load_raw()"); + strip = (int *) (pixel + raw_width*32); + order = 0x4d4d; + FORC(ns) strip[c] = get4(); + for (row=0; row < raw_height; row++) { + if ((row & 31) == 0) { + fseek (ifp, strip[row >> 5], SEEK_SET); + getbits(-1); + pi = 0; + } + for (col=0; col < raw_width; col++) { + chess = (row + col) & 1; + pi1 = chess ? pi-2 : pi-raw_width-1; + pi2 = chess ? pi-2*raw_width : pi-raw_width+1; + if (col <= chess) pi1 = -1; + if (pi1 < 0) pi1 = pi2; + if (pi2 < 0) pi2 = pi1; + if (pi1 < 0 && col > 1) pi1 = pi2 = pi-2; + pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1; + pixel[pi] = val = pred + ljpeg_diff (huff[chess]); + if (val >> 8) derror(); + val = curve[pixel[pi++]]; + if ((unsigned) (col-left_margin) < width) + BAYER(row,col-left_margin) = val; + else black += val; + } + } + free (pixel); + FORC(2) free (huff[c]); + if (raw_width > width) + black /= (raw_width - width) * height; +} + +int CLASS kodak_65000_decode (short *out, int bsize) +{ + uchar c, blen[768]; + ushort raw[6]; + INT64 bitbuf=0; + int save, bits=0, i, j, len, diff; + + save = ftell(ifp); + bsize = (bsize + 3) & -4; + for (i=0; i < bsize; i+=2) { + c = fgetc(ifp); + if ((blen[i ] = c & 15) > 12 || + (blen[i+1] = c >> 4) > 12 ) { + fseek (ifp, save, SEEK_SET); + for (i=0; i < bsize; i+=8) { + read_shorts (raw, 6); + out[i ] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12; + out[i+1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12; + for (j=0; j < 6; j++) + out[i+2+j] = raw[j] & 0xfff; + } + return 1; + } + } + if ((bsize & 7) == 4) { + bitbuf = fgetc(ifp) << 8; + bitbuf += fgetc(ifp); + bits = 16; + } + for (i=0; i < bsize; i++) { + len = blen[i]; + if (bits < len) { + for (j=0; j < 32; j+=8) + bitbuf += (INT64) fgetc(ifp) << (bits+(j^8)); + bits += 32; + } + diff = bitbuf & (0xffff >> (16-len)); + bitbuf >>= len; + bits -= len; + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + out[i] = diff; + } + return 0; +} + +void CLASS kodak_65000_load_raw() +{ + short buf[256]; + int row, col, len, pred[2], ret, i; + + for (row=0; row < height; row++) + for (col=0; col < width; col+=256) { + pred[0] = pred[1] = 0; + len = MIN (256, width-col); + ret = kodak_65000_decode (buf, len); + for (i=0; i < len; i++) + if ((BAYER(row,col+i) = curve[ret ? buf[i] : + (pred[i & 1] += buf[i])]) >> 12) derror(); + } +} + +void CLASS kodak_ycbcr_load_raw() +{ + short buf[384], *bp; + int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3]; + ushort *ip; + + for (row=0; row < height; row+=2) + for (col=0; col < width; col+=128) { + len = MIN (128, width-col); + kodak_65000_decode (buf, len*3); + y[0][1] = y[1][1] = cb = cr = 0; + for (bp=buf, i=0; i < len; i+=2, bp+=2) { + cb += bp[4]; + cr += bp[5]; + rgb[1] = -((cb + cr + 2) >> 2); + rgb[2] = rgb[1] + cb; + rgb[0] = rgb[1] + cr; + for (j=0; j < 2; j++) + for (k=0; k < 2; k++) { + if ((y[j][k] = y[j][k^1] + *bp++) >> 10) derror(); + ip = image[(row+j)*width + col+i+k]; + FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)]; + } + } + } +} + +void CLASS kodak_rgb_load_raw() +{ + short buf[768], *bp; + int row, col, len, c, i, rgb[3]; + ushort *ip=image[0]; + + for (row=0; row < height; row++) + for (col=0; col < width; col+=256) { + len = MIN (256, width-col); + kodak_65000_decode (buf, len*3); + memset (rgb, 0, sizeof rgb); + for (bp=buf, i=0; i < len; i++, ip+=4) + FORC3 if ((ip[c] = rgb[c] += *bp++) >> 12) derror(); + } +} + +void CLASS kodak_thumb_load_raw() +{ + int row, col; + colors = thumb_misc >> 5; + for (row=0; row < height; row++) + for (col=0; col < width; col++) + read_shorts (image[row*width+col], colors); + maximum = (1 << (thumb_misc & 31)) - 1; +} + +void CLASS sony_decrypt (unsigned *data, int len, int start, int key) +{ + static unsigned pad[128], p; + + if (start) { + for (p=0; p < 4; p++) + pad[p] = key = key * 48828125 + 1; + pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31; + for (p=4; p < 127; p++) + pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31; + for (p=0; p < 127; p++) + pad[p] = htonl(pad[p]); + } + while (len--) + *data++ ^= pad[p++ & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127]; +} + +void CLASS sony_load_raw() +{ + uchar head[40]; + ushort *pixel; + unsigned i, key, row, col; + + fseek (ifp, 200896, SEEK_SET); + fseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR); + order = 0x4d4d; + key = get4(); + fseek (ifp, 164600, SEEK_SET); + fread (head, 1, 40, ifp); + sony_decrypt ((unsigned int *) head, 10, 1, key); + for (i=26; i-- > 22; ) + key = key << 8 | head[i]; + fseek (ifp, data_offset, SEEK_SET); + pixel = (ushort *) calloc (raw_width, sizeof *pixel); + merror (pixel, "sony_load_raw()"); + for (row=0; row < height; row++) { + if (fread (pixel, 2, raw_width, ifp) < raw_width) derror(); + sony_decrypt ((unsigned int *) pixel, raw_width/2, !row, key); + for (col=9; col < left_margin; col++) + black += ntohs(pixel[col]); + for (col=0; col < width; col++) + if ((BAYER(row,col) = ntohs(pixel[col+left_margin])) >> 14) + derror(); + } + free (pixel); + if (left_margin > 9) + black /= (left_margin-9) * height; + maximum = 0x3ff0; +} + +void CLASS sony_arw_load_raw() +{ + ushort huff[32768]; + static const ushort tab[18] = + { 0xf11,0xf10,0xe0f,0xd0e,0xc0d,0xb0c,0xa0b,0x90a,0x809, + 0x708,0x607,0x506,0x405,0x304,0x303,0x300,0x202,0x201 }; + int i, c, n, col, row, len, diff, sum=0; + + for (n=i=0; i < 18; i++) + FORC(32768 >> (tab[i] >> 8)) huff[n++] = tab[i]; + getbits(-1); + for (col = raw_width; col--; ) + for (row=0; row < raw_height+1; row+=2) { + if (row == raw_height) row = 1; + len = getbithuff(15,huff); + diff = getbits(len); + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + if ((sum += diff) >> 12) derror(); + if (row < height) BAYER(row,col) = sum; + } +} + +void CLASS sony_arw2_load_raw() +{ + uchar *data, *dp; + ushort pix[16]; + int row, col, val, max, min, imax, imin, sh, bit, i; + + data = (uchar *) malloc (raw_width); + merror (data, "sony_arw2_load_raw()"); + for (row=0; row < height; row++) { + fread (data, 1, raw_width, ifp); + for (dp=data, col=0; col < width-30; dp+=16) { + max = 0x7ff & (val = sget4(dp)); + min = 0x7ff & val >> 11; + imax = 0x0f & val >> 22; + imin = 0x0f & val >> 26; + for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++); + for (bit=30, i=0; i < 16; i++) + if (i == imax) pix[i] = max; + else if (i == imin) pix[i] = min; + else { + pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min; + if (pix[i] > 0x7ff) pix[i] = 0x7ff; + bit += 7; + } + for (i=0; i < 16; i++, col+=2) + BAYER(row,col) = curve[pix[i] << 1] >> 1; + col -= col & 1 ? 1:31; + } + } + free (data); +} + +#define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1) + +/* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */ +void CLASS smal_decode_segment (unsigned seg[2][2], int holes) +{ + uchar hist[3][13] = { + { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 }, + { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 }, + { 3, 3, 0, 0, 63, 47, 31, 15, 0 } }; + int low, high=0xff, carry=0, nbits=8; + int s, count, bin, next, i, sym[3]; + uchar diff, pred[]={0,0}; + ushort data=0, range=0; + unsigned pix, row, col; + + fseek (ifp, seg[0][1]+1, SEEK_SET); + getbits(-1); + for (pix=seg[0][0]; pix < seg[1][0]; pix++) { + for (s=0; s < 3; s++) { + data = data << nbits | getbits(nbits); + if (carry < 0) + carry = (nbits += carry+1) < 1 ? nbits-1 : 0; + while (--nbits >= 0) + if ((data >> nbits & 0xff) == 0xff) break; + if (nbits > 0) + data = ((data & ((1 << (nbits-1)) - 1)) << 1) | + ((data + (((data & (1 << (nbits-1)))) << 1)) & (-1 << nbits)); + if (nbits >= 0) { + data += getbits(1); + carry = nbits - 8; + } + count = ((((data-range+1) & 0xffff) << 2) - 1) / (high >> 4); + for (bin=0; hist[s][bin+5] > count; bin++); + low = hist[s][bin+5] * (high >> 4) >> 2; + if (bin) high = hist[s][bin+4] * (high >> 4) >> 2; + high -= low; + for (nbits=0; high << nbits < 128; nbits++); + range = (range+low) << nbits; + high <<= nbits; + next = hist[s][1]; + if (++hist[s][2] > hist[s][3]) { + next = (next+1) & hist[s][0]; + hist[s][3] = (hist[s][next+4] - hist[s][next+5]) >> 2; + hist[s][2] = 1; + } + if (hist[s][hist[s][1]+4] - hist[s][hist[s][1]+5] > 1) { + if (bin < hist[s][1]) + for (i=bin; i < hist[s][1]; i++) hist[s][i+5]--; + else if (next <= bin) + for (i=hist[s][1]; i < bin; i++) hist[s][i+5]++; + } + hist[s][1] = next; + sym[s] = bin; + } + diff = sym[2] << 5 | sym[1] << 2 | (sym[0] & 3); + if (sym[0] & 4) + diff = diff ? -diff : 0x80; + if (ftell(ifp) + 12 >= seg[1][1]) + diff = 0; + pred[pix & 1] += diff; + row = pix / raw_width - top_margin; + col = pix % raw_width - left_margin; + if (row < height && col < width) + BAYER(row,col) = pred[pix & 1]; + if (!(pix & 1) && HOLE(row)) pix += 2; + } + maximum = 0xff; +} + +void CLASS smal_v6_load_raw() +{ + unsigned seg[2][2]; + + fseek (ifp, 16, SEEK_SET); + seg[0][0] = 0; + seg[0][1] = get2(); + seg[1][0] = raw_width * raw_height; + seg[1][1] = INT_MAX; + smal_decode_segment (seg, 0); +} + +int CLASS median4 (int *p) +{ + int min, max, sum, i; + + min = max = sum = p[0]; + for (i=1; i < 4; i++) { + sum += p[i]; + if (min > p[i]) min = p[i]; + if (max < p[i]) max = p[i]; + } + return (sum - min - max) >> 1; +} + +void CLASS fill_holes (int holes) +{ + int row, col, val[4]; + + for (row=2; row < height-2; row++) { + if (!HOLE(row)) continue; + for (col=1; col < width-1; col+=4) { + val[0] = BAYER(row-1,col-1); + val[1] = BAYER(row-1,col+1); + val[2] = BAYER(row+1,col-1); + val[3] = BAYER(row+1,col+1); + BAYER(row,col) = median4(val); + } + for (col=2; col < width-2; col+=4) + if (HOLE(row-2) || HOLE(row+2)) + BAYER(row,col) = (BAYER(row,col-2) + BAYER(row,col+2)) >> 1; + else { + val[0] = BAYER(row,col-2); + val[1] = BAYER(row,col+2); + val[2] = BAYER(row-2,col); + val[3] = BAYER(row+2,col); + BAYER(row,col) = median4(val); + } + } +} + +void CLASS smal_v9_load_raw() +{ + unsigned seg[256][2], offset, nseg, holes, i; + + fseek (ifp, 67, SEEK_SET); + offset = get4(); + nseg = fgetc(ifp); + fseek (ifp, offset, SEEK_SET); + for (i=0; i < nseg*2; i++) + seg[0][i] = get4() + data_offset*(i & 1); + fseek (ifp, 78, SEEK_SET); + holes = fgetc(ifp); + fseek (ifp, 88, SEEK_SET); + seg[nseg][0] = raw_height * raw_width; + seg[nseg][1] = get4() + data_offset; + for (i=0; i < nseg; i++) + smal_decode_segment (seg+i, holes); + if (holes) fill_holes (holes); +} + +/* RESTRICTED code starts here */ + +void CLASS foveon_decoder (unsigned size, unsigned code) +{ + static unsigned huff[1024]; + struct decode *cur; + int i, len; + + if (!code) { + for (i=0; i < size; i++) + huff[i] = get4(); + memset (first_decode, 0, sizeof first_decode); + free_decode = first_decode; + } + cur = free_decode++; + if (free_decode > first_decode+2048) { + fprintf (stderr,_("%s: decoder table overflow\n"), ifname); + longjmp (failure, 2); + } + if (code) + for (i=0; i < size; i++) + if (huff[i] == code) { + cur->leaf = i; + return; + } + if ((len = code >> 27) > 26) return; + code = (len+1) << 27 | (code & 0x3ffffff) << 1; + + cur->branch[0] = free_decode; + foveon_decoder (size, code); + cur->branch[1] = free_decode; + foveon_decoder (size, code+1); +} + +void CLASS foveon_thumb() +{ + unsigned bwide, row, col, bitbuf=0, bit=1, c, i; + char *buf; + struct decode *dindex; + short pred[3]; + + bwide = get4(); + fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); + if (bwide > 0) { + if (bwide < thumb_width*3) return; + buf = (char *) malloc (bwide); + merror (buf, "foveon_thumb()"); + for (row=0; row < thumb_height; row++) { + fread (buf, 1, bwide, ifp); + fwrite (buf, 3, thumb_width, ofp); + } + free (buf); + return; + } + foveon_decoder (256, 0); + + for (row=0; row < thumb_height; row++) { + memset (pred, 0, sizeof pred); + if (!bit) get4(); + for (bit=col=0; col < thumb_width; col++) + FORC3 { + for (dindex=first_decode; dindex->branch[0]; ) { + if ((bit = (bit-1) & 31) == 31) + for (i=0; i < 4; i++) + bitbuf = (bitbuf << 8) + fgetc(ifp); + dindex = dindex->branch[bitbuf >> bit & 1]; + } + pred[c] += dindex->leaf; + fputc (pred[c], ofp); + } + } +} + +void CLASS foveon_load_camf() +{ + unsigned key, i, val; + + fseek (ifp, meta_offset, SEEK_SET); + key = get4(); + fread (meta_data, 1, meta_length, ifp); + for (i=0; i < meta_length; i++) { + key = (key * 1597 + 51749) % 244944; + val = key * (INT64) 301593171 >> 24; + meta_data[i] ^= ((((key << 8) - val) >> 1) + val) >> 17; + } +} + +void CLASS foveon_load_raw() +{ + struct decode *dindex; + short diff[1024]; + unsigned bitbuf=0; + int pred[3], fixed, row, col, bit=-1, c, i; + + fixed = get4(); + read_shorts ((ushort *) diff, 1024); + if (!fixed) foveon_decoder (1024, 0); + + for (row=0; row < height; row++) { + memset (pred, 0, sizeof pred); + if (!bit && !fixed && atoi(model+2) < 14) get4(); + for (col=bit=0; col < width; col++) { + if (fixed) { + bitbuf = get4(); + FORC3 pred[2-c] += diff[bitbuf >> c*10 & 0x3ff]; + } + else FORC3 { + for (dindex=first_decode; dindex->branch[0]; ) { + if ((bit = (bit-1) & 31) == 31) + for (i=0; i < 4; i++) + bitbuf = (bitbuf << 8) + fgetc(ifp); + dindex = dindex->branch[bitbuf >> bit & 1]; + } + pred[c] += diff[dindex->leaf]; + if (pred[c] >> 16 && ~pred[c] >> 16) derror(); + } + FORC3 image[row*width+col][c] = pred[c]; + } + } + if (document_mode) + for (i=0; i < height*width*4; i++) + if ((short) image[0][i] < 0) image[0][i] = 0; + foveon_load_camf(); +} + +const char * CLASS foveon_camf_param (const char *block, const char *param) +{ + unsigned idx, num; + char *pos, *cp, *dp; + + for (idx=0; idx < meta_length; idx += sget4(pos+8)) { + pos = meta_data + idx; + if (strncmp (pos, "CMb", 3)) break; + if (pos[3] != 'P') continue; + if (strcmp (block, pos+sget4(pos+12))) continue; + cp = pos + sget4(pos+16); + num = sget4(cp); + dp = pos + sget4(cp+4); + while (num--) { + cp += 8; + if (!strcmp (param, dp+sget4(cp))) + return dp+sget4(cp+4); + } + } + return 0; +} + +void * CLASS foveon_camf_matrix (unsigned dim[3], const char *name) +{ + unsigned i, idx, type, ndim, size, *mat; + char *pos, *cp, *dp; + double dsize; + + for (idx=0; idx < meta_length; idx += sget4(pos+8)) { + pos = meta_data + idx; + if (strncmp (pos, "CMb", 3)) break; + if (pos[3] != 'M') continue; + if (strcmp (name, pos+sget4(pos+12))) continue; + dim[0] = dim[1] = dim[2] = 1; + cp = pos + sget4(pos+16); + type = sget4(cp); + if ((ndim = sget4(cp+4)) > 3) break; + dp = pos + sget4(cp+8); + for (i=ndim; i--; ) { + cp += 12; + dim[i] = sget4(cp); + } + if ((dsize = (double) dim[0]*dim[1]*dim[2]) > meta_length/4) break; + mat = (unsigned *) malloc ((size = dsize) * 4); + merror (mat, "foveon_camf_matrix()"); + for (i=0; i < size; i++) + if (type && type != 6) + mat[i] = sget4(dp + i*4); + else + mat[i] = sget4(dp + i*2) & 0xffff; + return mat; + } + fprintf (stderr,_("%s: \"%s\" matrix not found!\n"), ifname, name); + return 0; +} + +int CLASS foveon_fixed (void *ptr, int size, const char *name) +{ + void *dp; + unsigned dim[3]; + + dp = foveon_camf_matrix (dim, name); + if (!dp) return 0; + memcpy (ptr, dp, size*4); + free (dp); + return 1; +} + +float CLASS foveon_avg (short *pix, int range[2], float cfilt) +{ + int i; + float val, min=FLT_MAX, max=-FLT_MAX, sum=0; + + for (i=range[0]; i <= range[1]; i++) { + sum += val = pix[i*4] + (pix[i*4]-pix[(i-1)*4]) * cfilt; + if (min > val) min = val; + if (max < val) max = val; + } + if (range[1] - range[0] == 1) return sum/2; + return (sum - min - max) / (range[1] - range[0] - 1); +} + +short * CLASS foveon_make_curve (double max, double mul, double filt) +{ + short *curve; + unsigned i, size; + double x; + + if (!filt) filt = 0.8; + size = 4*M_PI*max / filt; + if (size == UINT_MAX) size--; + curve = (short *) calloc (size+1, sizeof *curve); + merror (curve, "foveon_make_curve()"); + curve[0] = size; + for (i=0; i < size; i++) { + x = i*filt/max/4; + curve[i+1] = (cos(x)+1)/2 * tanh(i*filt/mul) * mul + 0.5; + } + return curve; +} + +void CLASS foveon_make_curves + (short **curvep, float dq[3], float div[3], float filt) +{ + double mul[3], max=0; + int c; + + FORC3 mul[c] = dq[c]/div[c]; + FORC3 if (max < mul[c]) max = mul[c]; + FORC3 curvep[c] = foveon_make_curve (max, mul[c], filt); +} + +int CLASS foveon_apply_curve (short *curve, int i) +{ + if (abs(i) >= curve[0]) return 0; + return i < 0 ? -curve[1-i] : curve[1+i]; +} + +#define image ((short (*)[4]) image) + +void CLASS foveon_interpolate() +{ + static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 }; + short *pix, prev[3], *curve[8], (*shrink)[3]; + float cfilt=0, ddft[3][3][2], ppm[3][3][3]; + float cam_xyz[3][3], correct[3][3], last[3][3], trans[3][3]; + float chroma_dq[3], color_dq[3], diag[3][3], div[3]; + float (*black)[3], (*sgain)[3], (*sgrow)[3]; + float fsum[3], val, frow, num; + int row, col, c, i, j, diff, sgx, irow, sum, min, max, limit; + int dscr[2][2], dstb[4], (*smrow[7])[3], total[4], ipix[3]; + int work[3][3], smlast, smred, smred_p=0, dev[3]; + int satlev[3], keep[4], active[4]; + unsigned dim[3], *badpix; + double dsum=0, trsum[3]; + char str[128]; + const char* cp; + + if (verbose) + fprintf (stderr,_("Foveon interpolation...\n")); + + foveon_fixed (dscr, 4, "DarkShieldColRange"); + foveon_fixed (ppm[0][0], 27, "PostPolyMatrix"); + foveon_fixed (satlev, 3, "SaturationLevel"); + foveon_fixed (keep, 4, "KeepImageArea"); + foveon_fixed (active, 4, "ActiveImageArea"); + foveon_fixed (chroma_dq, 3, "ChromaDQ"); + foveon_fixed (color_dq, 3, + foveon_camf_param ("IncludeBlocks", "ColorDQ") ? + "ColorDQ" : "ColorDQCamRGB"); + if (foveon_camf_param ("IncludeBlocks", "ColumnFilter")) + foveon_fixed (&cfilt, 1, "ColumnFilter"); + + memset (ddft, 0, sizeof ddft); + if (!foveon_camf_param ("IncludeBlocks", "DarkDrift") + || !foveon_fixed (ddft[1][0], 12, "DarkDrift")) + for (i=0; i < 2; i++) { + foveon_fixed (dstb, 4, i ? "DarkShieldBottom":"DarkShieldTop"); + for (row = dstb[1]; row <= dstb[3]; row++) + for (col = dstb[0]; col <= dstb[2]; col++) + FORC3 ddft[i+1][c][1] += (short) image[row*width+col][c]; + FORC3 ddft[i+1][c][1] /= (dstb[3]-dstb[1]+1) * (dstb[2]-dstb[0]+1); + } + + if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2))) + { fprintf (stderr,_("%s: Invalid white balance \"%s\"\n"), ifname, model2); + return; } + foveon_fixed (cam_xyz, 9, cp); + foveon_fixed (correct, 9, + foveon_camf_param ("WhiteBalanceCorrections", model2)); + memset (last, 0, sizeof last); + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + FORC3 last[i][j] += correct[i][c] * cam_xyz[c][j]; + + #define LAST(x,y) last[(i+x)%3][(c+y)%3] + for (i=0; i < 3; i++) + FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1); + #undef LAST + FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583; + sprintf (str, "%sRGBNeutral", model2); + if (foveon_camf_param ("IncludeBlocks", str)) + foveon_fixed (div, 3, str); + num = 0; + FORC3 if (num < div[c]) num = div[c]; + FORC3 div[c] /= num; + + memset (trans, 0, sizeof trans); + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + FORC3 trans[i][j] += rgb_cam[i][c] * last[c][j] * div[j]; + FORC3 trsum[c] = trans[c][0] + trans[c][1] + trans[c][2]; + dsum = (6*trsum[0] + 11*trsum[1] + 3*trsum[2]) / 20; + for (i=0; i < 3; i++) + FORC3 last[i][c] = trans[i][c] * dsum / trsum[i]; + memset (trans, 0, sizeof trans); + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + FORC3 trans[i][j] += (i==c ? 32 : -1) * last[c][j] / 30; + + foveon_make_curves (curve, color_dq, div, cfilt); + FORC3 chroma_dq[c] /= 3; + foveon_make_curves (curve+3, chroma_dq, div, cfilt); + FORC3 dsum += chroma_dq[c] / div[c]; + curve[6] = foveon_make_curve (dsum, dsum, cfilt); + curve[7] = foveon_make_curve (dsum*2, dsum*2, cfilt); + + sgain = (float (*)[3]) foveon_camf_matrix (dim, "SpatialGain"); + if (!sgain) return; + sgrow = (float (*)[3]) calloc (dim[1], sizeof *sgrow); + sgx = (width + dim[1]-2) / (dim[1]-1); + + black = (float (*)[3]) calloc (height, sizeof *black); + for (row=0; row < height; row++) { + for (i=0; i < 6; i++) + ddft[0][0][i] = ddft[1][0][i] + + row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][i]); + FORC3 black[row][c] = + ( foveon_avg (image[row*width]+c, dscr[0], cfilt) + + foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3 + - ddft[0][c][0] ) / 4 - ddft[0][c][1]; + } + memcpy (black, black+8, sizeof *black*8); + memcpy (black+height-11, black+height-22, 11*sizeof *black); + memcpy (last, black, sizeof last); + + for (row=1; row < height-1; row++) { + FORC3 if (last[1][c] > last[0][c]) { + if (last[1][c] > last[2][c]) + black[row][c] = (last[0][c] > last[2][c]) ? last[0][c]:last[2][c]; + } else + if (last[1][c] < last[2][c]) + black[row][c] = (last[0][c] < last[2][c]) ? last[0][c]:last[2][c]; + memmove (last, last+1, 2*sizeof last[0]); + memcpy (last[2], black[row+1], sizeof last[2]); + } + FORC3 black[row][c] = (last[0][c] + last[1][c])/2; + FORC3 black[0][c] = (black[1][c] + black[3][c])/2; + + val = 1 - exp(-1/24.0); + memcpy (fsum, black, sizeof fsum); + for (row=1; row < height; row++) + FORC3 fsum[c] += black[row][c] = + (black[row][c] - black[row-1][c])*val + black[row-1][c]; + memcpy (last[0], black[height-1], sizeof last[0]); + FORC3 fsum[c] /= height; + for (row = height; row--; ) + FORC3 last[0][c] = black[row][c] = + (black[row][c] - fsum[c] - last[0][c])*val + last[0][c]; + + memset (total, 0, sizeof total); + for (row=2; row < height; row+=4) + for (col=2; col < width; col+=4) { + FORC3 total[c] += (short) image[row*width+col][c]; + total[3]++; + } + for (row=0; row < height; row++) + FORC3 black[row][c] += fsum[c]/2 + total[c]/(total[3]*100.0); + + for (row=0; row < height; row++) { + for (i=0; i < 6; i++) + ddft[0][0][i] = ddft[1][0][i] + + row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][i]); + pix = image[row*width]; + memcpy (prev, pix, sizeof prev); + frow = row / (height-1.0) * (dim[2]-1); + if ((irow = frow) == dim[2]-1) irow--; + frow -= irow; + for (i=0; i < dim[1]; i++) + FORC3 sgrow[i][c] = sgain[ irow *dim[1]+i][c] * (1-frow) + + sgain[(irow+1)*dim[1]+i][c] * frow; + for (col=0; col < width; col++) { + FORC3 { + diff = pix[c] - prev[c]; + prev[c] = pix[c]; + ipix[c] = pix[c] + floor ((diff + (diff*diff >> 14)) * cfilt + - ddft[0][c][1] - ddft[0][c][0] * ((float) col/width - 0.5) + - black[row][c] ); + } + FORC3 { + work[0][c] = ipix[c] * ipix[c] >> 14; + work[2][c] = ipix[c] * work[0][c] >> 14; + work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14; + } + FORC3 { + for (val=i=0; i < 3; i++) + for ( j=0; j < 3; j++) + val += ppm[c][i][j] * work[i][j]; + ipix[c] = floor ((ipix[c] + floor(val)) * + ( sgrow[col/sgx ][c] * (sgx - col%sgx) + + sgrow[col/sgx+1][c] * (col%sgx) ) / sgx / div[c]); + if (ipix[c] > 32000) ipix[c] = 32000; + pix[c] = ipix[c]; + } + pix += 4; + } + } + free (black); + free (sgrow); + free (sgain); + + if ((badpix = (unsigned int *) foveon_camf_matrix (dim, "BadPixels"))) { + for (i=0; i < dim[0]; i++) { + col = (badpix[i] >> 8 & 0xfff) - keep[0]; + row = (badpix[i] >> 20 ) - keep[1]; + if ((unsigned)(row-1) > height-3 || (unsigned)(col-1) > width-3) + continue; + memset (fsum, 0, sizeof fsum); + for (sum=j=0; j < 8; j++) + if (badpix[i] & (1 << j)) { + FORC3 fsum[c] += (short) + image[(row+hood[j*2])*width+col+hood[j*2+1]][c]; + sum++; + } + if (sum) FORC3 image[row*width+col][c] = fsum[c]/sum; + } + free (badpix); + } + + /* Array for 5x5 Gaussian averaging of red values */ + smrow[6] = (int (*)[3]) calloc (width*5, sizeof **smrow); + merror (smrow[6], "foveon_interpolate()"); + for (i=0; i < 5; i++) + smrow[i] = smrow[6] + i*width; + + /* Sharpen the reds against these Gaussian averages */ + for (smlast=-1, row=2; row < height-2; row++) { + while (smlast < row+2) { + for (i=0; i < 6; i++) + smrow[(i+5) % 6] = smrow[i]; + pix = image[++smlast*width+2]; + for (col=2; col < width-2; col++) { + smrow[4][col][0] = + (pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4; + pix += 4; + } + } + pix = image[row*width+2]; + for (col=2; col < width-2; col++) { + smred = ( 6 * smrow[2][col][0] + + 4 * (smrow[1][col][0] + smrow[3][col][0]) + + smrow[0][col][0] + smrow[4][col][0] + 8 ) >> 4; + if (col == 2) + smred_p = smred; + i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 3); + if (i > 32000) i = 32000; + pix[0] = i; + smred_p = smred; + pix += 4; + } + } + + /* Adjust the brighter pixels for better linearity */ + min = 0xffff; + FORC3 { + i = satlev[c] / div[c]; + if (min > i) min = i; + } + limit = min * 9 >> 4; + for (pix=image[0]; pix < image[height*width]; pix+=4) { + if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit) + continue; + min = max = pix[0]; + for (c=1; c < 3; c++) { + if (min > pix[c]) min = pix[c]; + if (max < pix[c]) max = pix[c]; + } + if (min >= limit*2) { + pix[0] = pix[1] = pix[2] = max; + } else { + i = 0x4000 - ((min - limit) << 14) / limit; + i = 0x4000 - (i*i >> 14); + i = i*i >> 14; + FORC3 pix[c] += (max - pix[c]) * i >> 14; + } + } +/* + Because photons that miss one detector often hit another, + the sum R+G+B is much less noisy than the individual colors. + So smooth the hues without smoothing the total. + */ + for (smlast=-1, row=2; row < height-2; row++) { + while (smlast < row+2) { + for (i=0; i < 6; i++) + smrow[(i+5) % 6] = smrow[i]; + pix = image[++smlast*width+2]; + for (col=2; col < width-2; col++) { + FORC3 smrow[4][col][c] = (pix[c-4]+2*pix[c]+pix[c+4]+2) >> 2; + pix += 4; + } + } + pix = image[row*width+2]; + for (col=2; col < width-2; col++) { + FORC3 dev[c] = -foveon_apply_curve (curve[7], pix[c] - + ((smrow[1][col][c] + 2*smrow[2][col][c] + smrow[3][col][c]) >> 2)); + sum = (dev[0] + dev[1] + dev[2]) >> 3; + FORC3 pix[c] += dev[c] - sum; + pix += 4; + } + } + for (smlast=-1, row=2; row < height-2; row++) { + while (smlast < row+2) { + for (i=0; i < 6; i++) + smrow[(i+5) % 6] = smrow[i]; + pix = image[++smlast*width+2]; + for (col=2; col < width-2; col++) { + FORC3 smrow[4][col][c] = + (pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8]+2) >> 2; + pix += 4; + } + } + pix = image[row*width+2]; + for (col=2; col < width-2; col++) { + for (total[3]=375, sum=60, c=0; c < 3; c++) { + for (total[c]=i=0; i < 5; i++) + total[c] += smrow[i][col][c]; + total[3] += total[c]; + sum += pix[c]; + } + if (sum < 0) sum = 0; + j = total[3] > 375 ? (sum << 16) / total[3] : sum * 174; + FORC3 pix[c] += foveon_apply_curve (curve[6], + ((j*total[c] + 0x8000) >> 16) - pix[c]); + pix += 4; + } + } + + /* Transform the image to a different colorspace */ + for (pix=image[0]; pix < image[height*width]; pix+=4) { + FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]); + sum = (pix[0]+pix[1]+pix[1]+pix[2]) >> 2; + FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]-sum); + FORC3 { + for (dsum=i=0; i < 3; i++) + dsum += trans[c][i] * pix[i]; + if (dsum < 0) dsum = 0; + if (dsum > 24000) dsum = 24000; + ipix[c] = dsum + 0.5; + } + FORC3 pix[c] = ipix[c]; + } + + /* Smooth the image bottom-to-top and save at 1/4 scale */ + shrink = (short (*)[3]) calloc ((width/4) * (height/4), sizeof *shrink); + merror (shrink, "foveon_interpolate()"); + for (row = height/4; row--; ) + for (col=0; col < width/4; col++) { + ipix[0] = ipix[1] = ipix[2] = 0; + for (i=0; i < 4; i++) + for (j=0; j < 4; j++) + FORC3 ipix[c] += image[(row*4+i)*width+col*4+j][c]; + FORC3 + if (row+2 > height/4) + shrink[row*(width/4)+col][c] = ipix[c] >> 4; + else + shrink[row*(width/4)+col][c] = + (shrink[(row+1)*(width/4)+col][c]*1840 + ipix[c]*141 + 2048) >> 12; + } + /* From the 1/4-scale image, smooth right-to-left */ + for (row=0; row < (height & ~3); row++) { + ipix[0] = ipix[1] = ipix[2] = 0; + if ((row & 3) == 0) + for (col = width & ~3 ; col--; ) + FORC3 smrow[0][col][c] = ipix[c] = + (shrink[(row/4)*(width/4)+col/4][c]*1485 + ipix[c]*6707 + 4096) >> 13; + + /* Then smooth left-to-right */ + ipix[0] = ipix[1] = ipix[2] = 0; + for (col=0; col < (width & ~3); col++) + FORC3 smrow[1][col][c] = ipix[c] = + (smrow[0][col][c]*1485 + ipix[c]*6707 + 4096) >> 13; + + /* Smooth top-to-bottom */ + if (row == 0) + memcpy (smrow[2], smrow[1], sizeof **smrow * width); + else + for (col=0; col < (width & ~3); col++) + FORC3 smrow[2][col][c] = + (smrow[2][col][c]*6707 + smrow[1][col][c]*1485 + 4096) >> 13; + + /* Adjust the chroma toward the smooth values */ + for (col=0; col < (width & ~3); col++) { + for (i=j=30, c=0; c < 3; c++) { + i += smrow[2][col][c]; + j += image[row*width+col][c]; + } + j = (j << 16) / i; + for (sum=c=0; c < 3; c++) { + ipix[c] = foveon_apply_curve (curve[c+3], + ((smrow[2][col][c] * j + 0x8000) >> 16) - image[row*width+col][c]); + sum += ipix[c]; + } + sum >>= 3; + FORC3 { + i = image[row*width+col][c] + ipix[c] - sum; + if (i < 0) i = 0; + image[row*width+col][c] = i; + } + } + } + free (shrink); + free (smrow[6]); + for (i=0; i < 8; i++) + free (curve[i]); + + /* Trim off the black border */ + active[1] -= keep[1]; + active[3] -= 2; + i = active[2] - active[0]; + for (row=0; row < active[3]-active[1]; row++) + memcpy (image[row*i], image[(row+active[1])*width+active[0]], + i * sizeof *image); + width = i; + height = row; +} +#undef image + +/* RESTRICTED code ends here */ + +/* + Seach from the current directory up to the root looking for + a ".badpixels" file, and fix those pixels now. + */ +void CLASS bad_pixels (const char *cfname) +{ + FILE *fp=0; + char *fname, *cp, line[128]; + int len, time, row, col, r, c, rad, tot, n, fixed=0; + + if (!filters) return; + if (cfname) + fp = fopen (cfname, "r"); + else { + for (len=32 ; ; len *= 2) { + fname = (char *) malloc (len); + if (!fname) return; + if (getcwd (fname, len-16)) break; + free (fname); + if (errno != ERANGE) return; + } +#if defined(WIN32) || defined(DJGPP) + if (fname[1] == ':') + memmove (fname, fname+2, len-2); + for (cp=fname; *cp; cp++) + if (*cp == '\\') *cp = '/'; +#endif + cp = fname + strlen(fname); + if (cp[-1] == '/') cp--; + while (*fname == '/') { + strcpy (cp, "/.badpixels"); + if ((fp = fopen (fname, "r"))) break; + if (cp == fname) break; + while (*--cp != '/'); + } + free (fname); + } + if (!fp) return; + while (fgets (line, 128, fp)) { + cp = strchr (line, '#'); + if (cp) *cp = 0; + if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue; + if ((unsigned) col >= width || (unsigned) row >= height) continue; + if (time > timestamp) continue; + for (tot=n=0, rad=1; rad < 3 && n==0; rad++) + for (r = row-rad; r <= row+rad; r++) + for (c = col-rad; c <= col+rad; c++) + if ((unsigned) r < height && (unsigned) c < width && + (r != row || c != col) && fc(r,c) == fc(row,col)) { + tot += BAYER2(r,c); + n++; + } + BAYER2(row,col) = tot/n; + if (verbose) { + if (!fixed++) + fprintf (stderr,_("Fixed dead pixels at:")); + fprintf (stderr, " %d,%d", col, row); + } + } + if (fixed) fputc ('\n', stderr); + fclose (fp); +} + +void CLASS subtract (const char *fname) +{ + FILE *fp; + int dim[3]={0,0,0}, comment=0, number=0, error=0, nd=0, c, row, col; + ushort *pixel; + + if (!(fp = fopen (fname, "rb"))) { + perror (fname); return; + } + if (fgetc(fp) != 'P' || fgetc(fp) != '5') error = 1; + while (!error && nd < 3 && (c = fgetc(fp)) != EOF) { + if (c == '#') comment = 1; + if (c == '\n') comment = 0; + if (comment) continue; + if (isdigit(c)) number = 1; + if (number) { + if (isdigit(c)) dim[nd] = dim[nd]*10 + c -'0'; + else if (isspace(c)) { + number = 0; nd++; + } else error = 1; + } + } + if (error || nd < 3) { + fprintf (stderr,_("%s is not a valid PGM file!\n"), fname); + fclose (fp); return; + } else if (dim[0] != width || dim[1] != height || dim[2] != 65535) { + fprintf (stderr,_("%s has the wrong dimensions!\n"), fname); + fclose (fp); return; + } + pixel = (ushort *) calloc (width, sizeof *pixel); + merror (pixel, "subtract()"); + for (row=0; row < height; row++) { + fread (pixel, 2, width, fp); + for (col=0; col < width; col++) + BAYER(row,col) = MAX (BAYER(row,col) - ntohs(pixel[col]), 0); + } + free (pixel); + black = 0; +} + +void CLASS gamma_curve (double pwr, double ts, int mode, int imax) +{ + int i; + double g[6], bnd[2]={0,0}, r; + + g[0] = pwr; + g[1] = ts; + g[2] = g[3] = g[4] = 0; + bnd[g[1] >= 1] = 1; + if (g[1] && (g[1]-1)*(g[0]-1) <= 0) { + for (i=0; i < 48; i++) { + g[2] = (bnd[0] + bnd[1])/2; + if (g[0]) bnd[(pow(g[2]/g[1],-g[0]) - 1)/g[0] - 1/g[2] > -1] = g[2]; + else bnd[g[2]/exp(1-1/g[2]) < g[1]] = g[2]; + } + g[3] = g[2] / g[1]; + if (g[0]) g[4] = g[2] * (1/g[0] - 1); + } + if (g[0]) g[5] = 1 / (g[1]*SQR(g[3])/2 - g[4]*(1 - g[3]) + + (1 - pow(g[3],1+g[0]))*(1 + g[4])/(1 + g[0])) - 1; + else g[5] = 1 / (g[1]*SQR(g[3])/2 + 1 + - g[2] - g[3] - g[2]*g[3]*(log(g[3]) - 1)) - 1; + if (!mode--) { + memcpy (gamm, g, sizeof gamm); + return; + } + for (i=0; i < 0x10000; i++) { + curve[i] = 0xffff; + if ((r = (double) i / imax) < 1) + curve[i] = 0x10000 * ( mode + ? (r < g[3] ? r*g[1] : (g[0] ? pow( r,g[0])*(1+g[4])-g[4] : log(r)*g[2]+1)) + : (r < g[2] ? r/g[1] : (g[0] ? pow((r+g[4])/(1+g[4]),1/g[0]) : exp((r-1)/g[2])))); + } +} + +void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size) +{ + double work[3][6], num; + int i, j, k; + + for (i=0; i < 3; i++) { + for (j=0; j < 6; j++) + work[i][j] = j == i+3; + for (j=0; j < 3; j++) + for (k=0; k < size; k++) + work[i][j] += in[k][i] * in[k][j]; + } + for (i=0; i < 3; i++) { + num = work[i][i]; + for (j=0; j < 6; j++) + work[i][j] /= num; + for (k=0; k < 3; k++) { + if (k==i) continue; + num = work[k][i]; + for (j=0; j < 6; j++) + work[k][j] -= work[i][j] * num; + } + } + for (i=0; i < size; i++) + for (j=0; j < 3; j++) + for (out[i][j]=k=0; k < 3; k++) + out[i][j] += work[j][k+3] * in[i][k]; +} + +void CLASS cam_xyz_coeff (double cam_xyz[4][3]) +{ + double cam_rgb[4][3], inverse[4][3], num; + int i, j, k; + + for (i=0; i < colors; i++) /* Multiply out XYZ colorspace */ + for (j=0; j < 3; j++) + for (cam_rgb[i][j] = k=0; k < 3; k++) + cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j]; + + for (i=0; i < colors; i++) { /* Normalize cam_rgb so that */ + for (num=j=0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */ + num += cam_rgb[i][j]; + for (j=0; j < 3; j++) + cam_rgb[i][j] /= num; + pre_mul[i] = 1 / num; + } + pseudoinverse (cam_rgb, inverse, colors); + for (raw_color = i=0; i < 3; i++) + for (j=0; j < colors; j++) + rgb_cam[i][j] = inverse[j][i]; +} + +#ifdef COLORCHECK +void CLASS colorcheck() +{ +#define NSQ 24 +// Coordinates of the GretagMacbeth ColorChecker squares +// width, height, 1st_column, 1st_row + int cut[NSQ][4]; // you must set these +// ColorChecker Chart under 6500-kelvin illumination + static const double gmb_xyY[NSQ][3] = { + { 0.400, 0.350, 10.1 }, // Dark Skin + { 0.377, 0.345, 35.8 }, // Light Skin + { 0.247, 0.251, 19.3 }, // Blue Sky + { 0.337, 0.422, 13.3 }, // Foliage + { 0.265, 0.240, 24.3 }, // Blue Flower + { 0.261, 0.343, 43.1 }, // Bluish Green + { 0.506, 0.407, 30.1 }, // Orange + { 0.211, 0.175, 12.0 }, // Purplish Blue + { 0.453, 0.306, 19.8 }, // Moderate Red + { 0.285, 0.202, 6.6 }, // Purple + { 0.380, 0.489, 44.3 }, // Yellow Green + { 0.473, 0.438, 43.1 }, // Orange Yellow + { 0.187, 0.129, 6.1 }, // Blue + { 0.305, 0.478, 23.4 }, // Green + { 0.539, 0.313, 12.0 }, // Red + { 0.448, 0.470, 59.1 }, // Yellow + { 0.364, 0.233, 19.8 }, // Magenta + { 0.196, 0.252, 19.8 }, // Cyan + { 0.310, 0.316, 90.0 }, // White + { 0.310, 0.316, 59.1 }, // Neutral 8 + { 0.310, 0.316, 36.2 }, // Neutral 6.5 + { 0.310, 0.316, 19.8 }, // Neutral 5 + { 0.310, 0.316, 9.0 }, // Neutral 3.5 + { 0.310, 0.316, 3.1 } }; // Black + double gmb_cam[NSQ][4], gmb_xyz[NSQ][3]; + double inverse[NSQ][3], cam_xyz[4][3], num; + int c, i, j, k, sq, row, col, count[4]; + + memset (gmb_cam, 0, sizeof gmb_cam); + for (sq=0; sq < NSQ; sq++) { + FORCC count[c] = 0; + for (row=cut[sq][3]; row < cut[sq][3]+cut[sq][1]; row++) + for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) { + c = FC(row,col); + if (c >= colors) c -= 2; + gmb_cam[sq][c] += BAYER(row,col); + count[c]++; + } + FORCC gmb_cam[sq][c] = gmb_cam[sq][c]/count[c] - black; + gmb_xyz[sq][0] = gmb_xyY[sq][2] * gmb_xyY[sq][0] / gmb_xyY[sq][1]; + gmb_xyz[sq][1] = gmb_xyY[sq][2]; + gmb_xyz[sq][2] = gmb_xyY[sq][2] * + (1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1]; + } + pseudoinverse (gmb_xyz, inverse, NSQ); + for (i=0; i < colors; i++) + for (j=0; j < 3; j++) + for (cam_xyz[i][j] = k=0; k < NSQ; k++) + cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j]; + cam_xyz_coeff (cam_xyz); + if (verbose) { + printf (" { \"%s %s\", %d,\n\t{", make, model, black); + num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]); + FORCC for (j=0; j < 3; j++) + printf ("%c%d", (c | j) ? ',':' ', (int) (cam_xyz[c][j] * num + 0.5)); + puts (" } },"); + } +#undef NSQ +} +#endif + +void CLASS hat_transform (float *temp, float *base, int st, int size, int sc) +{ + int i; + for (i=0; i < sc; i++) + temp[i] = 2*base[st*i] + base[st*(sc-i)] + base[st*(i+sc)]; + for (; i+sc < size; i++) + temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(i+sc)]; + for (; i < size; i++) + temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(2*size-2-(i+sc))]; +} + +void CLASS wavelet_denoise() +{ + float *fimg=0, *temp, thold, mul[2], avg, diff; + int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast; + ushort *window[4]; + static const float noise[] = + { 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 }; + + if (verbose) fprintf (stderr,_("Wavelet denoising...\n")); + + while (maximum << scale < 0x10000) scale++; + maximum <<= --scale; + black <<= scale; + if ((size = iheight*iwidth) < 0x15550000) + fimg = (float *) malloc ((size*3 + iheight + iwidth) * sizeof *fimg); + merror (fimg, "wavelet_denoise()"); + temp = fimg + size*3; + if ((nc = colors) == 3 && filters) nc++; + FORC(nc) { /* denoise R,G1,B,G3 individually */ + for (i=0; i < size; i++) + fimg[i] = 256 * sqrt(image[i][c] << scale); + for (hpass=lev=0; lev < 5; lev++) { + lpass = size*((lev & 1)+1); + for (row=0; row < iheight; row++) { + hat_transform (temp, fimg+hpass+row*iwidth, 1, iwidth, 1 << lev); + for (col=0; col < iwidth; col++) + fimg[lpass + row*iwidth + col] = temp[col] * 0.25; + } + for (col=0; col < iwidth; col++) { + hat_transform (temp, fimg+lpass+col, iwidth, iheight, 1 << lev); + for (row=0; row < iheight; row++) + fimg[lpass + row*iwidth + col] = temp[row] * 0.25; + } + thold = threshold * noise[lev]; + for (i=0; i < size; i++) { + fimg[hpass+i] -= fimg[lpass+i]; + if (fimg[hpass+i] < -thold) fimg[hpass+i] += thold; + else if (fimg[hpass+i] > thold) fimg[hpass+i] -= thold; + else fimg[hpass+i] = 0; + if (hpass) fimg[i] += fimg[hpass+i]; + } + hpass = lpass; + } + for (i=0; i < size; i++) + image[i][c] = CLIP(SQR(fimg[i]+fimg[lpass+i])/0x10000); + } + if (filters && colors == 3) { /* pull G1 and G3 closer together */ + for (row=0; row < 2; row++) + mul[row] = 0.125 * pre_mul[FC(row+1,0) | 1] / pre_mul[FC(row,0) | 1]; + for (i=0; i < 4; i++) + window[i] = (ushort *) fimg + width*i; + for (wlast=-1, row=1; row < height-1; row++) { + while (wlast < row+1) { + for (wlast++, i=0; i < 4; i++) + window[(i+3) & 3] = window[i]; + for (col = FC(wlast,1) & 1; col < width; col+=2) + window[2][col] = BAYER(wlast,col); + } + thold = threshold/512; + for (col = (FC(row,0) & 1)+1; col < width-1; col+=2) { + avg = ( window[0][col-1] + window[0][col+1] + + window[2][col-1] + window[2][col+1] - black*4 ) + * mul[row & 1] + (window[1][col] - black) * 0.5 + black; + avg = avg < 0 ? 0 : sqrt(avg); + diff = sqrt(BAYER(row,col)) - avg; + if (diff < -thold) diff += thold; + else if (diff > thold) diff -= thold; + else diff = 0; + BAYER(row,col) = CLIP(SQR(avg+diff) + 0.5); + } + } + } + free (fimg); +} + +void CLASS scale_colors() +{ + unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8]; + int val, dark, sat; + double dsum[8], dmin, dmax; + float scale_mul[4], fr, fc; + ushort *img=0, *pix; + + if (user_mul[0]) + memcpy (pre_mul, user_mul, sizeof pre_mul); + if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) { + memset (dsum, 0, sizeof dsum); + bottom = MIN (greybox[1]+greybox[3], height); + right = MIN (greybox[0]+greybox[2], width); + for (row=greybox[1]; row < bottom; row += 8) + for (col=greybox[0]; col < right; col += 8) { + memset (sum, 0, sizeof sum); + for (y=row; y < row+8 && y < bottom; y++) + for (x=col; x < col+8 && x < right; x++) + FORC4 { + if (filters) { + c = FC(y,x); + val = BAYER(y,x); + } else + val = image[y*width+x][c]; + if (val > maximum-25) goto skip_block; + if ((val -= black) < 0) val = 0; + sum[c] += val; + sum[c+4]++; + if (filters) break; + } + FORC(8) dsum[c] += sum[c]; +skip_block: ; + } + FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c]; + } + if (use_camera_wb && cam_mul[0] != -1) { + memset (sum, 0, sizeof sum); + for (row=0; row < 8; row++) + for (col=0; col < 8; col++) { + c = FC(row,col); + if ((val = white[row][col] - black) > 0) + sum[c] += val; + sum[c+4]++; + } + if (sum[0] && sum[1] && sum[2] && sum[3]) + FORC4 pre_mul[c] = (float) sum[c+4] / sum[c]; + else if (cam_mul[0] && cam_mul[2]) + memcpy (pre_mul, cam_mul, sizeof pre_mul); + else + fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname); + } + if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1; + dark = black; + sat = maximum; + if (threshold) wavelet_denoise(); + maximum -= black; + for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) { + if (dmin > pre_mul[c]) + dmin = pre_mul[c]; + if (dmax < pre_mul[c]) + dmax = pre_mul[c]; + } + if (!highlight) dmax = dmin; + FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum; + if (verbose) { + fprintf (stderr, + _("Scaling with darkness %d, saturation %d, and\nmultipliers"), dark, sat); + FORC4 fprintf (stderr, " %f", pre_mul[c]); + fputc ('\n', stderr); + } + size = iheight*iwidth; + for (i=0; i < size*4; i++) { + val = image[0][i]; + if (!val) continue; + val -= black; + val *= scale_mul[i & 3]; + image[0][i] = CLIP(val); + } + if ((aber[0] != 1 || aber[2] != 1) && colors == 3) { + if (verbose) + fprintf (stderr,_("Correcting chromatic aberration...\n")); + for (c=0; c < 4; c+=2) { + if (aber[c] == 1) continue; + img = (ushort *) malloc (size * sizeof *img); + merror (img, "scale_colors()"); + for (i=0; i < size; i++) + img[i] = image[i][c]; + for (row=0; row < iheight; row++) { + ur = fr = (row - iheight*0.5) * aber[c] + iheight*0.5; + if (ur > iheight-2) continue; + fr -= ur; + for (col=0; col < iwidth; col++) { + uc = fc = (col - iwidth*0.5) * aber[c] + iwidth*0.5; + if (uc > iwidth-2) continue; + fc -= uc; + pix = img + ur*iwidth + uc; + image[row*iwidth+col][c] = + (pix[ 0]*(1-fc) + pix[ 1]*fc) * (1-fr) + + (pix[iwidth]*(1-fc) + pix[iwidth+1]*fc) * fr; + } + } + free(img); + } + } +} + +void CLASS pre_interpolate() +{ + ushort (*img)[4]; + int row, col, c; + + if (shrink) { + if (half_size) { + height = iheight; + width = iwidth; + } else { + img = (ushort (*)[4]) calloc (height*width, sizeof *img); + merror (img, "pre_interpolate()"); + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + c = fc(row,col); + img[row*width+col][c] = image[(row >> 1)*iwidth+(col >> 1)][c]; + } + free (image); + image = img; + shrink = 0; + } + } + if (filters && colors == 3) { + if ((mix_green = four_color_rgb)) colors++; + else { + for (row = FC(1,0) >> 1; row < height; row+=2) + for (col = FC(row,1) & 1; col < width; col+=2) + image[row*width+col][1] = image[row*width+col][3]; +/*RT*/ pre_filters = filters; + filters &= ~((filters & 0x55555555) << 1); + } + } + if (half_size) filters = 0; +} + +void CLASS border_interpolate (int border) +{ + unsigned row, col, y, x, f, c, sum[8]; + + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + if (col==border && row >= border && row < height-border) + col = width-border; + memset (sum, 0, sizeof sum); + for (y=row-1; y != row+2; y++) + for (x=col-1; x != col+2; x++) + if (y < height && x < width) { + f = fc(y,x); + sum[f] += image[y*width+x][f]; + sum[f+4]++; + } + f = fc(row,col); + FORCC if (c != f && sum[c+4]) + image[row*width+col][c] = sum[c] / sum[c+4]; + } +} + +void CLASS lin_interpolate() +{ + int code[16][16][32], *ip, sum[4]; + int c, i, x, y, row, col, shift, color; + ushort *pix; + + if (verbose) fprintf (stderr,_("Bilinear interpolation...\n")); + + border_interpolate(1); + for (row=0; row < 16; row++) + for (col=0; col < 16; col++) { + ip = code[row][col]; + memset (sum, 0, sizeof sum); + for (y=-1; y <= 1; y++) + for (x=-1; x <= 1; x++) { + shift = (y==0) + (x==0); + if (shift == 2) continue; + color = fc(row+y,col+x); + *ip++ = (width*y + x)*4 + color; + *ip++ = shift; + *ip++ = color; + sum[color] += 1 << shift; + } + FORCC + if (c != fc(row,col)) { + *ip++ = c; + *ip++ = 256 / sum[c]; + } + } + for (row=1; row < height-1; row++) + for (col=1; col < width-1; col++) { + pix = image[row*width+col]; + ip = code[row & 15][col & 15]; + memset (sum, 0, sizeof sum); + for (i=8; i--; ip+=3) + sum[ip[2]] += pix[ip[0]] << ip[1]; + for (i=colors; --i; ip+=2) + pix[ip[0]] = sum[ip[0]] * ip[1] >> 8; + } +} + +/* + This algorithm is officially called: + + "Interpolation using a Threshold-based variable number of gradients" + + described in http://scien.stanford.edu/class/psych221/projects/99/tingchen/algodep/vargra.html + + I've extended the basic idea to work with non-Bayer filter arrays. + Gradients are numbered clockwise from NW=0 to W=7. + */ +void CLASS vng_interpolate() +{ + static const signed char *cp, terms[] = { + -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01, + -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01, + -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03, + -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06, + -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04, + -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01, + -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40, + -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11, + -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11, + -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22, + -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44, + -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10, + -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04, + +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40, + +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20, + +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08, + +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20, + +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44, + +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60, + +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80, + +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40, + +1,+0,+2,+1,0,0x10 + }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 }; + ushort (*brow[5])[4], *pix; + int prow=7, pcol=1, *ip, *code[16][16], gval[8], gmin, gmax, sum[4]; + int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag; + int g, diff, thold, num, c; + + lin_interpolate(); + if (verbose) fprintf (stderr,_("VNG interpolation...\n")); + + if (filters == 1) prow = pcol = 15; + ip = (int *) calloc ((prow+1)*(pcol+1), 1280); + merror (ip, "vng_interpolate()"); + for (row=0; row <= prow; row++) /* Precalculate for VNG */ + for (col=0; col <= pcol; col++) { + code[row][col] = ip; + for (cp=terms, t=0; t < 64; t++) { + y1 = *cp++; x1 = *cp++; + y2 = *cp++; x2 = *cp++; + weight = *cp++; + grads = *cp++; + color = fc(row+y1,col+x1); + if (fc(row+y2,col+x2) != color) continue; + diag = (fc(row,col+1) == color && fc(row+1,col) == color) ? 2:1; + if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue; + *ip++ = (y1*width + x1)*4 + color; + *ip++ = (y2*width + x2)*4 + color; + *ip++ = weight; + for (g=0; g < 8; g++) + if (grads & 1< gval[g]) gmin = gval[g]; + if (gmax < gval[g]) gmax = gval[g]; + } + if (gmax == 0) { + memcpy (brow[2][col], pix, sizeof *image); + continue; + } + thold = gmin + (gmax >> 1); + memset (sum, 0, sizeof sum); + color = fc(row,col); + for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */ + if (gval[g] <= thold) { + FORCC + if (c == color && ip[1]) + sum[c] += (pix[c] + pix[ip[1]]) >> 1; + else + sum[c] += pix[ip[0] + c]; + num++; + } + } + FORCC { /* Save to buffer */ + t = pix[color]; + if (c != color) + t += (sum[c] - sum[color]) / num; + brow[2][col][c] = CLIP(t); + } + } + if (row > 3) /* Write buffer to image */ + memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image); + for (g=0; g < 4; g++) + brow[(g-1) & 3] = brow[g]; + } + memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image); + memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image); + free (brow[4]); + free (code[0][0]); +} + +/* + Patterned Pixel Grouping Interpolation by Alain Desbiolles +*/ +void CLASS ppg_interpolate() +{ + int dir[5] = { 1, width, -1, -width, 1 }; + int row, col, diff[2], guess[2], c, d, i; + ushort (*pix)[4]; + + border_interpolate(3); + if (verbose) fprintf (stderr,_("PPG interpolation...\n")); + +/* Fill in the green layer with gradients and pattern recognition: */ + for (row=3; row < height-3; row++) + for (col=3+(FC(row,3) & 1), c=FC(row,col); col < width-3; col+=2) { + pix = image + row*width+col; + for (i=0; (d=dir[i]) > 0; i++) { + guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2 + - pix[-2*d][c] - pix[2*d][c]; + diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) + + ABS(pix[ 2*d][c] - pix[ 0][c]) + + ABS(pix[ -d][1] - pix[ d][1]) ) * 3 + + ( ABS(pix[ 3*d][1] - pix[ d][1]) + + ABS(pix[-3*d][1] - pix[-d][1]) ) * 2; + } + d = dir[i = diff[0] > diff[1]]; + pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]); + } +/* Calculate red and blue for each green pixel: */ + for (row=1; row < height-1; row++) + for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < width-1; col+=2) { + pix = image + row*width+col; + for (i=0; (d=dir[i]) > 0; c=2-c, i++) + pix[0][c] = CLIP((pix[-d][c] + pix[d][c] + 2*pix[0][1] + - pix[-d][1] - pix[d][1]) >> 1); + } +/* Calculate blue for red pixels and vice versa: */ + for (row=1; row < height-1; row++) + for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < width-1; col+=2) { + pix = image + row*width+col; + for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) { + diff[i] = ABS(pix[-d][c] - pix[d][c]) + + ABS(pix[-d][1] - pix[0][1]) + + ABS(pix[ d][1] - pix[0][1]); + guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1] + - pix[-d][1] - pix[d][1]; + } + if (diff[0] != diff[1]) + pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1); + else + pix[0][c] = CLIP((guess[0]+guess[1]) >> 2); + } +} + +/* + Adaptive Homogeneity-Directed interpolation is based on + the work of Keigo Hirakawa, Thomas Parks, and Paul Lee. + */ +#define TS 256 /* Tile Size */ + +void CLASS ahd_interpolate() +{ + int i, j, k, top, left, row, col, tr, tc, c, d, val, hm[2]; + ushort (*pix)[4], (*rix)[3]; + static const int dir[4] = { -1, 1, -TS, TS }; + unsigned ldiff[2][4], abdiff[2][4], leps, abeps; + float r, cbrt[0x10000], xyz[3], xyz_cam[3][4]; + ushort (*rgb)[TS][TS][3]; + short (*lab)[TS][TS][3], (*lix)[3]; + char (*homo)[TS][TS], *buffer; + + if (verbose) fprintf (stderr,_("AHD interpolation...\n")); + + for (i=0; i < 0x10000; i++) { + r = i / 65535.0; + cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0; + } + for (i=0; i < 3; i++) + for (j=0; j < colors; j++) + for (xyz_cam[i][j] = k=0; k < 3; k++) + xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i]; + + border_interpolate(5); + buffer = (char *) malloc (26*TS*TS); /* 1664 kB */ + merror (buffer, "ahd_interpolate()"); + rgb = (ushort(*)[TS][TS][3]) buffer; + lab = (short (*)[TS][TS][3])(buffer + 12*TS*TS); + homo = (char (*)[TS][TS]) (buffer + 24*TS*TS); + + for (top=2; top < height-5; top += TS-6) + for (left=2; left < width-5; left += TS-6) { + +/* Interpolate green horizontally and vertically: */ + for (row = top; row < top+TS && row < height-2; row++) { + col = left + (FC(row,left) & 1); + for (c = FC(row,col); col < left+TS && col < width-2; col+=2) { + pix = image + row*width+col; + val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2 + - pix[-2][c] - pix[2][c]) >> 2; + rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]); + val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2 + - pix[-2*width][c] - pix[2*width][c]) >> 2; + rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]); + } + } +/* Interpolate red and blue, and convert to CIELab: */ + for (d=0; d < 2; d++) + for (row=top+1; row < top+TS-1 && row < height-3; row++) + for (col=left+1; col < left+TS-1 && col < width-3; col++) { + pix = image + row*width+col; + rix = &rgb[d][row-top][col-left]; + lix = &lab[d][row-top][col-left]; + if ((c = 2 - FC(row,col)) == 1) { + c = FC(row+1,col); + val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c] + - rix[-1][1] - rix[1][1] ) >> 1); + rix[0][2-c] = CLIP(val); + val = pix[0][1] + (( pix[-width][c] + pix[width][c] + - rix[-TS][1] - rix[TS][1] ) >> 1); + } else + val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c] + + pix[+width-1][c] + pix[+width+1][c] + - rix[-TS-1][1] - rix[-TS+1][1] + - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2); + rix[0][c] = CLIP(val); + c = FC(row,col); + rix[0][c] = pix[0][c]; + xyz[0] = xyz[1] = xyz[2] = 0.5; + FORCC { + xyz[0] += xyz_cam[0][c] * rix[0][c]; + xyz[1] += xyz_cam[1][c] * rix[0][c]; + xyz[2] += xyz_cam[2][c] * rix[0][c]; + } + xyz[0] = cbrt[CLIP((int) xyz[0])]; + xyz[1] = cbrt[CLIP((int) xyz[1])]; + xyz[2] = cbrt[CLIP((int) xyz[2])]; + lix[0][0] = 64 * (116 * xyz[1] - 16); + lix[0][1] = 64 * 500 * (xyz[0] - xyz[1]); + lix[0][2] = 64 * 200 * (xyz[1] - xyz[2]); + } +/* Build homogeneity maps from the CIELab images: */ + memset (homo, 0, 2*TS*TS); + for (row=top+2; row < top+TS-2 && row < height-4; row++) { + tr = row-top; + for (col=left+2; col < left+TS-2 && col < width-4; col++) { + tc = col-left; + for (d=0; d < 2; d++) { + lix = &lab[d][tr][tc]; + for (i=0; i < 4; i++) { + ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]); + abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1]) + + SQR(lix[0][2]-lix[dir[i]][2]); + } + } + leps = MIN(MAX(ldiff[0][0],ldiff[0][1]), + MAX(ldiff[1][2],ldiff[1][3])); + abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]), + MAX(abdiff[1][2],abdiff[1][3])); + for (d=0; d < 2; d++) + for (i=0; i < 4; i++) + if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps) + homo[d][tr][tc]++; + } + } +/* Combine the most homogenous pixels for the final result: */ + for (row=top+3; row < top+TS-3 && row < height-5; row++) { + tr = row-top; + for (col=left+3; col < left+TS-3 && col < width-5; col++) { + tc = col-left; + for (d=0; d < 2; d++) + for (hm[d]=0, i=tr-1; i <= tr+1; i++) + for (j=tc-1; j <= tc+1; j++) + hm[d] += homo[d][i][j]; + if (hm[0] != hm[1]) + FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c]; + else + FORC3 image[row*width+col][c] = + (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1; + } + } + } + free (buffer); +} +#undef TS + +void CLASS median_filter() +{ + ushort (*pix)[4]; + int pass, c, i, j, k, med[9]; + static const uchar opt[] = /* Optimal 9-element median search */ + { 1,2, 4,5, 7,8, 0,1, 3,4, 6,7, 1,2, 4,5, 7,8, + 0,3, 5,8, 4,7, 3,6, 1,4, 2,5, 4,7, 4,2, 6,4, 4,2 }; + + for (pass=1; pass <= med_passes; pass++) { + if (verbose) + fprintf (stderr,_("Median filter pass %d...\n"), pass); + for (c=0; c < 3; c+=2) { + for (pix = image; pix < image+width*height; pix++) + pix[0][3] = pix[0][c]; + for (pix = image+width; pix < image+width*(height-1); pix++) { + if ((pix-image+1) % width < 2) continue; + for (k=0, i = -width; i <= width; i += width) + for (j = i-1; j <= i+1; j++) + med[k++] = pix[j][3] - pix[j][1]; + for (i=0; i < sizeof opt; i+=2) + if (med[opt[i]] > med[opt[i+1]]) + SWAP (med[opt[i]] , med[opt[i+1]]); + pix[0][c] = CLIP(med[4] + pix[0][1]); + } + } + } +} + +void CLASS blend_highlights() +{ + int clip=INT_MAX, row, col, c, i, j; + static const float trans[2][4][4] = + { { { 1,1,1 }, { 1.7320508,-1.7320508,0 }, { -1,-1,2 } }, + { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } }; + static const float itrans[2][4][4] = + { { { 1,0.8660254,-0.5 }, { 1,-0.8660254,-0.5 }, { 1,0,1 } }, + { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } }; + float cam[2][4], lab[2][4], sum[2], chratio; + + if ((unsigned) (colors-3) > 1) return; + if (verbose) fprintf (stderr,_("Blending highlights...\n")); + FORCC if (clip > (i = 65535*pre_mul[c])) clip = i; + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + FORCC if (image[row*width+col][c] > clip) break; + if (c == colors) continue; + FORCC { + cam[0][c] = image[row*width+col][c]; + cam[1][c] = MIN(cam[0][c],clip); + } + for (i=0; i < 2; i++) { + FORCC for (lab[i][c]=j=0; j < colors; j++) + lab[i][c] += trans[colors-3][c][j] * cam[i][j]; + for (sum[i]=0,c=1; c < colors; c++) + sum[i] += SQR(lab[i][c]); + } + chratio = sqrt(sum[1]/sum[0]); + for (c=1; c < colors; c++) + lab[0][c] *= chratio; + FORCC for (cam[0][c]=j=0; j < colors; j++) + cam[0][c] += itrans[colors-3][c][j] * lab[0][j]; + FORCC image[row*width+col][c] = cam[0][c] / colors; + } +} + +#define SCALE (4 >> shrink) +void CLASS recover_highlights() +{ + float *map, sum, wgt, grow; + int hsat[4], count, spread, change, val, i; + unsigned high, wide, mrow, mcol, row, col, kc, c, d, y, x; + ushort *pixel; + static const signed char dir[8][2] = + { {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} }; + + if (verbose) fprintf (stderr,_("Rebuilding highlights...\n")); + + grow = pow (2, 4-highlight); + FORCC hsat[c] = 32000 * pre_mul[c]; + for (kc=0, c=1; c < colors; c++) + if (pre_mul[kc] < pre_mul[c]) kc = c; + high = height / SCALE; + wide = width / SCALE; + map = (float *) calloc (high*wide, sizeof *map); + merror (map, "recover_highlights()"); + FORCC if (c != kc) { + memset (map, 0, high*wide*sizeof *map); + for (mrow=0; mrow < high; mrow++) + for (mcol=0; mcol < wide; mcol++) { + sum = wgt = count = 0; + for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++) + for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) { + pixel = image[row*width+col]; + if (pixel[c] / hsat[c] == 1 && pixel[kc] > 24000) { + sum += pixel[c]; + wgt += pixel[kc]; + count++; + } + } + if (count == SCALE*SCALE) + map[mrow*wide+mcol] = sum / wgt; + } + for (spread = 32/grow; spread--; ) { + for (mrow=0; mrow < high; mrow++) + for (mcol=0; mcol < wide; mcol++) { + if (map[mrow*wide+mcol]) continue; + sum = count = 0; + for (d=0; d < 8; d++) { + y = mrow + dir[d][0]; + x = mcol + dir[d][1]; + if (y < high && x < wide && map[y*wide+x] > 0) { + sum += (1 + (d & 1)) * map[y*wide+x]; + count += 1 + (d & 1); + } + } + if (count > 3) + map[mrow*wide+mcol] = - (sum+grow) / (count+grow); + } + for (change=i=0; i < high*wide; i++) + if (map[i] < 0) { + map[i] = -map[i]; + change = 1; + } + if (!change) break; + } + for (i=0; i < high*wide; i++) + if (map[i] == 0) map[i] = 1; + for (mrow=0; mrow < high; mrow++) + for (mcol=0; mcol < wide; mcol++) { + for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++) + for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) { + pixel = image[row*width+col]; + if (pixel[c] / hsat[c] > 1) { + val = pixel[kc] * map[mrow*wide+mcol]; + if (pixel[c] < val) pixel[c] = CLIP(val); + } + } + } + } + free (map); +} +#undef SCALE + +void CLASS tiff_get (unsigned base, + unsigned *tag, unsigned *type, unsigned *len, unsigned *save) +{ + *tag = get2(); + *type = get2(); + *len = get4(); + *save = ftell(ifp) + 4; + if (*len * ("11124811248488"[*type < 14 ? *type:0]-'0') > 4) + fseek (ifp, get4()+base, SEEK_SET); +} + +void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen) +{ + unsigned entries, tag, type, len, save; + + entries = get2(); + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + if (tag == toff) thumb_offset = get4()+base; + if (tag == tlen) thumb_length = get4(); + fseek (ifp, save, SEEK_SET); + } +} + +int CLASS parse_tiff_ifd (int base); + +void CLASS parse_makernote (int base, int uptag) +{ + static const uchar xlat[2][256] = { + { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d, + 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d, + 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f, + 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f, + 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1, + 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17, + 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89, + 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f, + 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b, + 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb, + 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3, + 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f, + 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35, + 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43, + 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5, + 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 }, + { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c, + 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34, + 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad, + 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05, + 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee, + 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d, + 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b, + 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b, + 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc, + 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33, + 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8, + 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6, + 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c, + 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49, + 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb, + 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } }; + unsigned offset=0, entries, tag, type, len, save, c; + unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0}; + uchar buf97[324], ci, cj, ck; + short sorder=order; + char buf[10]; +/* + The MakerNote might have its own TIFF header (possibly with + its own byte-order!), or it might just be a table. + */ + fread (buf, 1, 10, ifp); + if (!strncmp (buf,"KDK" ,3) || /* these aren't TIFF tables */ + !strncmp (buf,"VER" ,3) || + !strncmp (buf,"IIII",4) || + !strncmp (buf,"MMMM",4)) return; + if (!strncmp (buf,"KC" ,2) || /* Konica KD-400Z, KD-510Z */ + !strncmp (buf,"MLY" ,3)) { /* Minolta DiMAGE G series */ + order = 0x4d4d; + while ((i=ftell(ifp)) < data_offset && i < 16384) { + wb[0] = wb[2]; wb[2] = wb[1]; wb[1] = wb[3]; + wb[3] = get2(); + if (wb[1] == 256 && wb[3] == 256 && + wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640) + FORC4 cam_mul[c] = wb[c]; + } + goto quit; + } + if (!strcmp (buf,"Nikon")) { + base = ftell(ifp); + order = get2(); + if (get2() != 42) goto quit; + offset = get4(); + fseek (ifp, offset-8, SEEK_CUR); + } else if (!strcmp (buf,"OLYMPUS")) { + base = ftell(ifp)-10; + fseek (ifp, -2, SEEK_CUR); + order = get2(); get2(); + } else if (!strncmp (buf,"FUJIFILM",8) || + !strncmp (buf,"SONY",4) || + !strcmp (buf,"Panasonic")) { + order = 0x4949; + fseek (ifp, 2, SEEK_CUR); + } else if (!strcmp (buf,"OLYMP") || + !strcmp (buf,"LEICA") || + !strcmp (buf,"Ricoh") || + !strcmp (buf,"EPSON")) + fseek (ifp, -2, SEEK_CUR); + else if (!strcmp (buf,"AOC") || + !strcmp (buf,"QVC")) + fseek (ifp, -4, SEEK_CUR); + else fseek (ifp, -10, SEEK_CUR); + + entries = get2(); + if (entries > 1000) return; + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + tag |= uptag << 16; + if (tag == 2 && strstr(make,"NIKON")) + iso_speed = (get2(),get2()); + if (tag == 4 && len > 26 && len < 35) { + if ((i=(get4(),get2())) != 0x7fff && !iso_speed) + iso_speed = 50 * pow (2, i/32.0 - 4); + if ((i=(get2(),get2())) != 0x7fff && !aperture) + aperture = pow (2, i/64.0); + if ((i=get2()) != 0xffff && !shutter) + shutter = pow (2, (short) i/-32.0); + wbi = (get2(),get2()); + shot_order = (get2(),get2()); + } + if ((tag == 4 || tag == 0x114) && !strncmp(make,"KONICA",6)) { + fseek (ifp, tag == 4 ? 140:160, SEEK_CUR); + switch (get2()) { + case 72: flip = 0; break; + case 76: flip = 6; break; + case 82: flip = 5; break; + } + } + if (tag == 7 && type == 2 && len > 20) + fgets (model2, 64, ifp); + if (tag == 8 && type == 4) + shot_order = get4(); + if (tag == 9 && !strcmp(make,"Canon")) + fread (artist, 64, 1, ifp); + if (tag == 0xc && len == 4) { + cam_mul[0] = getreal(type); + cam_mul[2] = getreal(type); + } + if (tag == 0x10 && type == 4) + unique_id = get4(); + if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) { + fseek (ifp, get4()+base, SEEK_SET); + parse_tiff_ifd (base); + } + if (tag == 0x14 && len == 2560 && type == 7) { + fseek (ifp, 1248, SEEK_CUR); + goto get2_256; + } + if (tag == 0x15 && type == 2 && is_raw) + fread (model, 64, 1, ifp); + if (strstr(make,"PENTAX")) { + if (tag == 0x1b) tag = 0x1018; + if (tag == 0x1c) tag = 0x1017; + } + if (tag == 0x1d) + while ((c = fgetc(ifp)) && c != EOF) + serial = serial*10 + (isdigit(c) ? c - '0' : c % 10); + if (tag == 0x81 && type == 4) { + data_offset = get4(); + fseek (ifp, data_offset + 41, SEEK_SET); + raw_height = get2() * 2; + raw_width = get2(); + filters = 0x61616161; + } + if (tag == 0x29 && type == 1) { + c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0; + fseek (ifp, 8 + c*32, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4(); + } + if ((tag == 0x81 && type == 7) || + (tag == 0x100 && type == 7) || + (tag == 0x280 && type == 1)) { + thumb_offset = ftell(ifp); + thumb_length = len; + } + if (tag == 0x88 && type == 4 && (thumb_offset = get4())) + thumb_offset += base; + if (tag == 0x89 && type == 4) + thumb_length = get4(); + if (tag == 0x8c || tag == 0x96) + meta_offset = ftell(ifp); + if (tag == 0x97) { + for (i=0; i < 4; i++) + ver97 = ver97 * 10 + fgetc(ifp)-'0'; + switch (ver97) { + case 100: + fseek (ifp, 68, SEEK_CUR); + FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2(); + break; + case 102: + fseek (ifp, 6, SEEK_CUR); + goto get2_rggb; + case 103: + fseek (ifp, 16, SEEK_CUR); + FORC4 cam_mul[c] = get2(); + } + if (ver97 >= 200) { + if (ver97 != 205) fseek (ifp, 280, SEEK_CUR); + fread (buf97, 324, 1, ifp); + } + } + if (tag == 0xa4 && type == 3) { + fseek (ifp, wbi*48, SEEK_CUR); + FORC3 cam_mul[c] = get2(); + } + if (tag == 0xa7 && (unsigned) (ver97-200) < 12 && !cam_mul[0]) { + ci = xlat[0][serial & 0xff]; + cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)]; + ck = 0x60; + for (i=0; i < 324; i++) + buf97[i] ^= (cj += ci * ck++); + i = "66666>666;6A"[ver97-200] - '0'; + FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] = + sget2 (buf97 + (i & -2) + c*2); + } + if (tag == 0x200 && len == 3) + shot_order = (get4(),get4()); + if (tag == 0x200 && len == 4) + black = (get2()+get2()+get2()+get2())/4; + if (tag == 0x201 && len == 4) + goto get2_rggb; + if (tag == 0x220 && len == 53) + meta_offset = ftell(ifp) + 14; + if (tag == 0x401 && type == 4 && len == 4) { + black = (get4()+get4()+get4()+get4())/4; + } + if (tag == 0xe01) { /* Nikon Capture Note */ + type = order; + order = 0x4949; + fseek (ifp, 22, SEEK_CUR); + for (offset=22; offset+22 < len; offset += 22+i) { + tag = get4(); + fseek (ifp, 14, SEEK_CUR); + i = get4()-4; + if (tag == 0x76a43207) flip = get2(); + else fseek (ifp, i, SEEK_CUR); + } + order = type; + } + if (tag == 0xe80 && len == 256 && type == 7) { + fseek (ifp, 48, SEEK_CUR); + cam_mul[0] = get2() * 508 * 1.078 / 0x10000; + cam_mul[2] = get2() * 382 * 1.173 / 0x10000; + } + if (tag == 0xf00 && type == 7) { + if (len == 614) + fseek (ifp, 176, SEEK_CUR); + else if (len == 734 || len == 1502) + fseek (ifp, 148, SEEK_CUR); + else goto next; + goto get2_256; + } + if ((tag == 0x1011 && len == 9) || tag == 0x20400200) + for (i=0; i < 3; i++) + FORC3 cmatrix[i][c] = ((short) get2()) / 256.0; + if ((tag == 0x1012 || tag == 0x20400600) && len == 4) + for (black = i=0; i < 4; i++) + black += get2() << 2; + if (tag == 0x1017 || tag == 0x20400100) + cam_mul[0] = get2() / 256.0; + if (tag == 0x1018 || tag == 0x20400100) + cam_mul[2] = get2() / 256.0; + if (tag == 0x2011 && len == 2) { +get2_256: + order = 0x4d4d; + cam_mul[0] = get2() / 256.0; + cam_mul[2] = get2() / 256.0; + } + if ((tag | 0x70) == 0x2070 && type == 4) + fseek (ifp, get4()+base, SEEK_SET); + if (tag == 0x2010 && type != 7) + load_raw = &CLASS olympus_load_raw; + if (tag == 0x2020) + parse_thumb_note (base, 257, 258); + if (tag == 0x2040) + parse_makernote (base, 0x2040); + if (tag == 0xb028) { + fseek (ifp, get4(), SEEK_SET); + parse_thumb_note (base, 136, 137); + } + if (tag == 0x4001 && len > 500) { + i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126; + fseek (ifp, i, SEEK_CUR); +get2_rggb: + FORC4 cam_mul[c ^ (c >> 1)] = get2(); + fseek (ifp, 22, SEEK_CUR); + FORC4 sraw_mul[c ^ (c >> 1)] = get2(); + } +next: + fseek (ifp, save, SEEK_SET); + } +quit: + order = sorder; +} + +/* + Since the TIFF DateTime string has no timezone information, + assume that the camera's clock was set to Universal Time. + */ +void CLASS get_timestamp (int reversed) +{ + struct tm t; + char str[20]; + int i; + + str[19] = 0; + if (reversed) + for (i=19; i--; ) str[i] = fgetc(ifp); + else + fread (str, 19, 1, ifp); + memset (&t, 0, sizeof t); + if (sscanf (str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon, + &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6) + return; + t.tm_year -= 1900; + t.tm_mon -= 1; + if (mktime(&t) > 0) + timestamp = mktime(&t); +} + +void CLASS parse_exif (int base) +{ + unsigned kodak, entries, tag, type, len, save, c; + double expo; + + kodak = !strncmp(make,"EASTMAN",7); + entries = get2(); + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + switch (tag) { + case 33434: shutter = getreal(type); break; + case 33437: aperture = getreal(type); break; + case 34855: iso_speed = get2(); break; + case 36867: + case 36868: get_timestamp(0); break; + case 37377: if ((expo = -getreal(type)) < 128) + shutter = pow (2, expo); break; + case 37378: aperture = pow (2, getreal(type)/2); break; + case 37386: focal_len = getreal(type); break; + case 37500: parse_makernote (base, 0); break; + case 40962: if (kodak) raw_width = get4(); break; + case 40963: if (kodak) raw_height = get4(); break; + case 41730: + if (get4() == 0x20002) + for (exif_cfa=c=0; c < 8; c+=2) + exif_cfa |= fgetc(ifp) * 0x01010101 << c; + } + fseek (ifp, save, SEEK_SET); + } +} + +void CLASS parse_gps (int base) +{ + unsigned entries, tag, type, len, save, c; + + entries = get2(); + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + switch (tag) { + case 1: case 3: case 5: + gpsdata[29+tag/2] = getc(ifp); break; + case 2: case 4: case 7: + FORC(6) gpsdata[tag/3*6+c] = get4(); break; + case 6: + FORC(2) gpsdata[18+c] = get4(); break; + case 18: case 29: + fgets ((char *) (gpsdata+14+tag/3), MIN(len,12), ifp); + } + fseek (ifp, save, SEEK_SET); + } +} + +void CLASS romm_coeff (float romm_cam[3][3]) +{ + static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */ + { { 2.034193, -0.727420, -0.306766 }, + { -0.228811, 1.231729, -0.002922 }, + { -0.008565, -0.153273, 1.161839 } }; + int i, j, k; + + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + for (cmatrix[i][j] = k=0; k < 3; k++) + cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j]; +} + +void CLASS parse_mos (int offset) +{ + char data[40]; + int skip, from, i, c, neut[4], planes=0, frot=0; + static const char *mod[] = + { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22", + "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65", + "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7" }; + float romm_cam[3][3]; + + fseek (ifp, offset, SEEK_SET); + while (1) { + if (get4() != 0x504b5453) break; + get4(); + fread (data, 1, 40, ifp); + skip = get4(); + from = ftell(ifp); + if (!strcmp(data,"JPEG_preview_data")) { + thumb_offset = from; + thumb_length = skip; + } + if (!strcmp(data,"icc_camera_profile")) { + profile_offset = from; + profile_length = skip; + } + if (!strcmp(data,"ShootObj_back_type")) { + fscanf (ifp, "%d", &i); + if ((unsigned) i < sizeof mod / sizeof (*mod)) + strcpy (model, mod[i]); + } + if (!strcmp(data,"icc_camera_to_tone_matrix")) { + for (i=0; i < 9; i++) + romm_cam[0][i] = int_to_float(get4()); + romm_coeff (romm_cam); + } + if (!strcmp(data,"CaptProf_color_matrix")) { + for (i=0; i < 9; i++) + fscanf (ifp, "%f", &romm_cam[0][i]); + romm_coeff (romm_cam); + } + if (!strcmp(data,"CaptProf_number_of_planes")) + fscanf (ifp, "%d", &planes); + if (!strcmp(data,"CaptProf_raw_data_rotation")) + fscanf (ifp, "%d", &flip); + if (!strcmp(data,"CaptProf_mosaic_pattern")) + FORC4 { + fscanf (ifp, "%d", &i); + if (i == 1) frot = c ^ (c >> 1); + } + if (!strcmp(data,"ImgProf_rotation_angle")) { + fscanf (ifp, "%d", &i); + flip = i - flip; + } + if (!strcmp(data,"NeutObj_neutrals") && !cam_mul[0]) { + FORC4 fscanf (ifp, "%d", neut+c); + FORC3 cam_mul[c] = (float) neut[0] / neut[c+1]; + } + parse_mos (from); + fseek (ifp, skip+from, SEEK_SET); + } + if (planes) + filters = (planes == 1) * 0x01010101 * + (uchar) "\x94\x61\x16\x49"[(flip/90 + frot) & 3]; +} + +void CLASS linear_table (unsigned len) +{ + int i; + if (len > 0x1000) len = 0x1000; + read_shorts (curve, len); + for (i=len; i < 0x1000; i++) + curve[i] = curve[i-1]; + maximum = curve[0xfff]; +} + +void CLASS parse_kodak_ifd (int base) +{ + unsigned entries, tag, type, len, save; + int i, c, wbi=-2, wbtemp=6500; + float mul[3]={1,1,1}, num; + static const int wbtag[]={ 0xfa25,0xfa28,0xfa27,0xfa29,-1,-1,0xfa2a }; + + entries = get2(); + if (entries > 1024) return; + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + if (tag == 1020) wbi = getint(type); + if (tag == 1021 && len == 72) { /* WB set in software */ + fseek (ifp, 40, SEEK_CUR); + FORC3 cam_mul[c] = 2048.0 / get2(); + wbi = -2; + } + if (tag == 2118) wbtemp = getint(type); + if (tag == 2130 + wbi) + FORC3 mul[c] = getreal(type); + if (tag == 2140 + wbi && wbi >= 0) + FORC3 { + for (num=i=0; i < 4; i++) + num += getreal(type) * pow (wbtemp/100.0, i); + cam_mul[c] = 2048 / (num * mul[c]); + } + if (tag == 2317) linear_table (len); + if (tag == 6020) iso_speed = getint(type); + if (tag == 0xfa0d) wbi = fgetc(ifp); + if ((unsigned) wbi < 7 && tag == wbtag[wbi]) + FORC3 cam_mul[c] = get4(); + fseek (ifp, save, SEEK_SET); + } +} + +void CLASS parse_minolta (int base); + +int CLASS parse_tiff_ifd (int base) +{ + unsigned entries, tag, type, len, plen=16, save; + int ifd, use_cm=0, cfa, i, j, c, ima_len=0; + char software[64], *cbuf, *cp; + uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256]; + double dblack, cc[4][4], cm[4][3], cam_xyz[4][3], num; + double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 }; + unsigned sony_curve[] = { 0,0,0,0,0,4095 }; + unsigned *buf, sony_offset=0, sony_length=0, sony_key=0; + struct jhead jh; +/*RT*/ IMFILE *sfp; + + if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0]) + return 1; + ifd = tiff_nifds++; + for (j=0; j < 4; j++) + for (i=0; i < 4; i++) + cc[j][i] = i == j; + entries = get2(); + if (entries > 512) return 1; + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + switch (tag) { + case 17: case 18: + if (type == 3 && len == 1) + cam_mul[(tag-17)*2] = get2() / 256.0; + break; + case 23: + if (type == 3) iso_speed = get2(); + break; + case 36: case 37: case 38: + cam_mul[tag-0x24] = get2(); + break; + case 39: + if (len < 50 || cam_mul[0]) break; + fseek (ifp, 12, SEEK_CUR); + FORC3 cam_mul[c] = get2(); + break; + case 46: + if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break; + thumb_offset = ftell(ifp) - 2; + thumb_length = len; + break; + case 2: case 256: /* ImageWidth */ + tiff_ifd[ifd].width = getint(type); + break; + case 3: case 257: /* ImageHeight */ + tiff_ifd[ifd].height = getint(type); + break; + case 258: /* BitsPerSample */ + tiff_ifd[ifd].samples = len & 7; + tiff_ifd[ifd].bps = get2(); + break; + case 259: /* Compression */ + tiff_ifd[ifd].comp = get2(); + break; + case 262: /* PhotometricInterpretation */ + tiff_ifd[ifd].phint = get2(); + break; + case 270: /* ImageDescription */ + fread (desc, 512, 1, ifp); + break; + case 271: /* Make */ + fgets (make, 64, ifp); + break; + case 272: /* Model */ + fgets (model, 64, ifp); + break; + case 280: /* Panasonic RW2 offset */ + if (type != 4) break; + load_raw = &CLASS panasonic_load_raw; + load_flags = 0x2008; + case 273: /* StripOffset */ + case 513: + tiff_ifd[ifd].offset = get4()+base; + if (!tiff_ifd[ifd].bps) { + fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET); + if (ljpeg_start (&jh, 1)) { + tiff_ifd[ifd].comp = 6; + tiff_ifd[ifd].width = jh.wide << (jh.clrs == 2); + tiff_ifd[ifd].height = jh.high; + tiff_ifd[ifd].bps = jh.bits; + tiff_ifd[ifd].samples = jh.clrs; + } + } + break; + case 274: /* Orientation */ + tiff_ifd[ifd].flip = "50132467"[get2() & 7]-'0'; + break; + case 277: /* SamplesPerPixel */ + tiff_ifd[ifd].samples = getint(type) & 7; + break; + case 279: /* StripByteCounts */ + case 514: + tiff_ifd[ifd].bytes = get4(); + break; + case 305: case 11: /* Software */ + fgets (software, 64, ifp); + if (!strncmp(software,"Adobe",5) || + !strncmp(software,"dcraw",5) || + !strncmp(software,"UFRaw",5) || + !strncmp(software,"Bibble",6) || + !strncmp(software,"Nikon Scan",10) || + !strcmp (software,"Digital Photo Professional")) + is_raw = 0; + break; + case 306: /* DateTime */ + get_timestamp(0); + break; + case 315: /* Artist */ + fread (artist, 64, 1, ifp); + break; + case 322: /* TileWidth */ + tile_width = getint(type); + break; + case 323: /* TileLength */ + tile_length = getint(type); + break; + case 324: /* TileOffsets */ + tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4(); + if (len == 4) { + load_raw = &CLASS sinar_4shot_load_raw; + is_raw = 5; + } + break; + case 330: /* SubIFDs */ + if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) { + load_raw = &CLASS sony_arw_load_raw; + data_offset = get4()+base; + ifd++; break; + } + while (len--) { + i = ftell(ifp); + fseek (ifp, get4()+base, SEEK_SET); + if (parse_tiff_ifd (base)) break; + fseek (ifp, i+4, SEEK_SET); + } + break; + case 400: + strcpy (make, "Sarnoff"); + maximum = 0xfff; + break; + case 28688: + FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff; + for (i=0; i < 5; i++) + for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++) + curve[j] = curve[j-1] + (1 << i); + break; + case 29184: sony_offset = get4(); break; + case 29185: sony_length = get4(); break; + case 29217: sony_key = get4(); break; + case 29264: + parse_minolta (ftell(ifp)); + raw_width = 0; + break; + case 29443: + FORC4 cam_mul[c ^ (c < 2)] = get2(); + break; + case 29459: + FORC4 cam_mul[c ^ (c >> 1)] = get2(); + break; + case 33405: /* Model2 */ + fgets (model2, 64, ifp); + break; + case 33422: /* CFAPattern */ + case 64777: /* Kodak P-series */ + if ((plen=len) > 16) plen = 16; + fread (cfa_pat, 1, plen, ifp); + for (colors=cfa=i=0; i < plen; i++) { + colors += !(cfa & (1 << cfa_pat[i])); + cfa |= 1 << cfa_pat[i]; + } + if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3); /* CMY */ + if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4); /* GMCY */ + goto guess_cfa_pc; + case 33424: + case 65024: + fseek (ifp, get4()+base, SEEK_SET); + parse_kodak_ifd (base); + break; + case 33434: /* ExposureTime */ + shutter = getreal(type); + break; + case 33437: /* FNumber */ + aperture = getreal(type); + break; + case 34306: /* Leaf white balance */ + FORC4 cam_mul[c ^ 1] = 4096.0 / get2(); + break; + case 34307: /* Leaf CatchLight color matrix */ + fread (software, 1, 7, ifp); + if (strncmp(software,"MATRIX",6)) break; + colors = 4; + for (raw_color = i=0; i < 3; i++) { + FORC4 fscanf (ifp, "%f", &rgb_cam[i][c^1]); + if (!use_camera_wb) continue; + num = 0; + FORC4 num += rgb_cam[i][c]; + FORC4 rgb_cam[i][c] /= num; + } + break; + case 34310: /* Leaf metadata */ + parse_mos (ftell(ifp)); + case 34303: + strcpy (make, "Leaf"); + break; + case 34665: /* EXIF tag */ + fseek (ifp, get4()+base, SEEK_SET); + parse_exif (base); + break; + case 34853: /* GPSInfo tag */ + fseek (ifp, get4()+base, SEEK_SET); + parse_gps (base); + break; + case 34675: /* InterColorProfile */ + case 50831: /* AsShotICCProfile */ + profile_offset = ftell(ifp); + profile_length = len; + break; + case 37122: /* CompressedBitsPerPixel */ + kodak_cbpp = get4(); + break; + case 37386: /* FocalLength */ + focal_len = getreal(type); + break; + case 37393: /* ImageNumber */ + shot_order = getint(type); + break; + case 37400: /* old Kodak KDC tag */ + for (raw_color = i=0; i < 3; i++) { + getreal(type); + FORC3 rgb_cam[i][c] = getreal(type); + } + break; + case 46275: /* Imacon tags */ + strcpy (make, "Imacon"); + data_offset = ftell(ifp); + ima_len = len; + break; + case 46279: + if (!ima_len) break; + fseek (ifp, 78, SEEK_CUR); + raw_width = get4(); + raw_height = get4(); + left_margin = get4() & 7; + width = raw_width - left_margin - (get4() & 7); + top_margin = get4() & 7; + height = raw_height - top_margin - (get4() & 7); + if (raw_width == 7262) { + height = 5444; + width = 7244; + left_margin = 7; + } + fseek (ifp, 52, SEEK_CUR); + FORC3 cam_mul[c] = getreal(11); + fseek (ifp, 114, SEEK_CUR); + flip = (get2() >> 7) * 90; + if (width * height * 6 == ima_len) { + if (flip % 180 == 90) SWAP(width,height); + filters = flip = 0; + } + sprintf (model, "Ixpress %d-Mp", height*width/1000000); + load_raw = &CLASS imacon_full_load_raw; + if (filters) { + if (left_margin & 1) filters = 0x61616161; + load_raw = &CLASS unpacked_load_raw; + } + maximum = 0xffff; + break; + case 50454: /* Sinar tag */ + case 50455: + if (!(cbuf = (char *) malloc(len))) break; + fread (cbuf, 1, len, ifp); + for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n')) + if (!strncmp (++cp,"Neutral ",8)) + sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2); + free (cbuf); + break; + case 50458: + if (!make[0]) strcpy (make, "Hasselblad"); + break; + case 50459: /* Hasselblad tag */ + i = order; + j = ftell(ifp); + c = tiff_nifds; + order = get2(); + fseek (ifp, j+(get2(),get4()), SEEK_SET); + parse_tiff_ifd (j); + maximum = 0xffff; + tiff_nifds = c; + order = i; + break; + case 50706: /* DNGVersion */ + FORC4 dng_version = (dng_version << 8) + fgetc(ifp); + if (!make[0]) strcpy (make, "DNG"); + is_raw = 1; + break; + case 50710: /* CFAPlaneColor */ + if (len > 4) len = 4; + colors = len; + fread (cfa_pc, 1, colors, ifp); +guess_cfa_pc: + FORCC tab[cfa_pc[c]] = c; + cdesc[c] = 0; + for (i=16; i--; ) + filters = filters << 2 | tab[cfa_pat[i % plen]]; + break; + case 50711: /* CFALayout */ + if (get2() == 2) { + fuji_width = 1; + filters = 0x49494949; + } + break; + case 291: + case 50712: /* LinearizationTable */ + linear_table (len); + break; + case 50714: /* BlackLevel */ + case 50715: /* BlackLevelDeltaH */ + case 50716: /* BlackLevelDeltaV */ + for (dblack=i=0; i < len; i++) + dblack += getreal(type); + black += dblack/len + 0.5; + break; + case 50717: /* WhiteLevel */ + maximum = getint(type); + break; + case 50718: /* DefaultScale */ + pixel_aspect = getreal(type); + pixel_aspect /= getreal(type); + break; + case 50721: /* ColorMatrix1 */ + case 50722: /* ColorMatrix2 */ + FORCC for (j=0; j < 3; j++) + cm[c][j] = getreal(type); + use_cm = 1; + break; + case 50723: /* CameraCalibration1 */ + case 50724: /* CameraCalibration2 */ + for (i=0; i < colors; i++) + FORCC cc[i][c] = getreal(type); + break; + case 50727: /* AnalogBalance */ + FORCC ab[c] = getreal(type); + break; + case 50728: /* AsShotNeutral */ + FORCC asn[c] = getreal(type); + break; + case 50729: /* AsShotWhiteXY */ + xyz[0] = getreal(type); + xyz[1] = getreal(type); + xyz[2] = 1 - xyz[0] - xyz[1]; + FORC3 xyz[c] /= d65_white[c]; + break; + case 50740: /* DNGPrivateData */ + if (dng_version) break; + parse_minolta (j = get4()+base); + fseek (ifp, j, SEEK_SET); + parse_tiff_ifd (base); + break; + case 50752: + read_shorts (cr2_slice, 3); + break; + case 50829: /* ActiveArea */ + top_margin = getint(type); + left_margin = getint(type); + height = getint(type) - top_margin; + width = getint(type) - left_margin; + break; + case 64772: /* Kodak P-series */ + if (len < 13) break; + fseek (ifp, 16, SEEK_CUR); + data_offset = get4(); + fseek (ifp, 28, SEEK_CUR); + data_offset += get4(); + load_raw = &CLASS packed_load_raw; + break; + case 65026: + if (type == 2) fgets (model2, 64, ifp); + } + fseek (ifp, save, SEEK_SET); + } + if (sony_length && (buf = (unsigned *) malloc(sony_length))) { + fseek (ifp, sony_offset, SEEK_SET); + fread (buf, sony_length, 1, ifp); + sony_decrypt (buf, sony_length/4, 1, sony_key); + sfp = ifp; +/*RT*/ ifp = fopen (buf, sony_length); +// if ((ifp = tmpfile())) { +// fwrite (buf, sony_length, 1, ifp); +// fseek (ifp, 0, SEEK_SET); + parse_tiff_ifd (-sony_offset); +// fclose (ifp); +// } + ifp = sfp; + free (buf); + } + for (i=0; i < colors; i++) + FORCC cc[i][c] *= ab[i]; + if (use_cm) { + FORCC for (i=0; i < 3; i++) + for (cam_xyz[c][i]=j=0; j < colors; j++) + cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i]; + cam_xyz_coeff (cam_xyz); + } + if (asn[0]) { + cam_mul[3] = 0; + FORCC cam_mul[c] = 1 / asn[c]; + } + if (!use_cm) + FORCC pre_mul[c] /= cc[c][c]; + return 0; +} + +void CLASS parse_tiff (int base) +{ + int doff, max_samp=0, raw=-1, thm=-1, i; + struct jhead jh; + + /*RT*/ exif_base = base; + + fseek (ifp, base, SEEK_SET); + order = get2(); + if (order != 0x4949 && order != 0x4d4d) return; + get2(); + memset (tiff_ifd, 0, sizeof tiff_ifd); + tiff_nifds = 0; + while ((doff = get4())) { + fseek (ifp, doff+base, SEEK_SET); + if (parse_tiff_ifd (base)) break; + } + thumb_misc = 16; + if (thumb_offset) { + fseek (ifp, thumb_offset, SEEK_SET); + if (ljpeg_start (&jh, 1)) { + thumb_misc = jh.bits; + thumb_width = jh.wide; + thumb_height = jh.high; + } + } + for (i=0; i < tiff_nifds; i++) { + if (max_samp < tiff_ifd[i].samples) + max_samp = tiff_ifd[i].samples; + if (max_samp > 3) max_samp = 3; + if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) && + (tiff_ifd[i].width | tiff_ifd[i].height) < 0x10000 && + tiff_ifd[i].width*tiff_ifd[i].height > raw_width*raw_height) { + raw_width = tiff_ifd[i].width; + raw_height = tiff_ifd[i].height; + tiff_bps = tiff_ifd[i].bps; + tiff_compress = tiff_ifd[i].comp; + data_offset = tiff_ifd[i].offset; + tiff_flip = tiff_ifd[i].flip; + tiff_samples = tiff_ifd[i].samples; + raw = i; + } + } + fuji_width *= (raw_width+1)/2; + if (tiff_ifd[0].flip) tiff_flip = tiff_ifd[0].flip; + if (raw >= 0 && !load_raw) + switch (tiff_compress) { + case 0: case 1: + switch (tiff_bps) { + case 8: load_raw = &CLASS eight_bit_load_raw; break; + case 12: load_raw = &CLASS packed_load_raw; + if (tiff_ifd[raw].phint == 2) + load_flags = 6; + if (strncmp(make,"PENTAX",6)) break; + case 14: + case 16: load_raw = &CLASS unpacked_load_raw; break; + } + if (tiff_ifd[raw].bytes*5 == raw_width*raw_height*8) { + tiff_bps = 12; + maximum = 0xffff; + load_raw = &CLASS packed_load_raw; + load_flags = 273; + } + break; + case 6: case 7: case 99: + load_raw = &CLASS lossless_jpeg_load_raw; break; + case 262: + load_raw = &CLASS kodak_262_load_raw; break; + case 32767: + if (tiff_ifd[raw].bytes == raw_width*raw_height) { + tiff_bps = 12; + load_raw = &CLASS sony_arw2_load_raw; break; + } + if (tiff_ifd[raw].bytes*8 != raw_width*raw_height*tiff_bps) { + raw_height += 8; + load_raw = &CLASS sony_arw_load_raw; break; + } + load_flags = 79; + case 32769: + load_flags++; + case 32773: + load_raw = &CLASS packed_load_raw; break; + case 34713: + load_raw = &CLASS nikon_compressed_load_raw; break; + case 65535: + load_raw = &CLASS pentax_load_raw; break; + case 65000: + switch (tiff_ifd[raw].phint) { + case 2: load_raw = &CLASS kodak_rgb_load_raw; filters = 0; break; + case 6: load_raw = &CLASS kodak_ycbcr_load_raw; filters = 0; break; + case 32803: load_raw = &CLASS kodak_65000_load_raw; + } + case 32867: break; + default: is_raw = 0; + } + if (!dng_version) + if ( (tiff_samples == 3 && tiff_ifd[raw].bytes && + tiff_bps != 14 && tiff_bps != 2048) + || (tiff_bps == 8 && !strstr(make,"KODAK") && !strstr(make,"Kodak") && + !strstr(model2,"DEBUG RAW"))) + is_raw = 0; + for (i=0; i < tiff_nifds; i++) + if (i != raw && tiff_ifd[i].samples == max_samp && + tiff_ifd[i].width * tiff_ifd[i].height / SQR(tiff_ifd[i].bps+1) > + thumb_width * thumb_height / SQR(thumb_misc+1)) { + thumb_width = tiff_ifd[i].width; + thumb_height = tiff_ifd[i].height; + thumb_offset = tiff_ifd[i].offset; + thumb_length = tiff_ifd[i].bytes; + thumb_misc = tiff_ifd[i].bps; + thm = i; + } + if (thm >= 0) { + thumb_misc |= tiff_ifd[thm].samples << 5; + switch (tiff_ifd[thm].comp) { + case 0: + write_thumb = &CLASS layer_thumb; + break; + case 1: + if (tiff_ifd[thm].bps > 8) + thumb_load_raw = &CLASS kodak_thumb_load_raw; + else + write_thumb = &CLASS ppm_thumb; + break; + case 65000: + thumb_load_raw = tiff_ifd[thm].phint == 6 ? + &CLASS kodak_ycbcr_load_raw : &CLASS kodak_rgb_load_raw; + } + } +} + +void CLASS parse_minolta (int base) +{ + int save, tag, len, offset, high=0, wide=0, i, c; + short sorder=order; + + fseek (ifp, base, SEEK_SET); + if (fgetc(ifp) || fgetc(ifp)-'M' || fgetc(ifp)-'R') return; + order = fgetc(ifp) * 0x101; + offset = base + get4() + 8; + while ((save=ftell(ifp)) < offset) { + for (tag=i=0; i < 4; i++) + tag = tag << 8 | fgetc(ifp); + len = get4(); + switch (tag) { + case 0x505244: /* PRD */ + fseek (ifp, 8, SEEK_CUR); + high = get2(); + wide = get2(); + break; + case 0x574247: /* WBG */ + get4(); + i = strcmp(model,"DiMAGE A200") ? 0:3; + FORC4 cam_mul[c ^ (c >> 1) ^ i] = get2(); + break; + case 0x545457: /* TTW */ + parse_tiff (ftell(ifp)); + data_offset = offset; + } + fseek (ifp, save+len+8, SEEK_SET); + } + raw_height = high; + raw_width = wide; + order = sorder; +} + +/* + Many cameras have a "debug mode" that writes JPEG and raw + at the same time. The raw file has no header, so try to + to open the matching JPEG file and read its metadata. + */ +void CLASS parse_external_jpeg() +{ + const char *file, *ext; + char *jname, *jfile, *jext; +/*RT*/ IMFILE *save=ifp; + + ext = strrchr (ifname, '.'); + file = strrchr (ifname, '/'); + if (!file) file = strrchr (ifname, '\\'); + if (!file) file = ifname-1; + file++; + if (!ext || strlen(ext) != 4 || ext-file != 8) return; + jname = (char *) malloc (strlen(ifname) + 1); + merror (jname, "parse_external_jpeg()"); + strcpy (jname, ifname); + jfile = file - ifname + jname; + jext = ext - ifname + jname; + if (strcasecmp (ext, ".jpg")) { + strcpy (jext, isupper(ext[1]) ? ".JPG":".jpg"); + if (isdigit(*file)) { + memcpy (jfile, file+4, 4); + memcpy (jfile+4, file, 4); + } + } else + while (isdigit(*--jext)) { + if (*jext != '9') { + (*jext)++; + break; + } + *jext = '0'; + } + if (strcmp (jname, ifname)) { +/*RT*/ if ((ifp = fopen (jname))) { +// if ((ifp = fopen (jname, "rb"))) { + if (verbose) + fprintf (stderr,_("Reading metadata from %s ...\n"), jname); + parse_tiff (12); + thumb_offset = 0; + is_raw = 1; + fclose (ifp); + } + } + if (!timestamp) + fprintf (stderr,_("Failed to read metadata from %s\n"), jname); + free (jname); + ifp = save; +} + +/* + CIFF block 0x1030 contains an 8x8 white sample. + Load this into white[][] for use in scale_colors(). + */ +void CLASS ciff_block_1030() +{ + static const ushort key[] = { 0x410, 0x45f3 }; + int i, bpp, row, col, vbits=0; + unsigned long bitbuf=0; + + if ((get2(),get4()) != 0x80008 || !get4()) return; + bpp = get2(); + if (bpp != 10 && bpp != 12) return; + for (i=row=0; row < 8; row++) + for (col=0; col < 8; col++) { + if (vbits < bpp) { + bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]); + vbits += 16; + } + white[row][col] = + bitbuf << (LONG_BIT - vbits) >> (LONG_BIT - bpp); + vbits -= bpp; + } +} + +/* + Parse a CIFF file, better known as Canon CRW format. + */ +void CLASS parse_ciff (int offset, int length) +{ + int tboff, nrecs, c, type, len, save, wbi=-1; + ushort key[] = { 0x410, 0x45f3 }; + + fseek (ifp, offset+length-4, SEEK_SET); + tboff = get4() + offset; + fseek (ifp, tboff, SEEK_SET); + nrecs = get2(); + if (nrecs > 100) return; + while (nrecs--) { + type = get2(); + len = get4(); + save = ftell(ifp) + 4; + fseek (ifp, offset+get4(), SEEK_SET); + if ((((type >> 8) + 8) | 8) == 0x38) + parse_ciff (ftell(ifp), len); /* Parse a sub-table */ + + if (type == 0x0810) + fread (artist, 64, 1, ifp); + if (type == 0x080a) { + fread (make, 64, 1, ifp); + fseek (ifp, strlen(make) - 63, SEEK_CUR); + fread (model, 64, 1, ifp); + } + if (type == 0x1810) { + fseek (ifp, 12, SEEK_CUR); + flip = get4(); + } + if (type == 0x1835) /* Get the decoder table */ + tiff_compress = get4(); + if (type == 0x2007) { + thumb_offset = ftell(ifp); + thumb_length = len; + } + if (type == 0x1818) { + shutter = pow (2, -int_to_float((get4(),get4()))); + aperture = pow (2, int_to_float(get4())/2); + } + if (type == 0x102a) { + iso_speed = pow (2, (get4(),get2())/32.0 - 4) * 50; + aperture = pow (2, (get2(),(short)get2())/64.0); + shutter = pow (2,-((short)get2())/32.0); + wbi = (get2(),get2()); + if (wbi > 17) wbi = 0; + fseek (ifp, 32, SEEK_CUR); + if (shutter > 1e6) shutter = get2()/10.0; + } + if (type == 0x102c) { + if (get2() > 512) { /* Pro90, G1 */ + fseek (ifp, 118, SEEK_CUR); + FORC4 cam_mul[c ^ 2] = get2(); + } else { /* G2, S30, S40 */ + fseek (ifp, 98, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2(); + } + } + if (type == 0x0032) { + if (len == 768) { /* EOS D30 */ + fseek (ifp, 72, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1)] = 1024.0 / get2(); + if (!wbi) cam_mul[0] = -1; /* use my auto white balance */ + } else if (!cam_mul[0]) { + if (get2() == key[0]) /* Pro1, G6, S60, S70 */ + c = (strstr(model,"Pro1") ? + "012346000000000000":"01345:000000006008")[wbi]-'0'+ 2; + else { /* G3, G5, S45, S50 */ + c = "023457000000006000"[wbi]-'0'; + key[0] = key[1] = 0; + } + fseek (ifp, 78 + c*8, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2() ^ key[c & 1]; + if (!wbi) cam_mul[0] = -1; + } + } + if (type == 0x10a9) { /* D60, 10D, 300D, and clones */ + if (len > 66) wbi = "0134567028"[wbi]-'0'; + fseek (ifp, 2 + wbi*8, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1)] = get2(); + } + if (type == 0x1030 && (0x18040 >> wbi & 1)) + ciff_block_1030(); /* all that don't have 0x10a9 */ + if (type == 0x1031) { + raw_width = (get2(),get2()); + raw_height = get2(); + } + if (type == 0x5029) { + focal_len = len >> 16; + if ((len & 0xffff) == 2) focal_len /= 32; + } + if (type == 0x5813) flash_used = int_to_float(len); + if (type == 0x5814) canon_ev = int_to_float(len); + if (type == 0x5817) shot_order = len; + if (type == 0x5834) unique_id = len; + if (type == 0x580e) timestamp = len; + if (type == 0x180e) timestamp = get4(); +#ifdef LOCALTIME + if ((type | 0x4000) == 0x580e) + timestamp = mktime (gmtime (×tamp)); +#endif + fseek (ifp, save, SEEK_SET); + } +} + +void CLASS parse_rollei() +{ + char line[128], *val; + struct tm t; + + fseek (ifp, 0, SEEK_SET); + memset (&t, 0, sizeof t); + do { + fgets (line, 128, ifp); + if ((val = strchr(line,'='))) + *val++ = 0; + else + val = line + strlen(line); + if (!strcmp(line,"DAT")) + sscanf (val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year); + if (!strcmp(line,"TIM")) + sscanf (val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec); + if (!strcmp(line,"HDR")) + thumb_offset = atoi(val); + if (!strcmp(line,"X ")) + raw_width = atoi(val); + if (!strcmp(line,"Y ")) + raw_height = atoi(val); + if (!strcmp(line,"TX ")) + thumb_width = atoi(val); + if (!strcmp(line,"TY ")) + thumb_height = atoi(val); + } while (strncmp(line,"EOHD",4)); + data_offset = thumb_offset + thumb_width * thumb_height * 2; + t.tm_year -= 1900; + t.tm_mon -= 1; + if (mktime(&t) > 0) + timestamp = mktime(&t); + strcpy (make, "Rollei"); + strcpy (model,"d530flex"); + write_thumb = &CLASS rollei_thumb; +} + +void CLASS parse_sinar_ia() +{ + int entries, off; + char str[8], *cp; + + order = 0x4949; + fseek (ifp, 4, SEEK_SET); + entries = get4(); + fseek (ifp, get4(), SEEK_SET); + while (entries--) { + off = get4(); get4(); + fread (str, 8, 1, ifp); + if (!strcmp(str,"META")) meta_offset = off; + if (!strcmp(str,"THUMB")) thumb_offset = off; + if (!strcmp(str,"RAW0")) data_offset = off; + } + fseek (ifp, meta_offset+20, SEEK_SET); + fread (make, 64, 1, ifp); + make[63] = 0; + if ((cp = strchr(make,' '))) { + strcpy (model, cp+1); + *cp = 0; + } + raw_width = get2(); + raw_height = get2(); + load_raw = &CLASS unpacked_load_raw; + thumb_width = (get4(),get2()); + thumb_height = get2(); + write_thumb = &CLASS ppm_thumb; + maximum = 0x3fff; +} + +void CLASS parse_phase_one (int base) +{ + unsigned entries, tag, type, len, data, save, i, c; + float romm_cam[3][3]; + char *cp; + + memset (&ph1, 0, sizeof ph1); + fseek (ifp, base, SEEK_SET); + order = get4() & 0xffff; + if (get4() >> 8 != 0x526177) return; /* "Raw" */ + fseek (ifp, get4()+base, SEEK_SET); + entries = get4(); + get4(); + while (entries--) { + tag = get4(); + type = get4(); + len = get4(); + data = get4(); + save = ftell(ifp); + fseek (ifp, base+data, SEEK_SET); + switch (tag) { + case 0x100: flip = "0653"[data & 3]-'0'; break; + case 0x106: + for (i=0; i < 9; i++) + romm_cam[0][i] = getreal(11); + romm_coeff (romm_cam); + break; + case 0x107: + FORC3 cam_mul[c] = getreal(11); + break; + case 0x108: raw_width = data; break; + case 0x109: raw_height = data; break; + case 0x10a: left_margin = data; break; + case 0x10b: top_margin = data; break; + case 0x10c: width = data; break; + case 0x10d: height = data; break; + case 0x10e: ph1.format = data; break; + case 0x10f: data_offset = data+base; break; + case 0x110: meta_offset = data+base; + meta_length = len; break; + case 0x112: ph1.key_off = save - 4; break; + case 0x210: ph1.tag_210 = int_to_float(data); break; + case 0x21a: ph1.tag_21a = data; break; + case 0x21c: strip_offset = data+base; break; + case 0x21d: ph1.black = data; break; + case 0x222: ph1.split_col = data - left_margin; break; + case 0x223: ph1.black_off = data+base; break; + case 0x301: + model[63] = 0; + fread (model, 1, 63, ifp); + if ((cp = strstr(model," camera"))) *cp = 0; + } + fseek (ifp, save, SEEK_SET); + } + load_raw = ph1.format < 3 ? + &CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c; + maximum = 0xffff; + strcpy (make, "Phase One"); + if (model[0]) return; + switch (raw_height) { + case 2060: strcpy (model,"LightPhase"); break; + case 2682: strcpy (model,"H 10"); break; + case 4128: strcpy (model,"H 20"); break; + case 5488: strcpy (model,"H 25"); break; + } +} + +void CLASS parse_fuji (int offset) +{ + unsigned entries, tag, len, save, c; + + fseek (ifp, offset, SEEK_SET); + entries = get4(); + if (entries > 255) return; + while (entries--) { + tag = get2(); + len = get2(); + save = ftell(ifp); + if (tag == 0x100) { + raw_height = get2(); + raw_width = get2(); + } else if (tag == 0x121) { + height = get2(); + if ((width = get2()) == 4284) width += 3; + } else if (tag == 0x130) { + fuji_layout = fgetc(ifp) >> 7; + load_raw = fgetc(ifp) & 8 ? + &CLASS unpacked_load_raw : &CLASS fuji_load_raw; + } + if (tag == 0x2ff0) + FORC4 cam_mul[c ^ 1] = get2(); + fseek (ifp, save+len, SEEK_SET); + } + height <<= fuji_layout; + width >>= fuji_layout; +} + +int CLASS parse_jpeg (int offset) +{ + int len, save, hlen, mark; + + fseek (ifp, offset, SEEK_SET); + if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0; + + while (fgetc(ifp) == 0xff && (mark = fgetc(ifp)) != 0xda) { + order = 0x4d4d; + len = get2() - 2; + save = ftell(ifp); + if (mark == 0xc0 || mark == 0xc3) { + fgetc(ifp); + raw_height = get2(); + raw_width = get2(); + } + order = get2(); + hlen = get4(); + if (get4() == 0x48454150) /* "HEAP" */ +/*RT*/ { +/*RT*/ ciff_base = save+hlen; +/*RT*/ ciff_len = len-hlen; + parse_ciff (save+hlen, len-hlen); +/*RT*/ } + parse_tiff (save+6); + fseek (ifp, save+len, SEEK_SET); + } + return 1; +} + +void CLASS parse_riff() +{ + unsigned i, size, end; + char tag[4], date[64], month[64]; + static const char mon[12][4] = + { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" }; + struct tm t; + + order = 0x4949; + fread (tag, 4, 1, ifp); + size = get4(); + end = ftell(ifp) + size; + if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) { + get4(); + while (ftell(ifp)+7 < end) + parse_riff(); + } else if (!memcmp(tag,"nctg",4)) { + while (ftell(ifp)+7 < end) { + i = get2(); + size = get2(); + if ((i+1) >> 1 == 10 && size == 20) + get_timestamp(0); + else fseek (ifp, size, SEEK_CUR); + } + } else if (!memcmp(tag,"IDIT",4) && size < 64) { + fread (date, 64, 1, ifp); + date[size] = 0; + memset (&t, 0, sizeof t); + if (sscanf (date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday, + &t.tm_hour, &t.tm_min, &t.tm_sec, &t.tm_year) == 6) { + for (i=0; i < 12 && strcasecmp(mon[i],month); i++); + t.tm_mon = i; + t.tm_year -= 1900; + if (mktime(&t) > 0) + timestamp = mktime(&t); + } + } else + fseek (ifp, size, SEEK_CUR); +} + +void CLASS parse_smal (int offset, int fsize) +{ + int ver; + + fseek (ifp, offset+2, SEEK_SET); + order = 0x4949; + ver = fgetc(ifp); + if (ver == 6) + fseek (ifp, 5, SEEK_CUR); + if (get4() != fsize) return; + if (ver > 6) data_offset = get4(); + raw_height = height = get2(); + raw_width = width = get2(); + strcpy (make, "SMaL"); + sprintf (model, "v%d %dx%d", ver, width, height); + if (ver == 6) load_raw = &CLASS smal_v6_load_raw; + if (ver == 9) load_raw = &CLASS smal_v9_load_raw; +} + +void CLASS parse_cine() +{ + unsigned off_head, off_setup, off_image, i; + + order = 0x4949; + fseek (ifp, 4, SEEK_SET); + is_raw = get2() == 2; + fseek (ifp, 14, SEEK_CUR); + is_raw *= get4(); + off_head = get4(); + off_setup = get4(); + off_image = get4(); + timestamp = get4(); + if ((i = get4())) timestamp = i; + fseek (ifp, off_head+4, SEEK_SET); + raw_width = get4(); + raw_height = get4(); + switch (get2(),get2()) { + case 8: load_raw = &CLASS eight_bit_load_raw; break; + case 16: load_raw = &CLASS unpacked_load_raw; + } + fseek (ifp, off_setup+792, SEEK_SET); + strcpy (make, "CINE"); + sprintf (model, "%d", get4()); + fseek (ifp, 12, SEEK_CUR); + switch ((i=get4()) & 0xffffff) { + case 3: filters = 0x94949494; break; + case 4: filters = 0x49494949; break; + default: is_raw = 0; + } + fseek (ifp, 72, SEEK_CUR); + switch ((get4()+3600) % 360) { + case 270: flip = 4; break; + case 180: flip = 1; break; + case 90: flip = 7; break; + case 0: flip = 2; + } + cam_mul[0] = getreal(11); + cam_mul[2] = getreal(11); + maximum = ~(-1 << get4()); + fseek (ifp, 668, SEEK_CUR); + shutter = get4()/1000000000.0; + fseek (ifp, off_image, SEEK_SET); + if (shot_select < is_raw) + fseek (ifp, shot_select*8, SEEK_CUR); + data_offset = (INT64) get4() + 8; + data_offset += (INT64) get4() << 32; +} + +char * CLASS foveon_gets (int offset, char *str, int len) +{ + int i; + fseek (ifp, offset, SEEK_SET); + for (i=0; i < len-1; i++) + if ((str[i] = get2()) == 0) break; + str[i] = 0; + return str; +} + +void CLASS parse_foveon() +{ + int entries, img=0, off, len, tag, save, i, wide, high, pent, poff[256][2]; + char name[64], value[64]; + + order = 0x4949; /* Little-endian */ + fseek (ifp, 36, SEEK_SET); + flip = get4(); + fseek (ifp, -4, SEEK_END); + fseek (ifp, get4(), SEEK_SET); + if (get4() != 0x64434553) return; /* SECd */ + entries = (get4(),get4()); + while (entries--) { + off = get4(); + len = get4(); + tag = get4(); + save = ftell(ifp); + fseek (ifp, off, SEEK_SET); + if (get4() != (0x20434553 | (tag << 24))) return; + switch (tag) { + case 0x47414d49: /* IMAG */ + case 0x32414d49: /* IMA2 */ + fseek (ifp, 12, SEEK_CUR); + wide = get4(); + high = get4(); + if (wide > raw_width && high > raw_height) { + raw_width = wide; + raw_height = high; + data_offset = off+24; + } + fseek (ifp, off+28, SEEK_SET); + if (fgetc(ifp) == 0xff && fgetc(ifp) == 0xd8 + && thumb_length < len-28) { + thumb_offset = off+28; + thumb_length = len-28; + write_thumb = &CLASS jpeg_thumb; + } + if (++img == 2 && !thumb_length) { + thumb_offset = off+24; + thumb_width = wide; + thumb_height = high; + write_thumb = &CLASS foveon_thumb; + } + break; + case 0x464d4143: /* CAMF */ + meta_offset = off+24; + meta_length = len-28; + if (meta_length > 0x20000) + meta_length = 0x20000; + break; + case 0x504f5250: /* PROP */ + pent = (get4(),get4()); + fseek (ifp, 12, SEEK_CUR); + off += pent*8 + 24; + if ((unsigned) pent > 256) pent=256; + for (i=0; i < pent*2; i++) + poff[0][i] = off + get4()*2; + for (i=0; i < pent; i++) { + foveon_gets (poff[i][0], name, 64); + foveon_gets (poff[i][1], value, 64); + if (!strcmp (name, "ISO")) + iso_speed = atoi(value); + if (!strcmp (name, "CAMMANUF")) + strcpy (make, value); + if (!strcmp (name, "CAMMODEL")) + strcpy (model, value); + if (!strcmp (name, "WB_DESC")) + strcpy (model2, value); + if (!strcmp (name, "TIME")) + timestamp = atoi(value); + if (!strcmp (name, "EXPTIME")) + shutter = atoi(value) / 1000000.0; + if (!strcmp (name, "APERTURE")) + aperture = atof(value); + if (!strcmp (name, "FLENGTH")) + focal_len = atof(value); + } +#ifdef LOCALTIME + timestamp = mktime (gmtime (×tamp)); +#endif + } + fseek (ifp, save, SEEK_SET); + } + is_foveon = 1; +} + +/* + All matrices are from Adobe DNG Converter unless otherwise noted. + */ +void CLASS adobe_coeff (const char *make, const char *model) +{ + static const struct { + const char *prefix; + short black, maximum, trans[12]; + } table[] = { + { "AGFAPHOTO DC-833m", 0, 0, /* DJC */ + { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } }, + { "Apple QuickTake", 0, 0, /* DJC */ + { 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } }, + { "Canon EOS D2000", 0, 0, + { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } }, + { "Canon EOS D6000", 0, 0, + { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } }, + { "Canon EOS D30", 0, 0, + { 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } }, + { "Canon EOS D60", 0, 0xfa0, + { 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } }, + { "Canon EOS 5D Mark II", 0, 0x3cf0, + { 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } }, + { "Canon EOS 5D", 0, 0xe6c, + { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } }, + { "Canon EOS 7D", 0, 0x3510, + { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } }, + { "Canon EOS 10D", 0, 0xfa0, + { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } }, + { "Canon EOS 20Da", 0, 0, + { 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } }, + { "Canon EOS 20D", 0, 0xfff, + { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } }, + { "Canon EOS 30D", 0, 0, + { 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } }, + { "Canon EOS 40D", 0, 0x3f60, + { 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } }, + { "Canon EOS 50D", 0, 0x3d93, + { 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } }, + { "Canon EOS 300D", 0, 0xfa0, + { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } }, + { "Canon EOS 350D", 0, 0xfff, + { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } }, + { "Canon EOS 400D", 0, 0xe8e, + { 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } }, + { "Canon EOS 450D", 0, 0x390d, + { 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } }, + { "Canon EOS 500D", 0, 0x3479, + { 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } }, + { "Canon EOS 1000D", 0, 0xe43, + { 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } }, + { "Canon EOS-1Ds Mark III", 0, 0x3bb0, + { 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } }, + { "Canon EOS-1Ds Mark II", 0, 0xe80, + { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } }, + { "Canon EOS-1D Mark IV", 0, 0x3bb0, + { 6014,-220,-795,-4109,12014,2361,-561,1824,5787 } }, + { "Canon EOS-1D Mark III", 0, 0x3bb0, + { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } }, + { "Canon EOS-1D Mark II N", 0, 0xe80, + { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } }, + { "Canon EOS-1D Mark II", 0, 0xe80, + { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } }, + { "Canon EOS-1DS", 0, 0xe20, + { 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } }, + { "Canon EOS-1D", 0, 0xe20, + { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } }, + { "Canon EOS", 0, 0, + { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } }, + { "Canon PowerShot A530", 0, 0, + { 0 } }, /* don't want the A5 matrix */ + { "Canon PowerShot A50", 0, 0, + { -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } }, + { "Canon PowerShot A5", 0, 0, + { -4801,9475,1952,2926,1611,4094,-5259,10164,5947,-1554,10883,547 } }, + { "Canon PowerShot G10", 0, 0, + { 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } }, + { "Canon PowerShot G11", 0, 0, + { 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } }, + { "Canon PowerShot G1", 0, 0, + { -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } }, + { "Canon PowerShot G2", 0, 0, + { 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } }, + { "Canon PowerShot G3", 0, 0, + { 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } }, + { "Canon PowerShot G5", 0, 0, + { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } }, + { "Canon PowerShot G6", 0, 0, + { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } }, + { "Canon PowerShot G9", 0, 0, + { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } }, + { "Canon PowerShot Pro1", 0, 0, + { 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } }, + { "Canon PowerShot Pro70", 34, 0, + { -4155,9818,1529,3939,-25,4522,-5521,9870,6610,-2238,10873,1342 } }, + { "Canon PowerShot Pro90", 0, 0, + { -4963,9896,2235,4642,-987,4294,-5162,10011,5859,-1770,11230,577 } }, + { "Canon PowerShot S30", 0, 0, + { 10566,-3652,-1129,-6552,14662,2006,-2197,2581,7670 } }, + { "Canon PowerShot S40", 0, 0, + { 8510,-2487,-940,-6869,14231,2900,-2318,2829,9013 } }, + { "Canon PowerShot S45", 0, 0, + { 8163,-2333,-955,-6682,14174,2751,-2077,2597,8041 } }, + { "Canon PowerShot S50", 0, 0, + { 8882,-2571,-863,-6348,14234,2288,-1516,2172,6569 } }, + { "Canon PowerShot S60", 0, 0, + { 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } }, + { "Canon PowerShot S70", 0, 0, + { 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } }, + { "Canon PowerShot S90", 0, 0, + { 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } }, + { "Canon PowerShot A470", 0, 0, /* DJC */ + { 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } }, + { "Canon PowerShot A610", 0, 0, /* DJC */ + { 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } }, + { "Canon PowerShot A620", 0, 0, /* DJC */ + { 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } }, + { "Canon PowerShot A630", 0, 0, /* DJC */ + { 14201,-5308,-1757,-6087,14472,1617,-2191,3105,5348 } }, + { "Canon PowerShot A640", 0, 0, /* DJC */ + { 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } }, + { "Canon PowerShot A650", 0, 0, /* DJC */ + { 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } }, + { "Canon PowerShot A720", 0, 0, /* DJC */ + { 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } }, + { "Canon PowerShot S3 IS", 0, 0, /* DJC */ + { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } }, + { "Canon PowerShot SX1 IS", 0, 0, + { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } }, + { "Canon PowerShot SX110 IS", 0, 0, /* DJC */ + { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } }, + { "CASIO EX-S20", 0, 0, /* DJC */ + { 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } }, + { "CASIO EX-Z750", 0, 0, /* DJC */ + { 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } }, + { "CINE 650", 0, 0, + { 3390,480,-500,-800,3610,340,-550,2336,1192 } }, + { "CINE 660", 0, 0, + { 3390,480,-500,-800,3610,340,-550,2336,1192 } }, + { "CINE", 0, 0, + { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } }, + { "Contax N Digital", 0, 0xf1e, + { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } }, + { "EPSON R-D1", 0, 0, + { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } }, + { "FUJIFILM FinePix E550", 0, 0, + { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } }, + { "FUJIFILM FinePix E900", 0, 0, + { 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } }, + { "FUJIFILM FinePix F8", 0, 0, + { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } }, + { "FUJIFILM FinePix F7", 0, 0, + { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, + { "FUJIFILM FinePix S100FS", 514, 0, + { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } }, + { "FUJIFILM FinePix S20Pro", 0, 0, + { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, + { "FUJIFILM FinePix S2Pro", 128, 0, + { 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } }, + { "FUJIFILM FinePix S3Pro", 0, 0, + { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } }, + { "FUJIFILM FinePix S5Pro", 0, 0, + { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } }, + { "FUJIFILM FinePix S5000", 0, 0, + { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } }, + { "FUJIFILM FinePix S5100", 0, 0x3e00, + { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } }, + { "FUJIFILM FinePix S5500", 0, 0x3e00, + { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } }, + { "FUJIFILM FinePix S5200", 0, 0, + { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } }, + { "FUJIFILM FinePix S5600", 0, 0, + { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } }, + { "FUJIFILM FinePix S6", 0, 0, + { 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } }, + { "FUJIFILM FinePix S7000", 0, 0, + { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } }, + { "FUJIFILM FinePix S9000", 0, 0, + { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } }, + { "FUJIFILM FinePix S9500", 0, 0, + { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } }, + { "FUJIFILM FinePix S9100", 0, 0, + { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } }, + { "FUJIFILM FinePix S9600", 0, 0, + { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } }, + { "FUJIFILM IS-1", 0, 0, + { 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } }, + { "FUJIFILM IS Pro", 0, 0, + { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } }, + { "Imacon Ixpress", 0, 0, /* DJC */ + { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } }, + { "KODAK NC2000", 0, 0, + { 13891,-6055,-803,-465,9919,642,2121,82,1291 } }, + { "Kodak DCS315C", 8, 0, + { 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } }, + { "Kodak DCS330C", 8, 0, + { 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } }, + { "KODAK DCS420", 0, 0, + { 10868,-1852,-644,-1537,11083,484,2343,628,2216 } }, + { "KODAK DCS460", 0, 0, + { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } }, + { "KODAK EOSDCS1", 0, 0, + { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } }, + { "KODAK EOSDCS3B", 0, 0, + { 9898,-2700,-940,-2478,12219,206,1985,634,1031 } }, + { "Kodak DCS520C", 180, 0, + { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } }, + { "Kodak DCS560C", 188, 0, + { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } }, + { "Kodak DCS620C", 180, 0, + { 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } }, + { "Kodak DCS620X", 185, 0, + { 13095,-6231,154,12221,-21,-2137,895,4602,2258 } }, + { "Kodak DCS660C", 214, 0, + { 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } }, + { "Kodak DCS720X", 0, 0, + { 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } }, + { "Kodak DCS760C", 0, 0, + { 16623,-6309,-1411,-4344,13923,323,2285,274,2926 } }, + { "Kodak DCS Pro SLR", 0, 0, + { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } }, + { "Kodak DCS Pro 14nx", 0, 0, + { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } }, + { "Kodak DCS Pro 14", 0, 0, + { 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 } }, + { "Kodak ProBack645", 0, 0, + { 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } }, + { "Kodak ProBack", 0, 0, + { 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } }, + { "KODAK P712", 0, 0, + { 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } }, + { "KODAK P850", 0, 0xf7c, + { 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } }, + { "KODAK P880", 0, 0xfff, + { 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } }, + { "KODAK EasyShare Z980", 0, 0, + { 11313,-3559,-1101,-3893,11891,2257,-1214,2398,4908 } }, + { "KODAK EASYSHARE Z1015", 0, 0xef1, + { 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } }, + { "Leaf CMost", 0, 0, + { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } }, + { "Leaf Valeo 6", 0, 0, + { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } }, + { "Leaf Aptus 54S", 0, 0, + { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } }, + { "Leaf Aptus 65", 0, 0, + { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } }, + { "Leaf Aptus 75", 0, 0, + { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } }, + { "Leaf", 0, 0, + { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } }, + { "Mamiya ZD", 0, 0, + { 7645,2579,-1363,-8689,16717,2015,-3712,5941,5961 } }, + { "Micron 2010", 110, 0, /* DJC */ + { 16695,-3761,-2151,155,9682,163,3433,951,4904 } }, + { "Minolta DiMAGE 5", 0, 0xf7d, + { 8983,-2942,-963,-6556,14476,2237,-2426,2887,8014 } }, + { "Minolta DiMAGE 7Hi", 0, 0xf7d, + { 11368,-3894,-1242,-6521,14358,2339,-2475,3056,7285 } }, + { "Minolta DiMAGE 7", 0, 0xf7d, + { 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } }, + { "Minolta DiMAGE A1", 0, 0xf8b, + { 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } }, + { "MINOLTA DiMAGE A200", 0, 0, + { 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } }, + { "Minolta DiMAGE A2", 0, 0xf8f, + { 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } }, + { "Minolta DiMAGE Z2", 0, 0, /* DJC */ + { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } }, + { "MINOLTA DYNAX 5", 0, 0xffb, + { 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } }, + { "MINOLTA DYNAX 7", 0, 0xffb, + { 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } }, + { "MOTOROLA PIXL", 0, 0, /* DJC */ + { 8898,-989,-1033,-3292,11619,1674,-661,3178,5216 } }, + { "NIKON D100", 0, 0, + { 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } }, + { "NIKON D1H", 0, 0, + { 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 } }, + { "NIKON D1X", 0, 0, + { 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } }, + { "NIKON D1", 0, 0, /* multiplied by 2.218750, 1.0, 1.148438 */ + { 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } }, + { "NIKON D200", 0, 0xfbc, + { 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } }, + { "NIKON D2H", 0, 0, + { 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } }, + { "NIKON D2X", 0, 0, + { 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } }, + { "NIKON D3000", 0, 0, + { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } }, + { "NIKON D300", 0, 0, + { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } }, + { "NIKON D3X", 0, 0, + { 7171,-1986,-648,-8085,15555,2718,-2170,2512,7457 } }, + { "NIKON D3S", 0, 0, + { 8828,-2406,-694,-4874,12603,2541,-660,1509,7587 } }, + { "NIKON D3", 0, 0, + { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } }, + { "NIKON D40X", 0, 0, + { 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } }, + { "NIKON D40", 0, 0, + { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } }, + { "NIKON D5000", 0, 0xf00, + { 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } }, + { "NIKON D50", 0, 0, + { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, + { "NIKON D60", 0, 0, + { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } }, + { "NIKON D700", 0, 0, + { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } }, + { "NIKON D70", 0, 0, + { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, + { "NIKON D80", 0, 0, + { 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } }, + { "NIKON D90", 0, 0xf00, + { 7309,-1403,-519,-8474,16008,2622,-2434,2826,8064 } }, + { "NIKON E950", 0, 0x3dd, /* DJC */ + { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } }, + { "NIKON E995", 0, 0, /* copied from E5000 */ + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { "NIKON E2100", 0, 0, /* copied from Z2, new white balance */ + { 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711} }, + { "NIKON E2500", 0, 0, + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { "NIKON E4300", 0, 0, /* copied from Minolta DiMAGE Z2 */ + { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } }, + { "NIKON E4500", 0, 0, + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { "NIKON E5000", 0, 0, + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { "NIKON E5400", 0, 0, + { 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 } }, + { "NIKON E5700", 0, 0, + { -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 } }, + { "NIKON E8400", 0, 0, + { 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } }, + { "NIKON E8700", 0, 0, + { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, + { "NIKON E8800", 0, 0, + { 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } }, + { "NIKON COOLPIX P6000", 0, 0, + { 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } }, + { "OLYMPUS C5050", 0, 0, + { 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } }, + { "OLYMPUS C5060", 0, 0, + { 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } }, + { "OLYMPUS C7070", 0, 0, + { 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } }, + { "OLYMPUS C70", 0, 0, + { 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } }, + { "OLYMPUS C80", 0, 0, + { 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } }, + { "OLYMPUS E-10", 0, 0xffc0, + { 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } }, + { "OLYMPUS E-1", 0, 0xfff0, + { 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } }, + { "OLYMPUS E-20", 0, 0xffc0, + { 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } }, + { "OLYMPUS E-300", 0, 0, + { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } }, + { "OLYMPUS E-330", 0, 0, + { 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } }, + { "OLYMPUS E-30", 0, 0xfbc, + { 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } }, + { "OLYMPUS E-3", 0, 0xf99, + { 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } }, + { "OLYMPUS E-400", 0, 0xfff0, + { 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } }, + { "OLYMPUS E-410", 0, 0xf6a, + { 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } }, + { "OLYMPUS E-420", 0, 0xfd7, + { 8746,-2425,-1095,-7594,15612,2073,-1780,2309,7416 } }, + { "OLYMPUS E-450", 0, 0xfd2, + { 8745,-2425,-1095,-7594,15613,2073,-1780,2309,7416 } }, + { "OLYMPUS E-500", 0, 0xfff0, + { 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } }, + { "OLYMPUS E-510", 0, 0xf6a, + { 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } }, + { "OLYMPUS E-520", 0, 0xfd2, + { 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } }, + { "OLYMPUS E-620", 0, 0xfb9, + { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } }, + { "OLYMPUS E-P1", 0, 0xffd, + { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } }, + { "OLYMPUS SP350", 0, 0, + { 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } }, + { "OLYMPUS SP3", 0, 0, + { 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } }, + { "OLYMPUS SP500UZ", 0, 0xfff, + { 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } }, + { "OLYMPUS SP510UZ", 0, 0xffe, + { 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } }, + { "OLYMPUS SP550UZ", 0, 0xffe, + { 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } }, + { "OLYMPUS SP560UZ", 0, 0xff9, + { 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } }, + { "OLYMPUS SP570UZ", 0, 0, + { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } }, + { "PENTAX *ist DL2", 0, 0, + { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, + { "PENTAX *ist DL", 0, 0, + { 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } }, + { "PENTAX *ist DS2", 0, 0, + { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, + { "PENTAX *ist DS", 0, 0, + { 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } }, + { "PENTAX *ist D", 0, 0, + { 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } }, + { "PENTAX K10D", 0, 0, + { 9566,-2863,-803,-7170,15172,2112,-818,803,9705 } }, + { "PENTAX K1", 0, 0, + { 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } }, + { "PENTAX K20D", 0, 0, + { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } }, + { "PENTAX K200D", 0, 0, + { 9186,-2678,-907,-8693,16517,2260,-1129,1094,8524 } }, + { "PENTAX K2000", 0, 0, + { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } }, + { "PENTAX K-m", 0, 0, + { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } }, + { "PENTAX K-x", 0, 0, + { 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } }, + { "PENTAX K-7", 0, 0, + { 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } }, + { "Panasonic DMC-FZ8", 0, 0xf7f0, + { 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } }, + { "Panasonic DMC-FZ18", 0, 0, + { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } }, + { "Panasonic DMC-FZ28", 15, 0xfff, + { 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } }, + { "Panasonic DMC-FZ30", 0, 0xf94c, + { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } }, + { "Panasonic DMC-FZ35", 147, 0xfff, + { 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } }, + { "Panasonic DMC-FZ50", 0, 0xfff0, /* aka "LEICA V-LUX1" */ + { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } }, + { "Panasonic DMC-L10", 15, 0xf96, + { 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } }, + { "Panasonic DMC-L1", 0, 0xf7fc, /* aka "LEICA DIGILUX 3" */ + { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } }, + { "Panasonic DMC-LC1", 0, 0, /* aka "LEICA DIGILUX 2" */ + { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } }, + { "Panasonic DMC-LX1", 0, 0xf7f0, /* aka "LEICA D-LUX2" */ + { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } }, + { "Panasonic DMC-LX2", 0, 0, /* aka "LEICA D-LUX3" */ + { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } }, + { "Panasonic DMC-LX3", 15, 0xfff, /* aka "LEICA D-LUX4" */ + { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } }, + { "Panasonic DMC-FX150", 15, 0xfff, + { 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } }, + { "Panasonic DMC-G1", 15, 0xfff, + { 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } }, + { "Panasonic DMC-GF1", 15, 0xf92, + { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, + { "Panasonic DMC-GH1", 15, 0xf92, + { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } }, + { "Phase One H 20", 0, 0, /* DJC */ + { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } }, + { "Phase One P 2", 0, 0, + { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } }, + { "Phase One P 30", 0, 0, + { 4516,-245,-37,-7020,14976,2173,-3206,4671,7087 } }, + { "Phase One P 45", 0, 0, + { 5053,-24,-117,-5684,14076,1702,-2619,4492,5849 } }, + { "Phase One P65", 0, 0, /* DJC */ + { 8522,1268,-1916,-7706,16350,1358,-2397,4344,4923 } }, + { "SAMSUNG GX-1", 0, 0, + { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, + { "SAMSUNG S85", 0, 0, /* DJC */ + { 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } }, + { "Sinar", 0, 0, /* DJC */ + { 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } }, + { "SONY DSC-F828", 491, 0, + { 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } }, + { "SONY DSC-R1", 512, 0, + { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } }, + { "SONY DSC-V3", 0, 0, + { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } }, + { "SONY DSLR-A100", 0, 0xfeb, + { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } }, + { "SONY DSLR-A200", 0, 0, + { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } }, + { "SONY DSLR-A230", 0, 0, /* copied */ + { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } }, + { "SONY DSLR-A300", 0, 0, + { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } }, + { "SONY DSLR-A330", 0, 0, + { 9847,-3091,-929,-8485,16346,2225,-714,595,7103 } }, + { "SONY DSLR-A350", 0, 0xffc, + { 6038,-1484,-578,-9146,16746,2513,-875,746,7217 } }, + { "SONY DSLR-A380", 0, 0, + { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } }, + { "SONY DSLR-A5", 254, 0x1ffe, + { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } }, + { "SONY DSLR-A700", 254, 0x1ffe, + { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } }, + { "SONY DSLR-A850", 256, 0x1ffe, + { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } }, + { "SONY DSLR-A900", 254, 0x1ffe, + { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } } + }; + double cam_xyz[4][3]; + char name[130]; + int i, j; + + sprintf (name, "%s %s", make, model); + for (i=0; i < sizeof table / sizeof *table; i++) + if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) { + if (table[i].black) black = (ushort) table[i].black; + if (table[i].maximum) maximum = (ushort) table[i].maximum; + if (table[i].trans[0]) { + for (j=0; j < 12; j++) + cam_xyz[0][j] = table[i].trans[j] / 10000.0; + cam_xyz_coeff (cam_xyz); + } + break; + } +} + +void CLASS simple_coeff (int index) +{ + static const float table[][12] = { + /* index 0 -- all Foveon cameras */ + { 1.4032,-0.2231,-0.1016,-0.5263,1.4816,0.017,-0.0112,0.0183,0.9113 }, + /* index 1 -- Kodak DC20 and DC25 */ + { 2.25,0.75,-1.75,-0.25,-0.25,0.75,0.75,-0.25,-0.25,-1.75,0.75,2.25 }, + /* index 2 -- Logitech Fotoman Pixtura */ + { 1.893,-0.418,-0.476,-0.495,1.773,-0.278,-1.017,-0.655,2.672 }, + /* index 3 -- Nikon E880, E900, and E990 */ + { -1.936280, 1.800443, -1.448486, 2.584324, + 1.405365, -0.524955, -0.289090, 0.408680, + -1.204965, 1.082304, 2.941367, -1.818705 } + }; + int i, c; + + for (raw_color = i=0; i < 3; i++) + FORCC rgb_cam[i][c] = table[index][i*colors+c]; +} + +short CLASS guess_byte_order (int words) +{ + uchar test[4][2]; + int t=2, msb; + double diff, sum[2] = {0,0}; + + fread (test[0], 2, 2, ifp); + for (words-=2; words--; ) { + fread (test[t], 2, 1, ifp); + for (msb=0; msb < 2; msb++) { + diff = (test[t^2][msb] << 8 | test[t^2][!msb]) + - (test[t ][msb] << 8 | test[t ][!msb]); + sum[msb] += diff*diff; + } + t = (t+1) & 3; + } + return sum[0] < sum[1] ? 0x4d4d : 0x4949; +} + +float CLASS find_green (int bps, int bite, int off0, int off1) +{ + UINT64 bitbuf=0; + int vbits, col, i, c; + ushort img[2][2064]; + double sum[]={0,0}; + + FORC(2) { + fseek (ifp, c ? off1:off0, SEEK_SET); + for (vbits=col=0; col < width; col++) { + for (vbits -= bps; vbits < 0; vbits += bite) { + bitbuf <<= bite; + for (i=0; i < bite; i+=8) + bitbuf |= (unsigned) (fgetc(ifp) << i); + } + img[c][col] = bitbuf << (64-bps-vbits) >> (64-bps); + } + } + FORC(width-1) { + sum[ c & 1] += ABS(img[0][c]-img[1][c+1]); + sum[~c & 1] += ABS(img[1][c]-img[0][c+1]); + } + return 100 * log(sum[0]/sum[1]); +} + +/* + Identify which camera created this file, and set global variables + accordingly. + */ +void CLASS identify() +{ + char head[32], *cp; + int hlen, fsize, i, c, is_canon; + struct jhead jh; + static const struct { + int fsize; + char make[12], model[19], withjpeg; + } table[] = { + { 62464, "Kodak", "DC20" ,0 }, + { 124928, "Kodak", "DC20" ,0 }, + { 1652736, "Kodak", "DCS200" ,0 }, + { 4159302, "Kodak", "C330" ,0 }, + { 4162462, "Kodak", "C330" ,0 }, + { 460800, "Kodak", "C603v" ,0 }, + { 614400, "Kodak", "C603v" ,0 }, + { 6163328, "Kodak", "C603" ,0 }, + { 6166488, "Kodak", "C603" ,0 }, + { 9116448, "Kodak", "C603y" ,0 }, + { 311696, "ST Micro", "STV680 VGA" ,0 }, /* SPYz */ + { 787456, "Creative", "PC-CAM 600" ,0 }, + { 1138688, "Minolta", "RD175" ,0 }, + { 3840000, "Foculus", "531C" ,0 }, + { 786432, "AVT", "F-080C" ,0 }, + { 1447680, "AVT", "F-145C" ,0 }, + { 1920000, "AVT", "F-201C" ,0 }, + { 5067304, "AVT", "F-510C" ,0 }, + { 10134608, "AVT", "F-510C" ,0 }, + { 16157136, "AVT", "F-810C" ,0 }, + { 1409024, "Sony", "XCD-SX910CR" ,0 }, + { 2818048, "Sony", "XCD-SX910CR" ,0 }, + { 3884928, "Micron", "2010" ,0 }, + { 6624000, "Pixelink", "A782" ,0 }, + { 13248000, "Pixelink", "A782" ,0 }, + { 6291456, "RoverShot","3320AF" ,0 }, + { 6553440, "Canon", "PowerShot A460" ,0 }, + { 6653280, "Canon", "PowerShot A530" ,0 }, + { 6573120, "Canon", "PowerShot A610" ,0 }, + { 9219600, "Canon", "PowerShot A620" ,0 }, + { 9243240, "Canon", "PowerShot A470" ,0 }, + { 10341600, "Canon", "PowerShot A720" ,0 }, + { 10383120, "Canon", "PowerShot A630" ,0 }, + { 12945240, "Canon", "PowerShot A640" ,0 }, + { 15636240, "Canon", "PowerShot A650" ,0 }, + { 5298000, "Canon", "PowerShot SD300" ,0 }, + { 7710960, "Canon", "PowerShot S3 IS" ,0 }, + { 15467760, "Canon", "PowerShot SX110 IS",0 }, + { 5939200, "OLYMPUS", "C770UZ" ,0 }, + { 1581060, "NIKON", "E900" ,1 }, /* or E900s,E910 */ + { 2465792, "NIKON", "E950" ,1 }, /* or E800,E700 */ + { 2940928, "NIKON", "E2100" ,1 }, /* or E2500 */ + { 4771840, "NIKON", "E990" ,1 }, /* or E995, Oly C3030Z */ + { 4775936, "NIKON", "E3700" ,1 }, /* or Optio 33WR */ + { 5869568, "NIKON", "E4300" ,1 }, /* or DiMAGE Z2 */ + { 5865472, "NIKON", "E4500" ,1 }, + { 7438336, "NIKON", "E5000" ,1 }, /* or E5700 */ + { 8998912, "NIKON", "COOLPIX S6" ,1 }, + { 1976352, "CASIO", "QV-2000UX" ,1 }, + { 3217760, "CASIO", "QV-3*00EX" ,1 }, + { 6218368, "CASIO", "QV-5700" ,1 }, + { 6054400, "CASIO", "QV-R41" ,1 }, + { 7530816, "CASIO", "QV-R51" ,1 }, + { 7684000, "CASIO", "QV-4000" ,1 }, + { 2937856, "CASIO", "EX-S20" ,1 }, + { 4948608, "CASIO", "EX-S100" ,1 }, + { 7542528, "CASIO", "EX-Z50" ,1 }, + { 7753344, "CASIO", "EX-Z55" ,1 }, + { 7816704, "CASIO", "EX-Z60" ,1 }, + { 10843712, "CASIO", "EX-Z75" ,1 }, + { 10834368, "CASIO", "EX-Z750" ,1 }, + { 12310144, "CASIO", "EX-Z850" ,1 }, + { 7426656, "CASIO", "EX-P505" ,1 }, + { 9313536, "CASIO", "EX-P600" ,1 }, + { 10979200, "CASIO", "EX-P700" ,1 }, + { 3178560, "PENTAX", "Optio S" ,1 }, + { 4841984, "PENTAX", "Optio S" ,1 }, + { 6114240, "PENTAX", "Optio S4" ,1 }, /* or S4i, CASIO EX-Z4 */ + { 10702848, "PENTAX", "Optio 750Z" ,1 }, + { 15980544, "AGFAPHOTO","DC-833m" ,1 }, + { 16098048, "SAMSUNG", "S85" ,1 }, + { 16215552, "SAMSUNG", "S85" ,1 }, + { 12582980, "Sinar", "" ,0 }, + { 33292868, "Sinar", "" ,0 }, + { 44390468, "Sinar", "" ,0 } }; + static const char *corp[] = + { "Canon", "NIKON", "EPSON", "KODAK", "Kodak", "OLYMPUS", "PENTAX", + "MINOLTA", "Minolta", "Konica", "CASIO", "Sinar", "Phase One", + "SAMSUNG", "Mamiya", "MOTOROLA" }; + + tiff_flip = flip = filters = -1; /* 0 is valid, so -1 is unknown */ + raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0; + maximum = height = width = top_margin = left_margin = 0; + cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0; + iso_speed = shutter = aperture = focal_len = unique_id = 0; + memset (gpsdata, 0, sizeof gpsdata); + memset (white, 0, sizeof white); + thumb_offset = thumb_length = thumb_width = thumb_height = 0; + load_raw = thumb_load_raw = 0; + write_thumb = &CLASS jpeg_thumb; + data_offset = meta_length = tiff_bps = tiff_compress = 0; + kodak_cbpp = zero_after_ff = dng_version = load_flags = 0; + timestamp = shot_order = tiff_samples = black = is_foveon = 0; + mix_green = profile_length = data_error = zero_is_bad = 0; + pixel_aspect = is_raw = raw_color = 1; + tile_width = tile_length = INT_MAX; + for (i=0; i < 4; i++) { + cam_mul[i] = i == 1; + pre_mul[i] = i < 3; + FORC3 cmatrix[c][i] = 0; + FORC3 rgb_cam[c][i] = c == i; + } + colors = 3; + for (i=0; i < 0x4000; i++) curve[i] = i; + + order = get2(); + hlen = get4(); + fseek (ifp, 0, SEEK_SET); + fread (head, 1, 32, ifp); + fseek (ifp, 0, SEEK_END); + fsize = ftell(ifp); + + /*RT*/ if (fsize<100000) { + is_raw = 0; + return; + } + + if ((cp = (char *) memmem (head, 32, "MMMM", 4)) || + (cp = (char *) memmem (head, 32, "IIII", 4))) { + parse_phase_one (cp-head); + if (cp-head) parse_tiff(0); + } else if (order == 0x4949 || order == 0x4d4d) { + if (!memcmp (head+6,"HEAPCCDR",8)) { + data_offset = hlen; +/*RT*/ ciff_base = hlen; +/*RT*/ ciff_len = fsize - hlen; + parse_ciff (hlen, fsize - hlen); + } else { + parse_tiff(0); + } + } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) && + !memcmp (head+6,"Exif",4)) { + fseek (ifp, 4, SEEK_SET); + data_offset = 4 + get2(); + fseek (ifp, data_offset, SEEK_SET); + if (fgetc(ifp) != 0xff) + parse_tiff(12); + thumb_offset = 0; + } else if (!memcmp (head+25,"ARECOYK",7)) { + strcpy (make, "Contax"); + strcpy (model,"N Digital"); + fseek (ifp, 33, SEEK_SET); + get_timestamp(1); + fseek (ifp, 60, SEEK_SET); + FORC4 cam_mul[c ^ (c >> 1)] = get4(); + } else if (!strcmp (head, "PXN")) { + strcpy (make, "Logitech"); + strcpy (model,"Fotoman Pixtura"); + } else if (!strcmp (head, "qktk")) { + strcpy (make, "Apple"); + strcpy (model,"QuickTake 100"); + } else if (!strcmp (head, "qktn")) { + strcpy (make, "Apple"); + strcpy (model,"QuickTake 150"); + } else if (!memcmp (head,"FUJIFILM",8)) { + fseek (ifp, 84, SEEK_SET); + thumb_offset = get4(); + thumb_length = get4(); + fseek (ifp, 92, SEEK_SET); + parse_fuji (get4()); + if (thumb_offset > 120) { + fseek (ifp, 120, SEEK_SET); + is_raw += (i = get4()) && 1; + if (is_raw == 2 && shot_select) + parse_fuji (i); + } + fseek (ifp, 100, SEEK_SET); + data_offset = get4(); + parse_tiff (thumb_offset+12); + } else if (!memcmp (head,"RIFF",4)) { + fseek (ifp, 0, SEEK_SET); + parse_riff(); + } else if (!memcmp (head,"\0\001\0\001\0@",6)) { + fseek (ifp, 6, SEEK_SET); + fread (make, 1, 8, ifp); + fread (model, 1, 8, ifp); + fread (model2, 1, 16, ifp); + data_offset = get2(); + get2(); + raw_width = get2(); + raw_height = get2(); + load_raw = &CLASS nokia_load_raw; + filters = 0x61616161; + } else if (!memcmp (head,"DSC-Image",9)) + parse_rollei(); + else if (!memcmp (head,"PWAD",4)) + parse_sinar_ia(); + else if (!memcmp (head,"\0MRM",4)) + parse_minolta(0); + else if (!memcmp (head,"FOVb",4)) + parse_foveon(); + else if (!memcmp (head,"CI",2)) + parse_cine(); + else + for (i=0; i < sizeof table / sizeof *table; i++) + if (fsize == table[i].fsize) { + strcpy (make, table[i].make ); + strcpy (model, table[i].model); + if (table[i].withjpeg) + parse_external_jpeg(); + } + if (make[0] == 0) parse_smal (0, fsize); + if (make[0] == 0) parse_jpeg (is_raw = 0); + + for (i=0; i < sizeof corp / sizeof *corp; i++) + if (strstr (make, corp[i])) /* Simplify company names */ + strcpy (make, corp[i]); + if (!strncmp (make,"KODAK",5) && + ((cp = strstr(model," DIGITAL CAMERA")) || + (cp = strstr(model," Digital Camera")) || + (cp = strstr(model,"FILE VERSION")))) + *cp = 0; + cp = make + strlen(make); /* Remove trailing spaces */ + while (*--cp == ' ') *cp = 0; + cp = model + strlen(model); + while (*--cp == ' ') *cp = 0; + i = strlen(make); /* Remove make from model */ + if (!strncasecmp (model, make, i) && model[i++] == ' ') + memmove (model, model+i, 64-i); + if (!strncmp (model,"Digital Camera ",15)) + strcpy (model, model+15); + desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0; + if (!is_raw) goto notraw; + + if (!height) height = raw_height; + if (!width) width = raw_width; + if (fuji_width) { + width = height + fuji_width; + height = width - 1; + pixel_aspect = 1; + } + if (height == 2624 && width == 3936) /* Pentax K10D and Samsung GX10 */ + { height = 2616; width = 3896; } + if (height == 3136 && width == 4864) /* Pentax K20D */ + { height = 3124; width = 4688; } + if (height == 3136 && width == 4736) /* Pentax K-7 */ + { height = 3122; width = 4684; + top_margin = 2; filters = 0x16161616; } + if (height == 3014 && width == 4096) /* Ricoh GX200 */ + width = 4014; + if (dng_version) { + if (filters == UINT_MAX) filters = 0; + if (filters) is_raw = tiff_samples; + else colors = tiff_samples; + if (tiff_compress == 1) + load_raw = &CLASS adobe_dng_load_raw_nc; + if (tiff_compress == 7) + load_raw = &CLASS adobe_dng_load_raw_lj; + goto dng_skip; + } + if ((is_canon = !strcmp(make,"Canon"))) + load_raw = memcmp (head+6,"HEAPCCDR",8) ? + &CLASS lossless_jpeg_load_raw : &CLASS canon_compressed_load_raw; + if (!strcmp(make,"NIKON")) { + if (!load_raw) + load_raw = &CLASS packed_load_raw; + if (model[0] == 'E') + load_flags |= !data_offset << 2 | 2; + } + if (!strcmp(make,"CASIO")) { + load_raw = &CLASS packed_load_raw; + maximum = 0xf7f; + } + +/* Set parameters based on camera name (for non-DNG files). */ + + if (is_foveon) { + if (height*2 < width) pixel_aspect = 0.5; + if (height > width) pixel_aspect = 2; + filters = 0; + load_raw = &CLASS foveon_load_raw; + simple_coeff(0); + } else if (is_canon && tiff_bps == 15) { + switch (width) { + case 3344: width -= 66; + case 3872: width -= 6; + } + filters = 0; + load_raw = &CLASS canon_sraw_load_raw; + } else if (!strcmp(model,"PowerShot 600")) { + height = 613; + width = 854; + raw_width = 896; + pixel_aspect = 607/628.0; + colors = 4; + filters = 0xe1e4e1e4; + load_raw = &CLASS canon_600_load_raw; + } else if (!strcmp(model,"PowerShot A5") || + !strcmp(model,"PowerShot A5 Zoom")) { + height = 773; + width = 960; + raw_width = 992; + pixel_aspect = 256/235.0; + colors = 4; + filters = 0x1e4e1e4e; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A50")) { + height = 968; + width = 1290; + raw_width = 1320; + colors = 4; + filters = 0x1b4e4b1e; + goto canon_a5; + } else if (!strcmp(model,"PowerShot Pro70")) { + height = 1024; + width = 1552; + colors = 4; + filters = 0x1e4b4e1b; + goto canon_a5; + } else if (!strcmp(model,"PowerShot SD300")) { + height = 1752; + width = 2344; + raw_height = 1766; + raw_width = 2400; + top_margin = 12; + left_margin = 12; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A460")) { + height = 1960; + width = 2616; + raw_height = 1968; + raw_width = 2664; + top_margin = 4; + left_margin = 4; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A530")) { + height = 1984; + width = 2620; + raw_height = 1992; + raw_width = 2672; + top_margin = 6; + left_margin = 10; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A610")) { + if (canon_s2is()) strcpy (model+10, "S2 IS"); + height = 1960; + width = 2616; + raw_height = 1968; + raw_width = 2672; + top_margin = 8; + left_margin = 12; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A620")) { + height = 2328; + width = 3112; + raw_height = 2340; + raw_width = 3152; + top_margin = 12; + left_margin = 36; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A470")) { + height = 2328; + width = 3096; + raw_height = 2346; + raw_width = 3152; + top_margin = 6; + left_margin = 12; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A720")) { + height = 2472; + width = 3298; + raw_height = 2480; + raw_width = 3336; + top_margin = 5; + left_margin = 6; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A630")) { + height = 2472; + width = 3288; + raw_height = 2484; + raw_width = 3344; + top_margin = 6; + left_margin = 12; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A640")) { + height = 2760; + width = 3672; + raw_height = 2772; + raw_width = 3736; + top_margin = 6; + left_margin = 12; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A650")) { + height = 3024; + width = 4032; + raw_height = 3048; + raw_width = 4104; + top_margin = 12; + left_margin = 48; + goto canon_a5; + } else if (!strcmp(model,"PowerShot S3 IS")) { + height = 2128; + width = 2840; + raw_height = 2136; + raw_width = 2888; + top_margin = 8; + left_margin = 44; +canon_a5: + tiff_bps = 10; + load_raw = &CLASS packed_load_raw; + load_flags = 40; + if (raw_width > 1600) zero_is_bad = 1; + } else if (!strcmp(model,"PowerShot SX110 IS")) { + height = 2760; + width = 3684; + raw_height = 2772; + raw_width = 3720; + top_margin = 12; + left_margin = 6; + load_raw = &CLASS packed_load_raw; + load_flags = 40; + zero_is_bad = 1; + } else if (!strcmp(model,"PowerShot Pro90 IS")) { + width = 1896; + colors = 4; + filters = 0xb4b4b4b4; + } else if (is_canon && raw_width == 2144) { + height = 1550; + width = 2088; + top_margin = 8; + left_margin = 4; + if (!strcmp(model,"PowerShot G1")) { + colors = 4; + filters = 0xb4b4b4b4; + } + } else if (is_canon && raw_width == 2224) { + height = 1448; + width = 2176; + top_margin = 6; + left_margin = 48; + } else if (is_canon && raw_width == 2376) { + height = 1720; + width = 2312; + top_margin = 6; + left_margin = 12; + } else if (is_canon && raw_width == 2672) { + height = 1960; + width = 2616; + top_margin = 6; + left_margin = 12; + } else if (is_canon && raw_width == 3152) { + height = 2056; + width = 3088; + top_margin = 12; + left_margin = 64; + if (unique_id == 0x80000170) + adobe_coeff ("Canon","EOS 300D"); + } else if (is_canon && raw_width == 3160) { + height = 2328; + width = 3112; + top_margin = 12; + left_margin = 44; + } else if (is_canon && raw_width == 3344) { + height = 2472; + width = 3288; + top_margin = 6; + left_margin = 4; + } else if (!strcmp(model,"EOS D2000C")) { + filters = 0x61616161; + black = curve[200]; + } else if (is_canon && raw_width == 3516) { + top_margin = 14; + left_margin = 42; + if (unique_id == 0x80000189) + adobe_coeff ("Canon","EOS 350D"); + goto canon_cr2; + } else if (is_canon && raw_width == 3596) { + top_margin = 12; + left_margin = 74; + goto canon_cr2; + } else if (is_canon && raw_width == 3744) { + height = 2760; + width = 3684; + top_margin = 16; + left_margin = 8; + } else if (is_canon && raw_width == 3944) { + height = 2602; + width = 3908; + top_margin = 18; + left_margin = 30; + } else if (is_canon && raw_width == 3948) { + top_margin = 18; + left_margin = 42; + height -= 2; + if (unique_id == 0x80000236) + adobe_coeff ("Canon","EOS 400D"); + if (unique_id == 0x80000254) + adobe_coeff ("Canon","EOS 1000D"); + goto canon_cr2; + } else if (is_canon && raw_width == 3984) { + top_margin = 20; + left_margin = 76; + height -= 2; + goto canon_cr2; + } else if (is_canon && raw_width == 4104) { + height = 3024; + width = 4032; + top_margin = 12; + left_margin = 48; + } else if (is_canon && raw_width == 4152) { + top_margin = 12; + left_margin = 192; + goto canon_cr2; + } else if (is_canon && raw_width == 4312) { + top_margin = 18; + left_margin = 22; + height -= 2; + if (unique_id == 0x80000176) + adobe_coeff ("Canon","EOS 450D"); + goto canon_cr2; + } else if (is_canon && raw_width == 4476) { + top_margin = 34; + left_margin = 90; + goto canon_cr2; + } else if (is_canon && raw_width == 4480) { + height = 3326; + width = 4432; + top_margin = 10; + left_margin = 12; + filters = 0x49494949; + } else if (is_canon && raw_width == 1208) { + top_margin = unique_id == 0x80000261 ? 51:26; + left_margin = 62; + raw_width = width *= 4; + if (unique_id == 0x80000252) + adobe_coeff ("Canon","EOS 500D"); + goto canon_cr2; + } else if (is_canon && raw_width == 1280) { + height -= top_margin = 45; + left_margin = 142; + raw_width *= 4; + width = 4916; + } else if (is_canon && raw_width == 1340) { + top_margin = 51; + left_margin = 158; + raw_width = width *= 4; + goto canon_cr2; + } else if (is_canon && raw_width == 1448) { + top_margin = 51; + left_margin = 158; + raw_width = width *= 4; + goto canon_cr2; + } else if (is_canon && raw_width == 5108) { + top_margin = 13; + left_margin = 98; +canon_cr2: + height -= top_margin; + width -= left_margin; + } else if (is_canon && raw_width == 5712) { + height = 3752; + width = 5640; + top_margin = 20; + left_margin = 62; + } else if (!strcmp(model,"D1")) { + cam_mul[0] *= 256/527.0; + cam_mul[2] *= 256/317.0; + } else if (!strcmp(model,"D1X")) { + width -= 4; + pixel_aspect = 0.5; + } else if (!strcmp(model,"D40X") || + !strcmp(model,"D60") || + !strcmp(model,"D80") || + !strcmp(model,"D3000")) { + height -= 3; + width -= 4; + } else if (!strcmp(model,"D3") || + !strcmp(model,"D3S") || + !strcmp(model,"D700")) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"D5000")) { + width -= 42; + } else if (!strncmp(model,"D40",3) || + !strncmp(model,"D50",3) || + !strncmp(model,"D70",3)) { + width--; + } else if (!strcmp(model,"D90")) { + width -= 42; + } else if (!strcmp(model,"D100")) { + if (tiff_compress == 34713 && !nikon_is_compressed()) { + load_raw = &CLASS packed_load_raw; + load_flags |= 1; + raw_width = (width += 3) + 3; + } + } else if (!strcmp(model,"D200")) { + left_margin = 1; + width -= 4; + filters = 0x94949494; + } else if (!strncmp(model,"D2H",3)) { + left_margin = 6; + width -= 14; + } else if (!strncmp(model,"D2X",3)) { + if (width == 3264) width -= 32; + else width -= 8; + } else if (!strncmp(model,"D300",4)) { + width -= 32; + } else if (!strcmp(model,"COOLPIX P6000")) { + load_flags = 24; + filters = 0x94949494; + } else if (fsize == 1581060) { + height = 963; + width = 1287; + raw_width = 1632; + maximum = 0x3f4; + colors = 4; + filters = 0x1e1e1e1e; + simple_coeff(3); + pre_mul[0] = 1.2085; + pre_mul[1] = 1.0943; + pre_mul[3] = 1.1103; + goto e900; + } else if (fsize == 2465792) { + height = 1203; + width = 1616; + raw_width = 2048; + colors = 4; + filters = 0x4b4b4b4b; + adobe_coeff ("NIKON","E950"); +e900: + tiff_bps = 10; + load_raw = &CLASS packed_load_raw; + load_flags = 6; + } else if (fsize == 4771840) { + height = 1540; + width = 2064; + colors = 4; + filters = 0xe1e1e1e1; + load_raw = &CLASS packed_load_raw; + load_flags = 6; + if (!timestamp && nikon_e995()) + strcpy (model, "E995"); + if (strcmp(model,"E995")) { + filters = 0xb4b4b4b4; + simple_coeff(3); + pre_mul[0] = 1.196; + pre_mul[1] = 1.246; + pre_mul[2] = 1.018; + } + } else if (!strcmp(model,"E2100")) { + if (!timestamp && !nikon_e2100()) goto cp_e2500; + height = 1206; + width = 1616; + load_flags = 30; + } else if (!strcmp(model,"E2500")) { +cp_e2500: + strcpy (model, "E2500"); + height = 1204; + width = 1616; + colors = 4; + filters = 0x4b4b4b4b; + } else if (fsize == 4775936) { + height = 1542; + width = 2064; + load_raw = &CLASS packed_load_raw; + load_flags = 30; + if (!timestamp) nikon_3700(); + if (model[0] == 'E' && atoi(model+1) < 3700) + filters = 0x49494949; + if (!strcmp(model,"Optio 33WR")) { + flip = 1; + filters = 0x16161616; + } + if (make[0] == 'O') { + i = find_green (12, 32, 0, fsize/2); + c = find_green (12, 32, 0, 3096); + if (abs(i) < abs(c)) { + SWAP(i,c); + load_flags = 24; + } + if (i < 0) filters = 0x61616161; + } + } else if (fsize == 5869568) { + height = 1710; + width = 2288; + filters = 0x16161616; + if (!timestamp && minolta_z2()) { + strcpy (make, "Minolta"); + strcpy (model,"DiMAGE Z2"); + } + load_raw = &CLASS packed_load_raw; + load_flags = 6 + 24*(make[0] == 'M'); + } else if (!strcmp(model,"E4500")) { + height = 1708; + width = 2288; + colors = 4; + filters = 0xb4b4b4b4; + } else if (fsize == 7438336) { + height = 1924; + width = 2576; + colors = 4; + filters = 0xb4b4b4b4; + } else if (fsize == 8998912) { + height = 2118; + width = 2832; + maximum = 0xf83; + load_raw = &CLASS packed_load_raw; + load_flags = 30; + } else if (!strcmp(make,"FUJIFILM")) { + if (!strcmp(model+7,"S2Pro")) { + strcpy (model+7," S2Pro"); + height = 2144; + width = 2880; + flip = 6; + } else + maximum = 0x3e00; + if (is_raw == 2 && shot_select) + maximum = 0x2f00; + top_margin = (raw_height - height)/2; + left_margin = (raw_width - width )/2; + if (is_raw == 2) + data_offset += (shot_select > 0) * ( fuji_layout ? + (raw_width *= 2) : raw_height*raw_width*2 ); + if (load_raw == &CLASS fuji_load_raw) { + fuji_width = width >> !fuji_layout; + width = (height >> fuji_layout) + fuji_width; + raw_height = height; + height = width - 1; + if (~fuji_width & 1) filters = 0x49494949; + } + } else if (!strcmp(model,"RD175")) { + height = 986; + width = 1534; + data_offset = 513; + filters = 0x61616161; + load_raw = &CLASS minolta_rd175_load_raw; + } else if (!strcmp(model,"KD-400Z")) { + height = 1712; + width = 2312; + raw_width = 2336; + goto konica_400z; + } else if (!strcmp(model,"KD-510Z")) { + goto konica_510z; + } else if (!strcasecmp(make,"MINOLTA")) { + load_raw = &CLASS unpacked_load_raw; + maximum = 0xfff; + if (!strncmp(model,"DiMAGE A",8)) { + if (!strcmp(model,"DiMAGE A200")) + filters = 0x49494949; + tiff_bps = 12; + load_raw = &CLASS packed_load_raw; + } else if (!strncmp(model,"ALPHA",5) || + !strncmp(model,"DYNAX",5) || + !strncmp(model,"MAXXUM",6)) { + sprintf (model+20, "DYNAX %-10s", model+6+(model[0]=='M')); + adobe_coeff (make, model+20); + load_raw = &CLASS packed_load_raw; + } else if (!strncmp(model,"DiMAGE G",8)) { + if (model[8] == '4') { + height = 1716; + width = 2304; + } else if (model[8] == '5') { +konica_510z: + height = 1956; + width = 2607; + raw_width = 2624; + } else if (model[8] == '6') { + height = 2136; + width = 2848; + } + data_offset += 14; + filters = 0x61616161; +konica_400z: + load_raw = &CLASS unpacked_load_raw; + maximum = 0x3df; + order = 0x4d4d; + } + } else if (!strcmp(model,"*ist D")) { + data_error = -1; + } else if (!strcmp(model,"*ist DS")) { + height -= 2; + } else if (!strcmp(model,"K20D")) { + filters = 0x16161616; + } else if (!strcmp(model,"K-x")) { + width = 4309; + filters = 0x16161616; + } else if (!strcmp(model,"Optio S")) { + if (fsize == 3178560) { + height = 1540; + width = 2064; + load_raw = &CLASS eight_bit_load_raw; + cam_mul[0] *= 4; + cam_mul[2] *= 4; + } else { + height = 1544; + width = 2068; + raw_width = 3136; + load_raw = &CLASS packed_load_raw; + maximum = 0xf7c; + } + } else if (fsize == 6114240) { + height = 1737; + width = 2324; + raw_width = 3520; + load_raw = &CLASS packed_load_raw; + maximum = 0xf7a; + } else if (!strcmp(model,"Optio 750Z")) { + height = 2302; + width = 3072; + load_raw = &CLASS packed_load_raw; + load_flags = 30; + } else if (!strcmp(model,"DC-833m")) { + height = 2448; + width = 3264; + order = 0x4949; + filters = 0x61616161; + load_raw = &CLASS unpacked_load_raw; + maximum = 0xfc00; + } else if (!strncmp(model,"S85",3)) { + height = 2448; + width = 3264; + raw_width = fsize/height/2; + order = 0x4d4d; + load_raw = &CLASS unpacked_load_raw; + maximum = 0xffff; + } else if (!strcmp(model,"STV680 VGA")) { + height = 484; + width = 644; + load_raw = &CLASS eight_bit_load_raw; + flip = 2; + filters = 0x16161616; + black = 16; + } else if (!strcmp(model,"N95")) { + height = raw_height - (top_margin = 2); + } else if (!strcmp(model,"531C")) { + height = 1200; + width = 1600; + load_raw = &CLASS unpacked_load_raw; + filters = 0x49494949; + } else if (!strcmp(model,"F-080C")) { + height = 768; + width = 1024; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"F-145C")) { + height = 1040; + width = 1392; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"F-201C")) { + height = 1200; + width = 1600; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"F-510C")) { + height = 1958; + width = 2588; + load_raw = fsize < 7500000 ? + &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw; + maximum = 0xfff0; + } else if (!strcmp(model,"F-810C")) { + height = 2469; + width = 3272; + load_raw = &CLASS unpacked_load_raw; + maximum = 0xfff0; + } else if (!strcmp(model,"XCD-SX910CR")) { + height = 1024; + width = 1375; + raw_width = 1376; + filters = 0x49494949; + maximum = 0x3ff; + load_raw = fsize < 2000000 ? + &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw; + } else if (!strcmp(model,"2010")) { + height = 1207; + width = 1608; + order = 0x4949; + filters = 0x16161616; + data_offset = 3212; + maximum = 0x3ff; + load_raw = &CLASS unpacked_load_raw; + } else if (!strcmp(model,"A782")) { + height = 3000; + width = 2208; + filters = 0x61616161; + load_raw = fsize < 10000000 ? + &CLASS eight_bit_load_raw : &CLASS unpacked_load_raw; + maximum = 0xffc0; + } else if (!strcmp(model,"3320AF")) { + height = 1536; + raw_width = width = 2048; + filters = 0x61616161; + load_raw = &CLASS unpacked_load_raw; + maximum = 0x3ff; + fseek (ifp, 0x300000, SEEK_SET); + if ((order = guess_byte_order(0x10000)) == 0x4d4d) { + height -= (top_margin = 16); + width -= (left_margin = 28); + maximum = 0xf5c0; + strcpy (make, "ISG"); + model[0] = 0; + } + } else if (!strcmp(make,"Hasselblad")) { + if (load_raw == &CLASS lossless_jpeg_load_raw) + load_raw = &CLASS hasselblad_load_raw; + if (raw_width == 7262) { + height = 5444; + width = 7248; + top_margin = 4; + left_margin = 7; + filters = 0x61616161; + } else if (raw_width == 4090) { + strcpy (model, "V96C"); + height -= (top_margin = 6); + width -= (left_margin = 3) + 7; + filters = 0x61616161; + } + } else if (!strcmp(make,"Sinar")) { + if (!memcmp(head,"8BPS",4)) { + fseek (ifp, 14, SEEK_SET); + height = get4(); + width = get4(); + filters = 0x61616161; + data_offset = 68; + } + if (!load_raw) load_raw = &CLASS unpacked_load_raw; + maximum = 0x3fff; + } else if (!strcmp(make,"Leaf")) { + maximum = 0x3fff; + fseek (ifp, data_offset, SEEK_SET); + if (ljpeg_start (&jh, 1) && jh.bits == 15) + maximum = 0x1fff; + if (tiff_samples > 1) filters = 0; + if (tiff_samples > 1 || tile_length < raw_height) + load_raw = &CLASS leaf_hdr_load_raw; + if ((width | height) == 2048) { + if (tiff_samples == 1) { + filters = 1; + strcpy (cdesc, "RBTG"); + strcpy (model, "CatchLight"); + top_margin = 8; left_margin = 18; height = 2032; width = 2016; + } else { + strcpy (model, "DCB2"); + top_margin = 10; left_margin = 16; height = 2028; width = 2022; + } + } else if (width+height == 3144+2060) { + if (!model[0]) strcpy (model, "Cantare"); + if (width > height) { + top_margin = 6; left_margin = 32; height = 2048; width = 3072; + filters = 0x61616161; + } else { + left_margin = 6; top_margin = 32; width = 2048; height = 3072; + filters = 0x16161616; + } + if (!cam_mul[0] || model[0] == 'V') filters = 0; + else is_raw = tiff_samples; + } else if (width == 2116) { + strcpy (model, "Valeo 6"); + height -= 2 * (top_margin = 30); + width -= 2 * (left_margin = 55); + filters = 0x49494949; + } else if (width == 3171) { + strcpy (model, "Valeo 6"); + height -= 2 * (top_margin = 24); + width -= 2 * (left_margin = 24); + filters = 0x16161616; + } + } else if (!strcmp(make,"LEICA") || !strcmp(make,"Panasonic")) { + maximum = 0xfff0; + if ((fsize-data_offset) / (width*8/7) == height) + load_raw = &CLASS panasonic_load_raw; + if (!load_raw) load_raw = &CLASS unpacked_load_raw; + switch (width) { + case 2568: + adobe_coeff ("Panasonic","DMC-LC1"); break; + case 3130: + left_margin = -14; + case 3170: + left_margin += 18; + width = 3096; + if (height > 2326) { + height = 2326; + top_margin = 13; + filters = 0x49494949; + } + zero_is_bad = 1; + adobe_coeff ("Panasonic","DMC-FZ8"); break; + case 3213: + width -= 27; + case 3177: + width -= 10; + filters = 0x49494949; + zero_is_bad = 1; + adobe_coeff ("Panasonic","DMC-L1"); break; + case 3304: + width -= 17; + zero_is_bad = 1; + adobe_coeff ("Panasonic","DMC-FZ30"); break; + case 3330: + width += 43; + left_margin = -6; + maximum = 0xf7f0; + case 3370: + width -= 82; + left_margin += 15; + if (height > 2480) + height = 2480 - (top_margin = 10); + filters = 0x49494949; + zero_is_bad = 1; + adobe_coeff ("Panasonic","DMC-FZ18"); break; + case 3690: + height -= 2; + left_margin = -14; + maximum = 0xf7f0; + case 3770: + width = 3672; + if (--height == 2798 && (height = 2760)) + top_margin = 15; + else filters = 0x49494949; + left_margin += 17; + zero_is_bad = 1; + adobe_coeff ("Panasonic","DMC-FZ50"); break; + case 3710: + width = 3682; + filters = 0x49494949; + adobe_coeff ("Panasonic","DMC-L10"); break; + case 3724: + width -= 14; + if (height == 2450) height -= 2; + case 3836: + width -= 42; +lx3: filters = 0x16161616; + if (make[0] != 'P') + adobe_coeff ("Panasonic","DMC-LX3"); + break; + case 3880: + width -= 22; + left_margin = 6; + zero_is_bad = 1; + adobe_coeff ("Panasonic","DMC-LX1"); break; + case 4060: + width = 3982; + if (height == 2250) goto lx3; + width = 4018; + filters = 0x16161616; + if (!strncmp(model,"DMC-FZ3",7)) { + height -= 2; + adobe_coeff ("Panasonic","DMC-FZ35"); break; + } + filters = 0x49494949; + if (!strcmp(model,"DMC-GH1")) break; + zero_is_bad = 1; + adobe_coeff ("Panasonic","DMC-G1"); break; + case 4172: + case 4396: + width -= 28; + filters = 0x49494949; + adobe_coeff ("Panasonic","DMC-GH1"); break; + case 4290: + height += 38; + left_margin = -14; + filters = 0x49494949; + case 4330: + width = 4248; + if ((height -= 39) == 2400) + top_margin = 15; + left_margin += 17; + adobe_coeff ("Panasonic","DMC-LX2"); break; + case 4508: + height -= 6; + width = 4429; + filters = 0x16161616; + adobe_coeff ("Panasonic","DMC-FX150"); break; + } + } else if (!strcmp(model,"C770UZ")) { + height = 1718; + width = 2304; + filters = 0x16161616; + load_raw = &CLASS packed_load_raw; + load_flags = 30; + } else if (!strcmp(make,"OLYMPUS")) { + height += height & 1; + filters = exif_cfa; + if (width == 4100) width -= 4; + if (load_raw == &CLASS olympus_load_raw) { + tiff_bps = 12; + black >>= 4; + } else if (!strcmp(model,"E-10") || + !strncmp(model,"E-20",4)) { + black <<= 2; + } else if (!strcmp(model,"E-300") || + !strcmp(model,"E-500")) { + width -= 20; + if (load_raw == &CLASS unpacked_load_raw) { + maximum = 0xfc30; + black = 0; + } + } else if (!strcmp(model,"E-330")) { + width -= 30; + if (load_raw == &CLASS unpacked_load_raw) + maximum = 0xf790; + } else if (!strcmp(model,"SP550UZ")) { + thumb_length = fsize - (thumb_offset = 0xa39800); + thumb_height = 480; + thumb_width = 640; + } + } else if (!strcmp(model,"N Digital")) { + height = 2047; + width = 3072; + filters = 0x61616161; + data_offset = 0x1a00; + load_raw = &CLASS packed_load_raw; + } else if (!strcmp(model,"DSC-F828")) { + width = 3288; + left_margin = 5; + data_offset = 862144; + load_raw = &CLASS sony_load_raw; + filters = 0x9c9c9c9c; + colors = 4; + strcpy (cdesc, "RGBE"); + } else if (!strcmp(model,"DSC-V3")) { + width = 3109; + left_margin = 59; + data_offset = 787392; + load_raw = &CLASS sony_load_raw; + } else if (!strcmp(make,"SONY") && raw_width == 3984) { + adobe_coeff ("SONY","DSC-R1"); + width = 3925; + order = 0x4d4d; + } else if (!strcmp(model,"DSLR-A100")) { + height--; + width = ++raw_width; + filters = 0x61616161; + } else if (!strcmp(model,"DSLR-A350")) { + height -= 4; + } else if (!strcmp(model,"PIXL")) { + height -= top_margin = 4; + width -= left_margin = 32; + gamma_curve (0, 7, 1, 255); + } else if (!strcmp(model,"C603v")) { + height = 480; + width = 640; + if (fsize < 614400 || find_green (16, 16, 3840, 5120) < 25) goto c603v; + strcpy (model,"KAI-0340"); + height -= 3; + data_offset = 3840; + order = 0x4949; + load_raw = &CLASS unpacked_load_raw; + } else if (!strcmp(model,"C603y")) { + height = 2134; + width = 2848; +c603v: + filters = 0; + load_raw = &CLASS kodak_yrgb_load_raw; + gamma_curve (0, 3.875, 1, 255); + } else if (!strcmp(model,"C603")) { + raw_height = height = 2152; + raw_width = width = 2864; + goto c603; + } else if (!strcmp(model,"C330")) { + height = 1744; + width = 2336; + raw_height = 1779; + raw_width = 2338; + top_margin = 33; + left_margin = 1; +c603: + order = 0x4949; + if ((data_offset = fsize - raw_height*raw_width)) { + fseek (ifp, 168, SEEK_SET); + read_shorts (curve, 256); + } else gamma_curve (0, 3.875, 1, 255); + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"EASYSHARE Z1015 IS")) { + height = 2742; + width = 3664; + goto ezshare; + } else if (!strcmp(model,"EasyShare Z980")) { + height = 3006; + width = 4016; +ezshare: + data_offset = 0x15000; + load_raw = &CLASS packed_load_raw; + } else if (!strcasecmp(make,"KODAK")) { + if (filters == UINT_MAX) filters = 0x61616161; + if (!strncmp(model,"NC2000",6)) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"EOSDCS3B")) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"EOSDCS1")) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"DCS420")) { + width -= 4; + left_margin = 2; + } else if (!strncmp(model,"DCS460 ",7)) { + model[6] = 0; + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"DCS460A")) { + width -= 4; + left_margin = 2; + colors = 1; + filters = 0; + } else if (!strcmp(model,"DCS660M")) { + black = 214; + colors = 1; + filters = 0; + } else if (!strcmp(model,"DCS760M")) { + colors = 1; + filters = 0; + } + if (!strcmp(model+4,"20X")) + strcpy (cdesc, "MYCY"); + if (strstr(model,"DC25")) { + strcpy (model, "DC25"); + data_offset = 15424; + } + if (!strncmp(model,"DC2",3)) { + height = 242; + if (fsize < 100000) { + raw_width = 256; width = 249; + pixel_aspect = (4.0*height) / (3.0*width); + } else { + raw_width = 512; width = 501; + pixel_aspect = (493.0*height) / (373.0*width); + } + data_offset += raw_width + 1; + colors = 4; + filters = 0x8d8d8d8d; + simple_coeff(1); + pre_mul[1] = 1.179; + pre_mul[2] = 1.209; + pre_mul[3] = 1.036; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"40")) { + strcpy (model, "DC40"); + height = 512; + width = 768; + data_offset = 1152; + load_raw = &CLASS kodak_radc_load_raw; + } else if (strstr(model,"DC50")) { + strcpy (model, "DC50"); + height = 512; + width = 768; + data_offset = 19712; + load_raw = &CLASS kodak_radc_load_raw; + } else if (strstr(model,"DC120")) { + strcpy (model, "DC120"); + height = 976; + width = 848; + pixel_aspect = height/0.75/width; + load_raw = tiff_compress == 7 ? + &CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw; + } else if (!strcmp(model,"DCS200")) { + thumb_height = 128; + thumb_width = 192; + thumb_offset = 6144; + thumb_misc = 360; + write_thumb = &CLASS layer_thumb; + height = 1024; + width = 1536; + data_offset = 79872; + load_raw = &CLASS eight_bit_load_raw; + black = 17; + } + } else if (!strcmp(model,"Fotoman Pixtura")) { + height = 512; + width = 768; + data_offset = 3632; + load_raw = &CLASS kodak_radc_load_raw; + filters = 0x61616161; + simple_coeff(2); + } else if (!strcmp(model,"QuickTake 100")) { + fseek (ifp, 544, SEEK_SET); + height = get2(); + width = get2(); + data_offset = (get4(),get2()) == 30 ? 738:736; + if (height > width) { + SWAP(height,width); + fseek (ifp, data_offset-6, SEEK_SET); + flip = ~get2() & 3 ? 5:6; + } + load_raw = &CLASS quicktake_100_load_raw; + filters = 0x61616161; + } else if (!strcmp(model,"QuickTake 150")) { + data_offset = 738 - head[5]; + if (head[5]) strcpy (model+10, "200"); + load_raw = &CLASS kodak_radc_load_raw; + height = 480; + width = 640; + filters = 0x61616161; + } else if (!strcmp(make,"Rollei") && !load_raw) { + switch (raw_width) { + case 1316: + height = 1030; + width = 1300; + top_margin = 1; + left_margin = 6; + break; + case 2568: + height = 1960; + width = 2560; + top_margin = 2; + left_margin = 8; + } + filters = 0x16161616; + load_raw = &CLASS rollei_load_raw; + } else if (!strcmp(model,"PC-CAM 600")) { + height = 768; + data_offset = width = 1024; + filters = 0x49494949; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"QV-2000UX")) { + height = 1208; + width = 1632; + data_offset = width * 2; + load_raw = &CLASS eight_bit_load_raw; + } else if (fsize == 3217760) { + height = 1546; + width = 2070; + raw_width = 2080; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"QV-4000")) { + height = 1700; + width = 2260; + load_raw = &CLASS unpacked_load_raw; + maximum = 0xffff; + } else if (!strcmp(model,"QV-5700")) { + height = 1924; + width = 2576; + raw_width = 3232; + tiff_bps = 10; + } else if (!strcmp(model,"QV-R41")) { + height = 1720; + width = 2312; + raw_width = 3520; + left_margin = 2; + } else if (!strcmp(model,"QV-R51")) { + height = 1926; + width = 2580; + raw_width = 3904; + } else if (!strcmp(model,"EX-S20")) { + height = 1208; + width = 1620; + raw_width = 2432; + flip = 3; + } else if (!strcmp(model,"EX-S100")) { + height = 1544; + width = 2058; + raw_width = 3136; + } else if (!strcmp(model,"EX-Z50")) { + height = 1931; + width = 2570; + raw_width = 3904; + } else if (!strcmp(model,"EX-Z55")) { + height = 1960; + width = 2570; + raw_width = 3904; + } else if (!strcmp(model,"EX-Z60")) { + height = 2145; + width = 2833; + raw_width = 3584; + filters = 0x16161616; + tiff_bps = 10; + } else if (!strcmp(model,"EX-Z75")) { + height = 2321; + width = 3089; + raw_width = 4672; + maximum = 0xfff; + } else if (!strcmp(model,"EX-Z750")) { + height = 2319; + width = 3087; + raw_width = 4672; + maximum = 0xfff; + } else if (!strcmp(model,"EX-Z850")) { + height = 2468; + width = 3279; + raw_width = 4928; + maximum = 0xfff; + } else if (!strcmp(model,"EX-P505")) { + height = 1928; + width = 2568; + raw_width = 3852; + maximum = 0xfff; + } else if (fsize == 9313536) { /* EX-P600 or QV-R61 */ + height = 2142; + width = 2844; + raw_width = 4288; + } else if (!strcmp(model,"EX-P700")) { + height = 2318; + width = 3082; + raw_width = 4672; + } + if (!model[0]) + sprintf (model, "%dx%d", width, height); + if (filters == UINT_MAX) filters = 0x94949494; + if (raw_color) adobe_coeff (make, model); + if (load_raw == &CLASS kodak_radc_load_raw) + if (raw_color) adobe_coeff ("Apple","Quicktake"); + if (thumb_offset && !thumb_height) { + fseek (ifp, thumb_offset, SEEK_SET); + if (ljpeg_start (&jh, 1)) { + thumb_width = jh.wide; + thumb_height = jh.high; + } + } +dng_skip: + if (!tiff_bps) tiff_bps = 12; + if (!maximum) maximum = (1 << tiff_bps) - 1; + if (!load_raw || height < 22) is_raw = 0; +#ifdef NO_JPEG + if (load_raw == &CLASS kodak_jpeg_load_raw) { + fprintf (stderr,_("%s: You must link dcraw with libjpeg!!\n"), ifname); + is_raw = 0; + } +#endif + if (!cdesc[0]) + strcpy (cdesc, colors == 3 ? "RGB":"GMCY"); + if (!raw_height) raw_height = height; + if (!raw_width ) raw_width = width; + if (filters && colors == 3) + for (i=0; i < 32; i+=4) { + if ((filters >> i & 15) == 9) + filters |= 2 << i; + if ((filters >> i & 15) == 6) + filters |= 8 << i; + } +notraw: + if (flip == -1) flip = tiff_flip; + if (flip == -1) flip = 0; +} + +#ifndef NO_LCMS +void CLASS apply_profile (const char *input, const char *output) +{ + char *prof; + cmsHPROFILE hInProfile=0, hOutProfile=0; + cmsHTRANSFORM hTransform; + FILE *fp; + unsigned size; + + cmsErrorAction (LCMS_ERROR_SHOW); + if (strcmp (input, "embed")) + hInProfile = cmsOpenProfileFromFile (input, "r"); + else if (profile_length) { + prof = (char *) malloc (profile_length); + merror (prof, "apply_profile()"); + fseek (ifp, profile_offset, SEEK_SET); + fread (prof, 1, profile_length, ifp); + hInProfile = cmsOpenProfileFromMem (prof, profile_length); + free (prof); + } else + fprintf (stderr,_("%s has no embedded profile.\n"), ifname); + if (!hInProfile) return; + if (!output) + hOutProfile = cmsCreate_sRGBProfile(); + else if ((fp = fopen (output, "rb"))) { + fread (&size, 4, 1, fp); + fseek (fp, 0, SEEK_SET); + oprof = (unsigned *) malloc (size = ntohl(size)); + merror (oprof, "apply_profile()"); + fread (oprof, 1, size, fp); + fclose (fp); + if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) { + free (oprof); + oprof = 0; + } + } else + fprintf (stderr,_("Cannot open file %s!\n"), output); + if (!hOutProfile) goto quit; + if (verbose) + fprintf (stderr,_("Applying color profile...\n")); + hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16, + hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0); + cmsDoTransform (hTransform, image, image, width*height); + raw_color = 1; /* Don't use rgb_cam with a profile */ + cmsDeleteTransform (hTransform); + cmsCloseProfile (hOutProfile); +quit: + cmsCloseProfile (hInProfile); +} +#endif + +void CLASS convert_to_rgb() +{ + int row, col, c, i, j, k; + ushort *img; + float out[3], out_cam[3][4]; + double num, inverse[3][3]; + static const double xyzd50_srgb[3][3] = + { { 0.436083, 0.385083, 0.143055 }, + { 0.222507, 0.716888, 0.060608 }, + { 0.013930, 0.097097, 0.714022 } }; + static const double rgb_rgb[3][3] = + { { 1,0,0 }, { 0,1,0 }, { 0,0,1 } }; + static const double adobe_rgb[3][3] = + { { 0.715146, 0.284856, 0.000000 }, + { 0.000000, 1.000000, 0.000000 }, + { 0.000000, 0.041166, 0.958839 } }; + static const double wide_rgb[3][3] = + { { 0.593087, 0.404710, 0.002206 }, + { 0.095413, 0.843149, 0.061439 }, + { 0.011621, 0.069091, 0.919288 } }; + static const double prophoto_rgb[3][3] = + { { 0.529317, 0.330092, 0.140588 }, + { 0.098368, 0.873465, 0.028169 }, + { 0.016879, 0.117663, 0.865457 } }; + static const double (*out_rgb[])[3] = + { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb }; + static const char *name[] = + { "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ" }; + static const unsigned phead[] = + { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0, + 0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d }; + unsigned pbody[] = + { 10, 0x63707274, 0, 36, /* cprt */ + 0x64657363, 0, 40, /* desc */ + 0x77747074, 0, 20, /* wtpt */ + 0x626b7074, 0, 20, /* bkpt */ + 0x72545243, 0, 14, /* rTRC */ + 0x67545243, 0, 14, /* gTRC */ + 0x62545243, 0, 14, /* bTRC */ + 0x7258595a, 0, 20, /* rXYZ */ + 0x6758595a, 0, 20, /* gXYZ */ + 0x6258595a, 0, 20 }; /* bXYZ */ + static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc }; + unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 }; + + gamma_curve (gamm[0], gamm[1], 0, 0); + memcpy (out_cam, rgb_cam, sizeof out_cam); + raw_color |= colors == 1 || document_mode || + output_color < 1 || output_color > 5; + if (!raw_color) { + oprof = (unsigned *) calloc (phead[0], 1); + merror (oprof, "convert_to_rgb()"); + memcpy (oprof, phead, sizeof phead); + if (output_color == 5) oprof[4] = oprof[5]; + oprof[0] = 132 + 12*pbody[0]; + for (i=0; i < pbody[0]; i++) { + oprof[oprof[0]/4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874; + pbody[i*3+2] = oprof[0]; + oprof[0] += (pbody[i*3+3] + 3) & -4; + } + memcpy (oprof+32, pbody, sizeof pbody); + oprof[pbody[5]/4+2] = strlen(name[output_color-1]) + 1; + memcpy ((char *)oprof+pbody[8]+8, pwhite, sizeof pwhite); + pcurve[3] = (short)(256/gamm[5]+0.5) << 16; + for (i=4; i < 7; i++) + memcpy ((char *)oprof+pbody[i*3+2], pcurve, sizeof pcurve); + pseudoinverse ((double (*)[3]) out_rgb[output_color-1], inverse, 3); + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) { + for (num = k=0; k < 3; k++) + num += xyzd50_srgb[i][k] * inverse[j][k]; + oprof[pbody[j*3+23]/4+i+2] = num * 0x10000 + 0.5; + } + for (i=0; i < phead[0]/4; i++) + oprof[i] = htonl(oprof[i]); + strcpy ((char *)oprof+pbody[2]+8, "auto-generated by dcraw"); + strcpy ((char *)oprof+pbody[5]+12, name[output_color-1]); + for (i=0; i < 3; i++) + for (j=0; j < colors; j++) + for (out_cam[i][j] = k=0; k < 3; k++) + out_cam[i][j] += out_rgb[output_color-1][i][k] * rgb_cam[k][j]; + } + if (verbose) + fprintf (stderr, raw_color ? _("Building histograms...\n") : + _("Converting to %s colorspace...\n"), name[output_color-1]); + + memset (histogram, 0, sizeof histogram); + for (img=image[0], row=0; row < height; row++) + for (col=0; col < width; col++, img+=4) { + if (!raw_color) { + out[0] = out[1] = out[2] = 0; + FORCC { + out[0] += out_cam[0][c] * img[c]; + out[1] += out_cam[1][c] * img[c]; + out[2] += out_cam[2][c] * img[c]; + } + FORC3 img[c] = CLIP((int) out[c]); + } + else if (document_mode) + img[0] = img[FC(row,col)]; + FORCC histogram[c][img[c] >> 3]++; + } + if (colors == 4 && output_color) colors = 3; + if (document_mode && filters) colors = 1; +} + +void CLASS fuji_rotate() +{ + int i, row, col; + double step; + float r, c, fr, fc; + unsigned ur, uc; + ushort wide, high, (*img)[4], (*pix)[4]; + + if (!fuji_width) return; + if (verbose) + fprintf (stderr,_("Rotating image 45 degrees...\n")); + fuji_width = (fuji_width - 1 + shrink) >> shrink; + step = sqrt(0.5); + wide = fuji_width / step; + high = (height - fuji_width) / step; + img = (ushort (*)[4]) calloc (wide*high, sizeof *img); + merror (img, "fuji_rotate()"); + + for (row=0; row < high; row++) + for (col=0; col < wide; col++) { + ur = r = fuji_width + (row-col)*step; + uc = c = (row+col)*step; + if (ur > height-2 || uc > width-2) continue; + fr = r - ur; + fc = c - uc; + pix = image + ur*width + uc; + for (i=0; i < colors; i++) + img[row*wide+col][i] = + (pix[ 0][i]*(1-fc) + pix[ 1][i]*fc) * (1-fr) + + (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr; + } + free (image); + width = wide; + height = high; + image = img; + fuji_width = 0; +} + +void CLASS stretch() +{ + ushort newdim, (*img)[4], *pix0, *pix1; + int row, col, c; + double rc, frac; + + if (pixel_aspect == 1) return; + if (verbose) fprintf (stderr,_("Stretching the image...\n")); + if (pixel_aspect < 1) { + newdim = height / pixel_aspect + 0.5; + img = (ushort (*)[4]) calloc (width*newdim, sizeof *img); + merror (img, "stretch()"); + for (rc=row=0; row < newdim; row++, rc+=pixel_aspect) { + frac = rc - (c = rc); + pix0 = pix1 = image[c*width]; + if (c+1 < height) pix1 += width*4; + for (col=0; col < width; col++, pix0+=4, pix1+=4) + FORCC img[row*width+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5; + } + height = newdim; + } else { + newdim = width * pixel_aspect + 0.5; + img = (ushort (*)[4]) calloc (height*newdim, sizeof *img); + merror (img, "stretch()"); + for (rc=col=0; col < newdim; col++, rc+=1/pixel_aspect) { + frac = rc - (c = rc); + pix0 = pix1 = image[c]; + if (c+1 < width) pix1 += 4; + for (row=0; row < height; row++, pix0+=width*4, pix1+=width*4) + FORCC img[row*newdim+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5; + } + width = newdim; + } + free (image); + image = img; +} + +int CLASS flip_index (int row, int col) +{ + if (flip & 4) SWAP(row,col); + if (flip & 2) row = iheight - 1 - row; + if (flip & 1) col = iwidth - 1 - col; + return row * iwidth + col; +} + +struct tiff_tag { + ushort tag, type; + int count; + union { char c[4]; short s[2]; int i; } val; +}; + +struct tiff_hdr { + ushort order, magic; + int ifd; + ushort pad, ntag; + struct tiff_tag tag[23]; + int nextifd; + ushort pad2, nexif; + struct tiff_tag exif[4]; + ushort pad3, ngps; + struct tiff_tag gpst[10]; + short bps[4]; + int rat[10]; + unsigned gps[26]; + char desc[512], make[64], model[64], soft[32], date[20], artist[64]; +}; + +void CLASS tiff_set (ushort *ntag, + ushort tag, ushort type, int count, int val) +{ + struct tiff_tag *tt; + int c; + + tt = (struct tiff_tag *)(ntag+1) + (*ntag)++; + tt->tag = tag; + tt->type = type; + tt->count = count; + if (type < 3 && count <= 4) + FORC(4) tt->val.c[c] = val >> (c << 3); + else if (type == 3 && count <= 2) + FORC(2) tt->val.s[c] = val >> (c << 4); + else tt->val.i = val; +} + +#define TOFF(ptr) ((char *)(&(ptr)) - (char *)th) + +void CLASS tiff_head (struct tiff_hdr *th, int full) +{ + int c, psize=0; + struct tm *t; + + memset (th, 0, sizeof *th); + th->order = htonl(0x4d4d4949) >> 16; + th->magic = 42; + th->ifd = 10; + if (full) { + tiff_set (&th->ntag, 254, 4, 1, 0); + tiff_set (&th->ntag, 256, 4, 1, width); + tiff_set (&th->ntag, 257, 4, 1, height); + tiff_set (&th->ntag, 258, 3, colors, output_bps); + if (colors > 2) + th->tag[th->ntag-1].val.i = TOFF(th->bps); + FORC4 th->bps[c] = output_bps; + tiff_set (&th->ntag, 259, 3, 1, 1); + tiff_set (&th->ntag, 262, 3, 1, 1 + (colors > 1)); + } + tiff_set (&th->ntag, 270, 2, 512, TOFF(th->desc)); + tiff_set (&th->ntag, 271, 2, 64, TOFF(th->make)); + tiff_set (&th->ntag, 272, 2, 64, TOFF(th->model)); + if (full) { + if (oprof) psize = ntohl(oprof[0]); + tiff_set (&th->ntag, 273, 4, 1, sizeof *th + psize); + tiff_set (&th->ntag, 277, 3, 1, colors); + tiff_set (&th->ntag, 278, 4, 1, height); + tiff_set (&th->ntag, 279, 4, 1, height*width*colors*output_bps/8); + } else + tiff_set (&th->ntag, 274, 3, 1, "12435867"[flip]-'0'); + tiff_set (&th->ntag, 282, 5, 1, TOFF(th->rat[0])); + tiff_set (&th->ntag, 283, 5, 1, TOFF(th->rat[2])); + tiff_set (&th->ntag, 284, 3, 1, 1); + tiff_set (&th->ntag, 296, 3, 1, 2); + tiff_set (&th->ntag, 305, 2, 32, TOFF(th->soft)); + tiff_set (&th->ntag, 306, 2, 20, TOFF(th->date)); + tiff_set (&th->ntag, 315, 2, 64, TOFF(th->artist)); + tiff_set (&th->ntag, 34665, 4, 1, TOFF(th->nexif)); + if (psize) tiff_set (&th->ntag, 34675, 7, psize, sizeof *th); + tiff_set (&th->nexif, 33434, 5, 1, TOFF(th->rat[4])); + tiff_set (&th->nexif, 33437, 5, 1, TOFF(th->rat[6])); + tiff_set (&th->nexif, 34855, 3, 1, iso_speed); + tiff_set (&th->nexif, 37386, 5, 1, TOFF(th->rat[8])); + if (gpsdata[1]) { + tiff_set (&th->ntag, 34853, 4, 1, TOFF(th->ngps)); + tiff_set (&th->ngps, 0, 1, 4, 0x202); + tiff_set (&th->ngps, 1, 2, 2, gpsdata[29]); + tiff_set (&th->ngps, 2, 5, 3, TOFF(th->gps[0])); + tiff_set (&th->ngps, 3, 2, 2, gpsdata[30]); + tiff_set (&th->ngps, 4, 5, 3, TOFF(th->gps[6])); + tiff_set (&th->ngps, 5, 1, 1, gpsdata[31]); + tiff_set (&th->ngps, 6, 5, 1, TOFF(th->gps[18])); + tiff_set (&th->ngps, 7, 5, 3, TOFF(th->gps[12])); + tiff_set (&th->ngps, 18, 2, 12, TOFF(th->gps[20])); + tiff_set (&th->ngps, 29, 2, 12, TOFF(th->gps[23])); + memcpy (th->gps, gpsdata, sizeof th->gps); + } + th->rat[0] = th->rat[2] = 300; + th->rat[1] = th->rat[3] = 1; + FORC(6) th->rat[4+c] = 1000000; + th->rat[4] *= shutter; + th->rat[6] *= aperture; + th->rat[8] *= focal_len; + strncpy (th->desc, desc, 512); + strncpy (th->make, make, 64); + strncpy (th->model, model, 64); + strcpy (th->soft, "dcraw v"VERSION); + t = gmtime (×tamp); + sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d", + t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec); + strncpy (th->artist, artist, 64); +} + +void CLASS jpeg_thumb() +{ + char *thumb; + ushort exif[5]; + struct tiff_hdr th; + + thumb = (char *) malloc (thumb_length); + merror (thumb, "jpeg_thumb()"); + fread (thumb, 1, thumb_length, ifp); + fputc (0xff, ofp); + fputc (0xd8, ofp); + if (strcmp (thumb+6, "Exif")) { + memcpy (exif, "\xff\xe1 Exif\0\0", 10); + exif[1] = htons (8 + sizeof th); + fwrite (exif, 1, sizeof exif, ofp); + tiff_head (&th, 0); + fwrite (&th, 1, sizeof th, ofp); + } + fwrite (thumb+2, 1, thumb_length-2, ofp); + free (thumb); +} + +void CLASS write_ppm_tiff() +{ + struct tiff_hdr th; + uchar *ppm; + ushort *ppm2; + int c, row, col, soff, rstep, cstep; + int perc, val, total, white=0x2000; + + perc = width * height * 0.01; /* 99th percentile white level */ + if (fuji_width) perc /= 2; + if (!((highlight & ~2) || no_auto_bright)) + for (white=c=0; c < colors; c++) { + for (val=0x2000, total=0; --val > 32; ) + if ((total += histogram[c][val]) > perc) break; + if (white < val) white = val; + } + gamma_curve (gamm[0], gamm[1], 2, (white << 3)/bright); + iheight = height; + iwidth = width; + if (flip & 4) SWAP(height,width); + ppm = (uchar *) calloc (width, colors*output_bps/8); + ppm2 = (ushort *) ppm; + merror (ppm, "write_ppm_tiff()"); + if (output_tiff) { + tiff_head (&th, 1); + fwrite (&th, sizeof th, 1, ofp); + if (oprof) + fwrite (oprof, ntohl(oprof[0]), 1, ofp); + } else if (colors > 3) + fprintf (ofp, + "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n", + width, height, colors, (1 << output_bps)-1, cdesc); + else + fprintf (ofp, "P%d\n%d %d\n%d\n", + colors/2+5, width, height, (1 << output_bps)-1); + soff = flip_index (0, 0); + cstep = flip_index (0, 1) - soff; + rstep = flip_index (1, 0) - flip_index (0, width); + for (row=0; row < height; row++, soff += rstep) { + for (col=0; col < width; col++, soff += cstep) + if (output_bps == 8) + FORCC ppm [col*colors+c] = curve[image[soff][c]] >> 8; + else FORCC ppm2[col*colors+c] = curve[image[soff][c]]; + if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa) + swab ((char*)ppm2, (char*)ppm2, width*colors*2); + fwrite (ppm, colors*output_bps/8, width, ofp); + } + free (ppm); +} + +/*int CLASS main (int argc, const char **argv) +{ + int arg, status=0; + int timestamp_only=0, thumbnail_only=0, identify_only=0; + int user_qual=-1, user_black=-1, user_sat=-1, user_flip=-1; + int use_fuji_rotate=1, write_to_stdout=0, quality, i, c; + const char *sp, *bpfile=0, *dark_frame=0, *write_ext; + char opm, opt, *ofname, *cp; + struct utimbuf ut; +#ifndef NO_LCMS + const char *cam_profile=0, *out_profile=0; +#endif + +#ifndef LOCALTIME + putenv ((char *) "TZ=UTC"); +#endif +#ifdef LOCALEDIR + setlocale (LC_CTYPE, ""); + setlocale (LC_MESSAGES, ""); + bindtextdomain ("dcraw", LOCALEDIR); + textdomain ("dcraw"); +#endif + + if (argc == 1) { + printf(_("\nRaw photo decoder \"dcraw\" v%s"), VERSION); + printf(_("\nby Dave Coffin, dcoffin a cybercom o net\n")); + printf(_("\nUsage: %s [OPTION]... [FILE]...\n\n"), argv[0]); + puts(_("-v Print verbose messages")); + puts(_("-c Write image data to standard output")); + puts(_("-e Extract embedded thumbnail image")); + puts(_("-i Identify files without decoding them")); + puts(_("-i -v Identify files and show metadata")); + puts(_("-z Change file dates to camera timestamp")); + puts(_("-w Use camera white balance, if possible")); + puts(_("-a Average the whole image for white balance")); + puts(_("-A Average a grey box for white balance")); + puts(_("-r Set custom white balance")); + puts(_("+M/-M Use/don't use an embedded color matrix")); + puts(_("-C Correct chromatic aberration")); + puts(_("-P Fix the dead pixels listed in this file")); + puts(_("-K Subtract dark frame (16-bit raw PGM)")); + puts(_("-k Set the darkness level")); + puts(_("-S Set the saturation level")); + puts(_("-n Set threshold for wavelet denoising")); + puts(_("-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)")); + puts(_("-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)")); + puts(_("-o [0-5] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ)")); +#ifndef NO_LCMS + puts(_("-o Apply output ICC profile from file")); + puts(_("-p Apply camera ICC profile from file or \"embed\"")); +#endif + puts(_("-d Document mode (no color, no interpolation)")); + puts(_("-D Document mode without scaling (totally raw)")); + puts(_("-j Don't stretch or rotate raw pixels")); + puts(_("-W Don't automatically brighten the image")); + puts(_("-b Adjust brightness (default = 1.0)")); + puts(_("-g

Set custom gamma curve (default = 2.222 4.5)")); + puts(_("-q [0-3] Set the interpolation quality")); + puts(_("-h Half-size color image (twice as fast as \"-q 0\")")); + puts(_("-f Interpolate RGGB as four colors")); + puts(_("-m Apply a 3x3 median filter to R-G and B-G")); + puts(_("-s [0..N-1] Select one raw image or \"all\" from each file")); + puts(_("-6 Write 16-bit instead of 8-bit")); + puts(_("-4 Linear 16-bit, same as \"-6 -W -g 1 1\"")); + puts(_("-T Write TIFF instead of PPM")); + puts(""); + return 1; + } + argv[argc] = ""; + for (arg=1; (((opm = argv[arg][0]) - 2) | 2) == '+'; ) { + opt = argv[arg++][1]; + if ((cp = (char *) strchr (sp="nbrkStqmHACg", opt))) + for (i=0; i < "114111111422"[cp-sp]-'0'; i++) + if (!isdigit(argv[arg+i][0])) { + fprintf (stderr,_("Non-numeric argument to \"-%c\"\n"), opt); + return 1; + } + switch (opt) { + case 'n': threshold = atof(argv[arg++]); break; + case 'b': bright = atof(argv[arg++]); break; + case 'r': + FORC4 user_mul[c] = atof(argv[arg++]); break; + case 'C': aber[0] = 1 / atof(argv[arg++]); + aber[2] = 1 / atof(argv[arg++]); break; + case 'g': gamm[0] = atof(argv[arg++]); + gamm[1] = atof(argv[arg++]); + if (gamm[0]) gamm[0] = 1/gamm[0]; break; + case 'k': user_black = atoi(argv[arg++]); break; + case 'S': user_sat = atoi(argv[arg++]); break; + case 't': user_flip = atoi(argv[arg++]); break; + case 'q': user_qual = atoi(argv[arg++]); break; + case 'm': med_passes = atoi(argv[arg++]); break; + case 'H': highlight = atoi(argv[arg++]); break; + case 's': + shot_select = abs(atoi(argv[arg])); + multi_out = !strcmp(argv[arg++],"all"); + break; + case 'o': + if (isdigit(argv[arg][0]) && !argv[arg][1]) + output_color = atoi(argv[arg++]); +#ifndef NO_LCMS + else out_profile = argv[arg++]; + break; + case 'p': cam_profile = argv[arg++]; +#endif + break; + case 'P': bpfile = argv[arg++]; break; + case 'K': dark_frame = argv[arg++]; break; + case 'z': timestamp_only = 1; break; + case 'e': thumbnail_only = 1; break; + case 'i': identify_only = 1; break; + case 'c': write_to_stdout = 1; break; + case 'v': verbose = 1; break; + case 'h': half_size = 1; /* "-h" implies "-f" *//* + case 'f': four_color_rgb = 1; break; + case 'A': FORC4 greybox[c] = atoi(argv[arg++]); + case 'a': use_auto_wb = 1; break; + case 'w': use_camera_wb = 1; break; + case 'M': use_camera_matrix = (opm == '+'); break; + case 'D': + case 'd': document_mode = 1 + (opt == 'D'); + case 'j': use_fuji_rotate = 0; break; + case 'W': no_auto_bright = 1; break; + case 'T': output_tiff = 1; break; + case '4': gamm[0] = gamm[1] = + no_auto_bright = 1; + case '6': output_bps = 16; break; + default: + fprintf (stderr,_("Unknown option \"-%c\".\n"), opt); + return 1; + } + } + if (use_camera_matrix < 0) + use_camera_matrix = use_camera_wb; + if (arg == argc) { + fprintf (stderr,_("No files to process.\n")); + return 1; + } + if (write_to_stdout) { + if (isatty(1)) { + fprintf (stderr,_("Will not write an image to the terminal!\n")); + return 1; + } +#if defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__) + if (setmode(1,O_BINARY) < 0) { + perror ("setmode()"); + return 1; + } +#endif + } + for ( ; arg < argc; arg++) { + status = 1; + image = 0; + oprof = 0; + meta_data = ofname = 0; + ofp = stdout; + if (setjmp (failure)) { + if (fileno(ifp) > 2) fclose(ifp); + if (fileno(ofp) > 2) fclose(ofp); + status = 1; + goto cleanup; + } + ifname = argv[arg]; + if (!(ifp = fopen (ifname, "rb"))) { + perror (ifname); + continue; + } + status = (identify(),!is_raw); + if (user_flip >= 0) + flip = user_flip; + switch ((flip+3600) % 360) { + case 270: flip = 5; break; + case 180: flip = 3; break; + case 90: flip = 6; + } + if (timestamp_only) { + if ((status = !timestamp)) + fprintf (stderr,_("%s has no timestamp.\n"), ifname); + else if (identify_only) + printf ("%10ld%10d %s\n", (long) timestamp, shot_order, ifname); + else { + if (verbose) + fprintf (stderr,_("%s time set to %d.\n"), ifname, (int) timestamp); + ut.actime = ut.modtime = timestamp; + utime (ifname, &ut); + } + goto next; + } + write_fun = &CLASS write_ppm_tiff; + if (thumbnail_only) { + if ((status = !thumb_offset)) { + fprintf (stderr,_("%s has no thumbnail.\n"), ifname); + goto next; + } else if (thumb_load_raw) { + load_raw = thumb_load_raw; + data_offset = thumb_offset; + height = thumb_height; + width = thumb_width; + filters = 0; + } else { + fseek (ifp, thumb_offset, SEEK_SET); + write_fun = write_thumb; + goto thumbnail; + } + } + if (load_raw == &CLASS kodak_ycbcr_load_raw) { + height += height & 1; + width += width & 1; + } + if (identify_only && verbose && make[0]) { + printf (_("\nFilename: %s\n"), ifname); + printf (_("Timestamp: %s"), ctime(×tamp)); + printf (_("Camera: %s %s\n"), make, model); + if (artist[0]) + printf (_("Owner: %s\n"), artist); + if (dng_version) { + printf (_("DNG Version: ")); + for (i=24; i >= 0; i -= 8) + printf ("%d%c", dng_version >> i & 255, i ? '.':'\n'); + } + printf (_("ISO speed: %d\n"), (int) iso_speed); + printf (_("Shutter: ")); + if (shutter > 0 && shutter < 1) + shutter = (printf ("1/"), 1 / shutter); + printf (_("%0.1f sec\n"), shutter); + printf (_("Aperture: f/%0.1f\n"), aperture); + printf (_("Focal length: %0.1f mm\n"), focal_len); + printf (_("Embedded ICC profile: %s\n"), profile_length ? _("yes"):_("no")); + printf (_("Number of raw images: %d\n"), is_raw); + if (pixel_aspect != 1) + printf (_("Pixel Aspect Ratio: %0.6f\n"), pixel_aspect); + if (thumb_offset) + printf (_("Thumb size: %4d x %d\n"), thumb_width, thumb_height); + printf (_("Full size: %4d x %d\n"), raw_width, raw_height); + } else if (!is_raw) + fprintf (stderr,_("Cannot decode file %s\n"), ifname); + if (!is_raw) goto next; + shrink = filters && + (half_size || threshold || aber[0] != 1 || aber[2] != 1); + iheight = (height + shrink) >> shrink; + iwidth = (width + shrink) >> shrink; + if (identify_only) { + if (verbose) { + if (use_fuji_rotate) { + if (fuji_width) { + fuji_width = (fuji_width - 1 + shrink) >> shrink; + iwidth = fuji_width / sqrt(0.5); + iheight = (iheight - fuji_width) / sqrt(0.5); + } else { + if (pixel_aspect < 1) iheight = iheight / pixel_aspect + 0.5; + if (pixel_aspect > 1) iwidth = iwidth * pixel_aspect + 0.5; + } + } + if (flip & 4) + SWAP(iheight,iwidth); + printf (_("Image size: %4d x %d\n"), width, height); + printf (_("Output size: %4d x %d\n"), iwidth, iheight); + printf (_("Raw colors: %d"), colors); + if (filters) { + printf (_("\nFilter pattern: ")); + if (!cdesc[3]) cdesc[3] = 'G'; + for (i=0; i < 16; i++) + putchar (cdesc[fc(i >> 1,i & 1)]); + } + printf (_("\nDaylight multipliers:")); + FORCC printf (" %f", pre_mul[c]); + if (cam_mul[0] > 0) { + printf (_("\nCamera multipliers:")); + FORC4 printf (" %f", cam_mul[c]); + } + putchar ('\n'); + } else + printf (_("%s is a %s %s image.\n"), ifname, make, model); +next: + fclose(ifp); + continue; + } + if (use_camera_matrix && cmatrix[0][0] > 0.25) { + memcpy (rgb_cam, cmatrix, sizeof cmatrix); + raw_color = 0; + } + image = (ushort (*)[4]) calloc (iheight*iwidth, sizeof *image); + merror (image, "main()"); + if (meta_length) { + meta_data = (char *) malloc (meta_length); + merror (meta_data, "main()"); + } + if (verbose) + fprintf (stderr,_("Loading %s %s image from %s ...\n"), + make, model, ifname); + if (shot_select >= is_raw) + fprintf (stderr,_("%s: \"-s %d\" requests a nonexistent image!\n"), + ifname, shot_select); + fseeko (ifp, data_offset, SEEK_SET); + (*load_raw)(); + if (zero_is_bad) remove_zeroes(); + bad_pixels (bpfile); + if (dark_frame) subtract (dark_frame); + quality = 2 + !fuji_width; + if (user_qual >= 0) quality = user_qual; + if (user_black >= 0) black = user_black; + if (user_sat > 0) maximum = user_sat; +#ifdef COLORCHECK + colorcheck(); +#endif + if (is_foveon && !document_mode) foveon_interpolate(); + if (!is_foveon && document_mode < 2) scale_colors(); + pre_interpolate(); + if (filters && !document_mode) { + if (quality == 0) + lin_interpolate(); + else if (quality == 1 || colors > 3) + vng_interpolate(); + else if (quality == 2) + ppg_interpolate(); + else ahd_interpolate(); + } + if (mix_green) + for (colors=3, i=0; i < height*width; i++) + image[i][1] = (image[i][1] + image[i][3]) >> 1; + if (!is_foveon && colors == 3) median_filter(); + if (!is_foveon && highlight == 2) blend_highlights(); + if (!is_foveon && highlight > 2) recover_highlights(); + if (use_fuji_rotate) fuji_rotate(); +#ifndef NO_LCMS + if (cam_profile) apply_profile (cam_profile, out_profile); +#endif + convert_to_rgb(); + if (use_fuji_rotate) stretch(); +thumbnail: + if (write_fun == &CLASS jpeg_thumb) + write_ext = ".jpg"; + else if (output_tiff && write_fun == &CLASS write_ppm_tiff) + write_ext = ".tiff"; + else + write_ext = ".pgm\0.ppm\0.ppm\0.pam" + colors*5-5; + ofname = (char *) malloc (strlen(ifname) + 64); + merror (ofname, "main()"); + if (write_to_stdout) + strcpy (ofname,_("standard output")); + else { + strcpy (ofname, ifname); + if ((cp = strrchr (ofname, '.'))) *cp = 0; + if (multi_out) + sprintf (ofname+strlen(ofname), "_%0*d", + snprintf(0,0,"%d",is_raw-1), shot_select); + if (thumbnail_only) + strcat (ofname, ".thumb"); + strcat (ofname, write_ext); + ofp = fopen (ofname, "wb"); + if (!ofp) { + status = 1; + perror (ofname); + goto cleanup; + } + } + if (verbose) + fprintf (stderr,_("Writing data to %s ...\n"), ofname); + (*write_fun)(); + fclose(ifp); + if (ofp != stdout) fclose(ofp); +cleanup: + if (meta_data) free (meta_data); + if (ofname) free (ofname); + if (oprof) free (oprof); + if (image) free (image); + if (multi_out) { + if (++shot_select < is_raw) arg--; + else shot_select = 0; + } + } + return status; +} +*/ + +#include +#include +#include +#include +#include +#include + +namespace rtengine { + +extern Settings* settings; + +Glib::Mutex* dcrMutex=NULL; + +int loadFujiRaw (const char* fname, struct RawImage *ri) { + + ushort height_r; + ushort width_r; + ushort (*image_r)[4]; + int col; + int row; + int c; + + ushort max_val = pow(2, 14) - 1; + float sat_s; + + ushort *pvalue_r; + ushort *pvalue_s; + float svalue; + float rvalue; + + // Factors between S captors and R captors + const double factor_canal[] = {17.71, 15.75, 18.3, 15.75}; + + static const double xyzd50_srgb[3][3] = + { { 0.436083, 0.385083, 0.143055 }, + { 0.222507, 0.716888, 0.060608 }, + { 0.013930, 0.097097, 0.714022 } }; + +dcrMutex->lock (); + + ifname = fname;//strdup (fname); + image = NULL; + + exif_base = -1; + ciff_base = -1; + ciff_len = -1; + verbose = settings->verbose; + oprof = NULL; + ri->data = NULL; + ri->allocation = NULL; + ri->profile_data = NULL; + ifp = gfopen (fname); + if (!ifp) { + dcrMutex->unlock (); + return 3; + } + + use_camera_wb = 0; + highlight = 1; + half_size = 0; + + // Load image belonging to the R captors + shot_select = 1; + + identify (); + use_camera_wb = 1; + shrink = 0; + + if (settings->verbose) printf ("Loading %s %s image from %s...\n", make, model, fname); + iheight = height; + iwidth = width; + + image = (UshORt (*)[4])calloc (height*width*sizeof *image + meta_length, 1); + image_r = (UshORt (*)[4])calloc (height*width*sizeof *image + meta_length, 1); + meta_data = (char *) (image + height*width); + + if (setjmp (failure)) { + if (image) + free (image); + if (ri->data) + free(ri->data); + fclose (ifp); + dcrMutex->unlock (); + return 100; + } + + fseek (ifp, data_offset, SEEK_SET); + (*load_raw)(); + + memcpy(image_r, image, height*width*sizeof *image + meta_length); + height_r = height; + width_r = width; + free(image); + + // Load image belonging to the S captors + exif_base = -1; + ciff_base = -1; + ciff_len = -1; + verbose = settings->verbose; + oprof = NULL; + ri->data = NULL; + ri->allocation = NULL; + ri->profile_data = NULL; + fseek (ifp, 0, SEEK_SET); + + shot_select = 0; + + use_camera_wb = 0; + highlight = 1; + half_size = 0; + + identify (); + use_camera_wb = 1; + shrink = 0; + + if (settings->verbose) printf ("Loading %s %s image from %s...\n", make, model, fname); + iheight = height; + iwidth = width; + + image = (UshORt (*)[4])calloc (height*width*sizeof *image + meta_length, 1); + meta_data = (char *) (image + height*width); + + if (setjmp (failure)) { + if (image) + free (image); + if (ri->data) + free(ri->data); + fclose (ifp); + dcrMutex->unlock (); + return 100; + } + + fseek (ifp, data_offset, SEEK_SET); + (*load_raw)(); + + // The saturation of the S captors depends of the ISO value + switch((int)iso_speed){ + case 100: + sat_s = 0.82; + break; + default: + sat_s = 0.96; + } + + ushort saturacion = sat_s * max_val; + + // Scale values + for (int row = 0; row < height_r; row++) + for (int col = 0; col < width_r; col++) + FORC4 { + pvalue_r = &image_r[row*width_r+col][c]; + pvalue_s = &image[(row+1)*width+col][c]; + rvalue = *pvalue_r; + svalue = *pvalue_s; + + // If the captors is saturated + if(svalue > saturacion) + svalue = rvalue * factor_canal[c]; + + *pvalue_s = (ushort) CLIP(svalue); + } + + ri->profile_len = 0; + ri->profile_data = NULL; + if (profile_length) { + ri->profile_len = profile_length; + ri->profile_data = (char *) malloc (profile_length); + fseek (ifp, profile_offset, SEEK_SET); + fread (ri->profile_data, 1, profile_length, ifp); + } + + fclose(ifp); + if (zero_is_bad) remove_zeroes(); + + ri->red_multiplier = pre_mul[0]; + ri->green_multiplier = pre_mul[1]; + ri->blue_multiplier = pre_mul[2]; + + // We set up the max value to 65535 for don't scale values. However + // we should execute "scale_colors" to apply the white balance + maximum = 65535; + + scale_colors(); + pre_interpolate (); + + ri->width = width; + ri->height = height; + ri->filters = filters; + + if (filters) { + ri->allocation = (short unsigned int*)calloc(height*width, sizeof(unsigned short)); + ri->data = (unsigned short**)calloc(height, sizeof(unsigned short*)); + for (int i=0; idata[i] = ri->allocation + i*width; + for (int row = 0; row < height; row++) + for (int col = 0; col < width; col++) + if (ISGREEN(ri,row,col)) + ri->data[row][col] = image[row*width+col][1]; + else if (ISRED(ri,row,col)) + ri->data[row][col] = image[row*width+col][0]; + else + ri->data[row][col] = image[row*width+col][2]; + } + else { + ri->allocation = (short unsigned int*)calloc(3*height*width, sizeof(unsigned short)); + ri->data = (unsigned short**)calloc(height, sizeof(unsigned short*)); + for (int i=0; idata[i] = ri->allocation + 3*i*width; + for (int row = 0; row < height; row++) + for (int col = 0; col < width; col++) { + ri->data[row][3*col+0] = image[row*width+col][0]; + ri->data[row][3*col+1] = image[row*width+col][1]; + ri->data[row][3*col+2] = image[row*width+col][2]; + } + } + + if (flip==5) + ri->rotate_deg = 270; + else if (flip==3) + ri->rotate_deg = 180; + else if (flip==6) + ri->rotate_deg = 90; + else + ri->rotate_deg = 0; + + ri->make = strdup (make); + ri->model = strdup (model); + + ri->exifbase = exif_base; + ri->prefilters = pre_filters; + ri->ciff_base = ciff_base; + ri->ciff_len = ciff_len; + + ri->camwb_red = ri->red_multiplier / pre_mul[0]; + ri->camwb_green = ri->green_multiplier / pre_mul[1]; + ri->camwb_blue = ri->blue_multiplier / pre_mul[2]; + + ri->defgain = 1.0 / MIN(MIN(pre_mul[0],pre_mul[1]),pre_mul[2]); + + ri->fuji_width = fuji_width; + + for (int a=0; a < 3; a++) + for (int b=0; b < 3; b++) + ri->coeff[a][b] = rgb_cam[a][b]; + + free (image); + free (image_r); +dcrMutex->unlock (); + return 0; + +} + +int loadRaw (const char* fname, struct RawImage *ri) { + + static const double xyzd50_srgb[3][3] = + { { 0.436083, 0.385083, 0.143055 }, + { 0.222507, 0.716888, 0.060608 }, + { 0.013930, 0.097097, 0.714022 } }; + +dcrMutex->lock (); + + ifname = fname;//strdup (fname); + image = NULL; + + exif_base = -1; + ciff_base = -1; + ciff_len = -1; + verbose = settings->verbose; + oprof = NULL; + ri->data = NULL; + ri->allocation = NULL; + ri->profile_data = NULL; + ifp = gfopen (fname); + if (!ifp) { + dcrMutex->unlock (); + return 3; + } + + use_camera_wb = 0; + highlight = 1; + half_size = 0; + + identify (); + use_camera_wb = 1; + if (!is_raw) { + fclose(ifp); + dcrMutex->unlock (); + return 2; + } + else if (is_raw == 2 && !strcmp("FUJIFILM", make) && !strcmp("FinePix S5Pro", model)) { + fclose(ifp); + dcrMutex->unlock (); + return loadFujiRaw(fname, ri); + } + + shrink = 0; + + if (settings->verbose) printf ("Loading %s %s image from %s...\n", make, model, fname); + iheight = height; + iwidth = width; + + image = (UshORt (*)[4])calloc (height*width*sizeof *image + meta_length, 1); + meta_data = (char *) (image + height*width); + + if (setjmp (failure)) { + if (image) + free (image); + if (ri->data) + free(ri->data); + fclose (ifp); + dcrMutex->unlock (); + return 100; + } + + fseek (ifp, data_offset, SEEK_SET); + (*load_raw)(); + + ri->profile_len = 0; + ri->profile_data = NULL; + if (profile_length) { + ri->profile_len = profile_length; + ri->profile_data = (char *) malloc (profile_length); + fseek (ifp, profile_offset, SEEK_SET); + fread (ri->profile_data, 1, profile_length, ifp); + } + + fclose(ifp); + if (zero_is_bad) remove_zeroes(); + + ri->red_multiplier = pre_mul[0]; + ri->green_multiplier = pre_mul[1]; + ri->blue_multiplier = pre_mul[2]; + + scale_colors(); + pre_interpolate (); + + ri->width = width; + ri->height = height; + ri->filters = filters; + + if (filters) { + ri->allocation = (short unsigned int*)calloc(height*width, sizeof(unsigned short)); + ri->data = (unsigned short**)calloc(height, sizeof(unsigned short*)); + for (int i=0; idata[i] = ri->allocation + i*width; + for (int row = 0; row < height; row++) + for (int col = 0; col < width; col++) + if (ISGREEN(ri,row,col)) + ri->data[row][col] = image[row*width+col][1]; + else if (ISRED(ri,row,col)) + ri->data[row][col] = image[row*width+col][0]; + else + ri->data[row][col] = image[row*width+col][2]; + } + else { + ri->allocation = (short unsigned int*)calloc(3*height*width, sizeof(unsigned short)); + ri->data = (unsigned short**)calloc(height, sizeof(unsigned short*)); + for (int i=0; idata[i] = ri->allocation + 3*i*width; + for (int row = 0; row < height; row++) + for (int col = 0; col < width; col++) { + ri->data[row][3*col+0] = image[row*width+col][0]; + ri->data[row][3*col+1] = image[row*width+col][1]; + ri->data[row][3*col+2] = image[row*width+col][2]; + } + } + + if (flip==5) + ri->rotate_deg = 270; + else if (flip==3) + ri->rotate_deg = 180; + else if (flip==6) + ri->rotate_deg = 90; + else + ri->rotate_deg = 0; + + ri->make = strdup (make); + ri->model = strdup (model); + + ri->exifbase = exif_base; + ri->prefilters = pre_filters; + ri->ciff_base = ciff_base; + ri->ciff_len = ciff_len; + + ri->camwb_red = ri->red_multiplier / pre_mul[0]; + ri->camwb_green = ri->green_multiplier / pre_mul[1]; + ri->camwb_blue = ri->blue_multiplier / pre_mul[2]; + + ri->defgain = 1.0 / MIN(MIN(pre_mul[0],pre_mul[1]),pre_mul[2]); + + ri->fuji_width = fuji_width; + + for (int a=0; a < 3; a++) + for (int b=0; b < 3; b++) + ri->coeff[a][b] = rgb_cam[a][b]; + + free (image); +dcrMutex->unlock (); + return 0; +} + +int getRawFileBasicInfo (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, int& rotation, int& thumbWidth, int& thumbHeight, int& thumbOffset, int& thumbType) { + + int status=0; + +dcrMutex->lock (); + + exif_base = -1; + ciff_base = -1; + ciff_len = -1; + + half_size = 1; + bright = 1.0; + verbose = settings->verbose; + use_camera_wb = 1; + + thumb_length = 0; + thumb_offset = 0; + thumb_load_raw = 0; + status = 1; + + ifname = fname.c_str(); + if (!(ifp = gfopen (ifname))) { + status = 2; + dcrMutex->unlock (); + return status; + } + identify (); + if (!is_raw || colors>3) { + status = 3; + fclose (ifp); + dcrMutex->unlock (); + return status; + } + + thumbOffset = thumb_offset; + + if (flip==5) + rotation = 270; + else if (flip==3) + rotation = 180; + else if (flip==6) + rotation = 90; + else + rotation = 0; + + thumbWidth = thumb_width; + thumbHeight = thumb_height; + if (!thumb_load_raw && thumb_offset && write_thumb == jpeg_thumb) + thumbType = 1; + else if (!thumb_load_raw && thumb_offset && write_thumb == ppm_thumb) + thumbType = 2; + else { + thumbType = 0; + thumbWidth = width; + thumbHeight = height; + } + + rml.exifBase = exif_base; + rml.ciffBase = ciff_base; + rml.ciffLength = ciff_len; + + fclose (ifp); +dcrMutex->unlock (); + return !is_raw; +} + +#include + +rtengine::Thumbnail* rtengine::Thumbnail::loadFromRaw (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, int &w, int &h, int fixwh) { + +dcrMutex->lock (); +MyTime t0, t1, t2, t3, t4, t5, t6; +t0.set (); + + image = NULL; + ifname = fname.c_str(); + exif_base = -1; + ciff_base = -1; + ciff_len = -1; + verbose = settings->verbose; + oprof = NULL; + ifp = gfopen (fname.c_str()); + if (!ifp) { + dcrMutex->unlock (); + return NULL; + } + +t1.set (); + + if (setjmp (failure)) { + if (image) + free (image); + fclose (ifp); + dcrMutex->unlock (); + return NULL; + } + + use_camera_wb = 0; + highlight = 1; + half_size = 0; + shrink = 0; + identify (); + use_camera_wb = 1; + if (!is_raw || colors>3) { + fclose(ifp); + dcrMutex->unlock (); + return NULL; + } + +t2.set(); + + iheight = ::height; + iwidth = ::width; + + image = (UshORt (*)[4])calloc (::height*::width*sizeof *image + meta_length, 1); + meta_data = (char *) (image + ::height*::width); + + if (settings->verbose) printf ("Loading %s %s image from %s...\n", make, model, fname.c_str()); + fseek (ifp, data_offset, SEEK_SET); + (*load_raw)(); + if (zero_is_bad) remove_zeroes(); + + rtengine::Thumbnail* tpp = new rtengine::Thumbnail; + + tpp->isRaw = true; + tpp->embProfileLength = 0; + if (profile_length) { + tpp->embProfileLength = profile_length; + tpp->embProfileData = new unsigned char[profile_length]; + fseek (ifp, profile_offset, SEEK_SET); + fread (tpp->embProfileData, 1, profile_length, ifp); + tpp->embProfile = cmsOpenProfileFromMem (tpp->embProfileData, tpp->embProfileLength); + } + else { + tpp->embProfile = NULL; + tpp->embProfileData = NULL; + } + + fclose(ifp); + tpp->redMultiplier = pre_mul[0]; + tpp->greenMultiplier = pre_mul[1]; + tpp->blueMultiplier = pre_mul[2]; + +t3.set (); + + scale_colors(); + pre_interpolate (); + + unsigned filter = filters; + int firstgreen = 1; + // locate first green location in the first row + while (!FISGREEN(filter,1,firstgreen)) + firstgreen++; + + int skip = 1; + if (fixwh==1) // fix height, scale width + skip = (::height-firstgreen-1) / h; + else + skip = (::width-firstgreen-1) / w; + if (skip%2) + skip--; + if (skip<1) + skip = 1; + + int hskip = skip, vskip = skip; + if (!strcmp (model, "D1X")) + hskip *=2; + + rml.exifBase = exif_base; + rml.ciffBase = ciff_base; + rml.ciffLength = ciff_len; + tpp->camwbRed = tpp->redMultiplier / pre_mul[0]; + tpp->camwbGreen = tpp->greenMultiplier / pre_mul[1]; + tpp->camwbBlue = tpp->blueMultiplier / pre_mul[2]; + + tpp->defGain = 1.0 / MIN(MIN(pre_mul[0],pre_mul[1]),pre_mul[2]); + tpp->gammaCorrected = true; + + int ix = 0; + int rofs = 0; + int tmpw = (::width-2)/hskip; + int tmph = (::height-2)/vskip; + Image16* tmpImg = new Image16 (tmpw, tmph); + if (filter) { + for (int row=1, y=0; row< ::height-1 && y> 1; + b = (image[ofs+::width][2] + image[ofs-::width][2]) >> 1; + } + else { + b = (image[ofs+1][2] + image[ofs-1][2]) >> 1; + r = (image[ofs+::width][0] + image[ofs-::width][0]) >> 1; + } + tmpImg->r[y][x] = r; + tmpImg->g[y][x] = g; + tmpImg->b[y][x] = b; + } + } + } + else { + for (int row=1, y=0; row< ::height-1 && yr[y][x] = image[ofs][0]; + tmpImg->g[y][x] = image[ofs][1]; + tmpImg->b[y][x] = image[ofs][2]; + } + } + } + + if (fuji_width) { + int fw = fuji_width / hskip; + double step = sqrt(0.5); + int wide = fw / step; + int high = (tmph - fw) / step; + Image16* fImg = new Image16 (wide, high); + float r, c; + + for (int row=0; row < high; row++) + for (int col=0; col < wide; col++) { + unsigned ur = r = fw + (row-col)*step; + unsigned uc = c = (row+col)*step; + if (ur > tmph-2 || uc > tmpw-2) + continue; + double fr = r - ur; + double fc = c - uc; + int oofs = (ur*tmpw + uc)*3; + int fofs = (row*wide+col)*3; + fImg->r[row][col] = (tmpImg->r[ur][uc] * (1-fc) + tmpImg->r[ur][uc+1] * fc) * (1-fr) + (tmpImg->r[ur+1][uc] * (1-fc) + tmpImg->r[ur+1][uc+1] * fc) * fr; + fImg->g[row][col] = (tmpImg->g[ur][uc] * (1-fc) + tmpImg->g[ur][uc+1] * fc) * (1-fr) + (tmpImg->g[ur+1][uc] * (1-fc) + tmpImg->g[ur+1][uc+1] * fc) * fr; + fImg->b[row][col] = (tmpImg->b[ur][uc] * (1-fc) + tmpImg->b[ur][uc+1] * fc) * (1-fr) + (tmpImg->b[ur+1][uc] * (1-fc) + tmpImg->b[ur+1][uc+1] * fc) * fr; + } + delete tmpImg; + tmpImg = fImg; + } + + + if (fixwh==1) // fix height, scale width + w = tmpw * h / tmph; + else + h = tmph * w / tmpw; + + tpp->thumbImg = tmpImg->resize (w, h, TI_Bilinear); + delete tmpImg; + + if (fuji_width) + tpp->scale = (double)(::height - fuji_width) / sqrt(0.5) / h; + else + tpp->scale = (double)::height / h; + +t4.set (); + + // generate histogram for auto exposure + tpp->aeHistCompression = 3; + tpp->aeHistogram = new unsigned int[65536>>tpp->aeHistCompression]; + memset (tpp->aeHistogram, 0, (65536>>tpp->aeHistCompression)*sizeof(int)); + int radd = 4; + int gadd = 2; + int badd = 4; + if (!filter) + radd = gadd = badd = 1; + for (int i=8; i< ::height-8; i++) { + int start, end; + if (fuji_width) { + int fw = fuji_width; + start = ABS(fw-i) + 8; + end = MIN( ::height+ ::width-fw-i, fw+i) - 8; + } + else { + start = 8; + end = ::width-8; + } + for (int j=start; jaeHistogram[image[i* ::width+j][1]>>tpp->aeHistCompression]+=gadd; + else if (FISRED(filter,i,j)) + tpp->aeHistogram[image[i* ::width+j][0]>>tpp->aeHistCompression]+=radd; + else if (FISBLUE(filter,i,j)) + tpp->aeHistogram[image[i* ::width+j][2]>>tpp->aeHistCompression]+=badd; + } + +t5.set (); + + // generate autoWB + double avg_r = 0; + double avg_g = 0; + double avg_b = 0; + int rn = 0, gn = 0, bn = 0; + + for (int i=32; i< ::height-32; i++) { + int start, end; + if (fuji_width) { + int fw = fuji_width; + start = ABS(fw-i) + 32; + end = MIN( ::height+ ::width-fw-i, fw+i) - 32; + } + else { + start = 32; + end = ::width-32; + } + for (int j=start; jdefGain * image[i* ::width+j][1]; + if (d>64000) + continue; + avg_g += d*d*d*d*d*d; + gn++; + } + if (FISRED(filter,i,j)) { + double d = tpp->defGain * image[i* ::width+j][0]; + if (d>64000) + continue; + avg_r += d*d*d*d*d*d; + rn++; + } + if (FISBLUE(filter,i,j)) { + double d = tpp->defGain * image[i* ::width+j][2]; + if (d>64000) + continue; + avg_b += d*d*d*d*d*d; + bn++; + } + } + } + + double reds = pow (avg_r/rn, 1.0/6.0) * tpp->camwbRed; + double greens = pow (avg_g/gn, 1.0/6.0) * tpp->camwbGreen; + double blues = pow (avg_b/bn, 1.0/6.0) * tpp->camwbBlue; + + double rm = rgb_cam[0][0]*reds + rgb_cam[0][1]*greens + rgb_cam[0][2]*blues; + double gm = rgb_cam[1][0]*reds + rgb_cam[1][1]*greens + rgb_cam[1][2]*blues; + double bm = rgb_cam[2][0]*reds + rgb_cam[2][1]*greens + rgb_cam[2][2]*blues; + + ColorTemp::mul2temp (rm, gm, bm, tpp->autowbTemp, tpp->autowbGreen); + +t6.set (); + +if (settings->verbose) printf ("0: %d, 1: %d, 2: %d, 3: %d, 4: %d, 5: %d All: %d\n", t1.etime(t0), t2.etime(t1), t3.etime(t2), t4.etime(t3), t5.etime(t4), t6.etime(t5), t6.etime(t0)); + + int deg = 0; + if (flip==5) + deg = 270; + else if (flip==3) + deg = 180; + else if (flip==6) + deg = 90; + + if (deg>0) { + Image16* rot = tpp->thumbImg->rotate (deg); + delete tpp->thumbImg; + tpp->thumbImg = rot; + } + + for (int a=0; a < 3; a++) + for (int b=0; b < 3; b++) + tpp->colorMatrix[a][b] = rgb_cam[a][b]; + + tpp->init (); + + free (image); + +dcrMutex->unlock (); + + return tpp; +} + + +} + diff --git a/rtengine/dcraw.patch b/rtengine/dcraw.patch new file mode 100644 index 000000000..9b520da4d --- /dev/null +++ b/rtengine/dcraw.patch @@ -0,0 +1,727 @@ +--- dcraw.c 2009-08-31 17:24:29.000000000 +0200 ++++ dcraw.cc 2009-10-09 08:55:28.000000000 +0200 +@@ -1,3 +1,16 @@ ++/*RT*/#include ++/*RT*/#include ++/*RT*/int ciff_base, ciff_len, exif_base, pre_filters; ++/*RT*/#undef MAX ++/*RT*/#undef MIN ++/*RT*/#define NO_LCMS ++/*RT*/#define NO_JPEG ++/*RT*/#define LOCALTIME ++/*RT*/#define DJGPP ++/*RT*/#include ++ ++#include "myfile.h" ++ + /* + dcraw.c -- Dave Coffin's raw photo decoder + Copyright 1997-2009 by Dave Coffin, dcoffin a cybercom o net +@@ -46,7 +59,9 @@ + NO_LCMS disables the "-p" option. + */ + #ifndef NO_JPEG +-#include ++/*RT*/extern "C" { ++/*RT*/#include ++/*RT*/} + #endif + #ifndef NO_LCMS + #include +@@ -101,7 +116,8 @@ + access them are prefixed with "CLASS". Note that a thread-safe + C++ class cannot have non-const static local variables. + */ +-FILE *ifp, *ofp; ++/*RT*/IMFILE *ifp; ++FILE * ofp; + short order; + const char *ifname; + char *meta_data; +@@ -271,6 +287,7 @@ + fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp)); + } + data_error = 1; ++ /*RT*/ longjmp (failure, 1); + } + + ushort CLASS sget2 (uchar *s) +@@ -344,7 +361,7 @@ + { + if (fread (pixel, 2, count, ifp) < count) derror(); + if ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) +- swab (pixel, pixel, count*2); ++ swab ((char*)pixel, (char*)pixel, count*2); + } + + void CLASS canon_black (double dark[2], int nblack) +@@ -2131,7 +2148,7 @@ + size_t nbytes; + + nbytes = fread (jpeg_buffer, 1, 4096, ifp); +- swab (jpeg_buffer, jpeg_buffer, nbytes); ++ swab ((char*)jpeg_buffer, (char*)jpeg_buffer, nbytes); + cinfo->src->next_input_byte = jpeg_buffer; + cinfo->src->bytes_in_buffer = nbytes; + return TRUE; +@@ -3773,6 +3790,7 @@ + for (row = FC(1,0) >> 1; row < height; row+=2) + for (col = FC(row,1) & 1; col < width; col+=2) + image[row*width+col][1] = image[row*width+col][3]; ++/*RT*/ pre_filters = filters; + filters &= ~((filters & 0x55555555) << 1); + } + } +@@ -4824,7 +4842,7 @@ + unsigned sony_curve[] = { 0,0,0,0,0,4095 }; + unsigned *buf, sony_offset=0, sony_length=0, sony_key=0; + struct jhead jh; +- FILE *sfp; ++/*RT*/ IMFILE *sfp; + + if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0]) + return 1; +@@ -5200,12 +5218,13 @@ + fread (buf, sony_length, 1, ifp); + sony_decrypt (buf, sony_length/4, 1, sony_key); + sfp = ifp; +- if ((ifp = tmpfile())) { +- fwrite (buf, sony_length, 1, ifp); +- fseek (ifp, 0, SEEK_SET); ++/*RT*/ ifp = fopen (buf, sony_length); ++// if ((ifp = tmpfile())) { ++// fwrite (buf, sony_length, 1, ifp); ++// fseek (ifp, 0, SEEK_SET); + parse_tiff_ifd (-sony_offset); +- fclose (ifp); +- } ++// fclose (ifp); ++// } + ifp = sfp; + free (buf); + } +@@ -5231,6 +5250,8 @@ + int doff, max_samp=0, raw=-1, thm=-1, i; + struct jhead jh; + ++ /*RT*/ exif_base = base; ++ + fseek (ifp, base, SEEK_SET); + order = get2(); + if (order != 0x4949 && order != 0x4d4d) return; +@@ -5399,7 +5420,7 @@ + { + const char *file, *ext; + char *jname, *jfile, *jext; +- FILE *save=ifp; ++/*RT*/ IMFILE *save=ifp; + + ext = strrchr (ifname, '.'); + file = strrchr (ifname, '/'); +@@ -5427,7 +5448,8 @@ + *jext = '0'; + } + if (strcmp (jname, ifname)) { +- if ((ifp = fopen (jname, "rb"))) { ++/*RT*/ if ((ifp = fopen (jname))) { ++// if ((ifp = fopen (jname, "rb"))) { + if (verbose) + fprintf (stderr,_("Reading metadata from %s ...\n"), jname); + parse_tiff (12); +@@ -5757,7 +5779,11 @@ + order = get2(); + hlen = get4(); + if (get4() == 0x48454150) /* "HEAP" */ ++/*RT*/ { ++/*RT*/ ciff_base = save+hlen; ++/*RT*/ ciff_len = len-hlen; + parse_ciff (save+hlen, len-hlen); ++/*RT*/ } + parse_tiff (save+6); + fseek (ifp, save+len, SEEK_SET); + } +@@ -6656,6 +6682,12 @@ + fread (head, 1, 32, ifp); + fseek (ifp, 0, SEEK_END); + fsize = ftell(ifp); ++ ++ /*RT*/ if (fsize<100000) { ++ is_raw = 0; ++ return; ++ } ++ + if ((cp = (char *) memmem (head, 32, "MMMM", 4)) || + (cp = (char *) memmem (head, 32, "IIII", 4))) { + parse_phase_one (cp-head); +@@ -6663,6 +6695,8 @@ + } else if (order == 0x4949 || order == 0x4d4d) { + if (!memcmp (head+6,"HEAPCCDR",8)) { + data_offset = hlen; ++/*RT*/ ciff_base = hlen; ++/*RT*/ ciff_len = fsize - hlen; + parse_ciff (hlen, fsize - hlen); + } else { + parse_tiff(0); +@@ -8354,13 +8388,13 @@ + FORCC ppm [col*colors+c] = curve[image[soff][c]] >> 8; + else FORCC ppm2[col*colors+c] = curve[image[soff][c]]; + if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa) +- swab (ppm2, ppm2, width*colors*2); ++ swab ((char*)ppm2, (char*)ppm2, width*colors*2); + fwrite (ppm, colors*output_bps/8, width, ofp); + } + free (ppm); + } + +-int CLASS main (int argc, const char **argv) ++/*int CLASS main (int argc, const char **argv) + { + int arg, status=0; + int timestamp_only=0, thumbnail_only=0, identify_only=0; +@@ -8473,7 +8507,7 @@ + case 'i': identify_only = 1; break; + case 'c': write_to_stdout = 1; break; + case 'v': verbose = 1; break; +- case 'h': half_size = 1; /* "-h" implies "-f" */ ++ case 'h': half_size = 1; /* "-h" implies "-f" *//* + case 'f': four_color_rgb = 1; break; + case 'A': FORC4 greybox[c] = atoi(argv[arg++]); + case 'a': use_auto_wb = 1; break; +@@ -8733,3 +8767,537 @@ + } + return status; + } ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++namespace rtengine { ++ ++extern Settings* settings; ++ ++Glib::Mutex* dcrMutex=NULL; ++ ++int loadRaw (const char* fname, struct RawImage *ri) { ++ ++ static const double xyzd50_srgb[3][3] = ++ { { 0.436083, 0.385083, 0.143055 }, ++ { 0.222507, 0.716888, 0.060608 }, ++ { 0.013930, 0.097097, 0.714022 } }; ++ ++dcrMutex->lock (); ++ ++ ifname = fname;//strdup (fname); ++ image = NULL; ++ ++ exif_base = -1; ++ ciff_base = -1; ++ ciff_len = -1; ++ verbose = settings->verbose; ++ oprof = NULL; ++ ri->data = NULL; ++ ri->allocation = NULL; ++ ri->profile_data = NULL; ++ ifp = gfopen (fname); ++ if (!ifp) { ++ dcrMutex->unlock (); ++ return 3; ++ } ++ ++ use_camera_wb = 0; ++ highlight = 1; ++ half_size = 0; ++ ++ identify (); ++ use_camera_wb = 1; ++ if (!is_raw) { ++ fclose(ifp); ++ dcrMutex->unlock (); ++ return 2; ++ } ++ ++ shrink = 0; ++ ++ if (settings->verbose) printf ("Loading %s %s image from %s...\n", make, model, fname); ++ iheight = height; ++ iwidth = width; ++ ++ image = (UshORt (*)[4])calloc (height*width*sizeof *image + meta_length, 1); ++ meta_data = (char *) (image + height*width); ++ ++ if (setjmp (failure)) { ++ if (image) ++ free (image); ++ if (ri->data) ++ free(ri->data); ++ fclose (ifp); ++ dcrMutex->unlock (); ++ return 100; ++ } ++ ++ fseek (ifp, data_offset, SEEK_SET); ++ (*load_raw)(); ++ ++ ri->profile_len = 0; ++ ri->profile_data = NULL; ++ if (profile_length) { ++ ri->profile_len = profile_length; ++ ri->profile_data = (char *) malloc (profile_length); ++ fseek (ifp, profile_offset, SEEK_SET); ++ fread (ri->profile_data, 1, profile_length, ifp); ++ } ++ ++ fclose(ifp); ++ if (zero_is_bad) remove_zeroes(); ++ ++ ri->red_multiplier = pre_mul[0]; ++ ri->green_multiplier = pre_mul[1]; ++ ri->blue_multiplier = pre_mul[2]; ++ ++ scale_colors(); ++ pre_interpolate (); ++ ++ ri->width = width; ++ ri->height = height; ++ ri->filters = filters; ++ ++ if (filters) { ++ ri->allocation = (short unsigned int*)calloc(height*width, sizeof(unsigned short)); ++ ri->data = (unsigned short**)calloc(height, sizeof(unsigned short*)); ++ for (int i=0; idata[i] = ri->allocation + i*width; ++ for (int row = 0; row < height; row++) ++ for (int col = 0; col < width; col++) ++ if (ISGREEN(ri,row,col)) ++ ri->data[row][col] = image[row*width+col][1]; ++ else if (ISRED(ri,row,col)) ++ ri->data[row][col] = image[row*width+col][0]; ++ else ++ ri->data[row][col] = image[row*width+col][2]; ++ } ++ else { ++ ri->allocation = (short unsigned int*)calloc(3*height*width, sizeof(unsigned short)); ++ ri->data = (unsigned short**)calloc(height, sizeof(unsigned short*)); ++ for (int i=0; idata[i] = ri->allocation + 3*i*width; ++ for (int row = 0; row < height; row++) ++ for (int col = 0; col < width; col++) { ++ ri->data[row][3*col+0] = image[row*width+col][0]; ++ ri->data[row][3*col+1] = image[row*width+col][1]; ++ ri->data[row][3*col+2] = image[row*width+col][2]; ++ } ++ } ++ ++ if (flip==5) ++ ri->rotate_deg = 270; ++ else if (flip==3) ++ ri->rotate_deg = 180; ++ else if (flip==6) ++ ri->rotate_deg = 90; ++ else ++ ri->rotate_deg = 0; ++ ++ ri->make = strdup (make); ++ ri->model = strdup (model); ++ ++ ri->exifbase = exif_base; ++ ri->prefilters = pre_filters; ++ ri->ciff_base = ciff_base; ++ ri->ciff_len = ciff_len; ++ ++ ri->camwb_red = ri->red_multiplier / pre_mul[0]; ++ ri->camwb_green = ri->green_multiplier / pre_mul[1]; ++ ri->camwb_blue = ri->blue_multiplier / pre_mul[2]; ++ ++ ri->defgain = 1.0 / MIN(MIN(pre_mul[0],pre_mul[1]),pre_mul[2]); ++ ++ ri->fuji_width = fuji_width; ++ ++ for (int a=0; a < 3; a++) ++ for (int b=0; b < 3; b++) ++ ri->coeff[a][b] = rgb_cam[a][b]; ++ ++ free (image); ++dcrMutex->unlock (); ++ return 0; ++} ++ ++int getRawFileBasicInfo (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, int& rotation, int& thumbWidth, int& thumbHeight, int& thumbOffset, int& thumbType) { ++ ++ int status=0; ++ ++dcrMutex->lock (); ++ ++ exif_base = -1; ++ ciff_base = -1; ++ ciff_len = -1; ++ ++ half_size = 1; ++ bright = 1.0; ++ verbose = settings->verbose; ++ use_camera_wb = 1; ++ ++ thumb_length = 0; ++ thumb_offset = 0; ++ thumb_load_raw = 0; ++ status = 1; ++ ++ ifname = fname.c_str(); ++ if (!(ifp = gfopen (ifname))) { ++ status = 2; ++ dcrMutex->unlock (); ++ return status; ++ } ++ identify (); ++ if (!is_raw || colors>3) { ++ status = 3; ++ fclose (ifp); ++ dcrMutex->unlock (); ++ return status; ++ } ++ ++ thumbOffset = thumb_offset; ++ ++ if (flip==5) ++ rotation = 270; ++ else if (flip==3) ++ rotation = 180; ++ else if (flip==6) ++ rotation = 90; ++ else ++ rotation = 0; ++ ++ thumbWidth = thumb_width; ++ thumbHeight = thumb_height; ++ if (!thumb_load_raw && thumb_offset && write_thumb == jpeg_thumb) ++ thumbType = 1; ++ else if (!thumb_load_raw && thumb_offset && write_thumb == ppm_thumb) ++ thumbType = 2; ++ else { ++ thumbType = 0; ++ thumbWidth = width; ++ thumbHeight = height; ++ } ++ ++ rml.exifBase = exif_base; ++ rml.ciffBase = ciff_base; ++ rml.ciffLength = ciff_len; ++ ++ fclose (ifp); ++dcrMutex->unlock (); ++ return !is_raw; ++} ++ ++#include ++ ++rtengine::Thumbnail* rtengine::Thumbnail::loadFromRaw (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, int &w, int &h, int fixwh) { ++ ++dcrMutex->lock (); ++MyTime t0, t1, t2, t3, t4, t5, t6; ++t0.set (); ++ ++ image = NULL; ++ ifname = fname.c_str(); ++ exif_base = -1; ++ ciff_base = -1; ++ ciff_len = -1; ++ verbose = settings->verbose; ++ oprof = NULL; ++ ifp = gfopen (fname.c_str()); ++ if (!ifp) { ++ dcrMutex->unlock (); ++ return NULL; ++ } ++ ++t1.set (); ++ ++ if (setjmp (failure)) { ++ if (image) ++ free (image); ++ fclose (ifp); ++ dcrMutex->unlock (); ++ return NULL; ++ } ++ ++ use_camera_wb = 0; ++ highlight = 1; ++ half_size = 0; ++ shrink = 0; ++ identify (); ++ use_camera_wb = 1; ++ if (!is_raw || colors>3) { ++ fclose(ifp); ++ dcrMutex->unlock (); ++ return NULL; ++ } ++ ++t2.set(); ++ ++ iheight = ::height; ++ iwidth = ::width; ++ ++ image = (UshORt (*)[4])calloc (::height*::width*sizeof *image + meta_length, 1); ++ meta_data = (char *) (image + ::height*::width); ++ ++ if (settings->verbose) printf ("Loading %s %s image from %s...\n", make, model, fname.c_str()); ++ fseek (ifp, data_offset, SEEK_SET); ++ (*load_raw)(); ++ if (zero_is_bad) remove_zeroes(); ++ ++ rtengine::Thumbnail* tpp = new rtengine::Thumbnail; ++ ++ tpp->isRaw = true; ++ tpp->embProfileLength = 0; ++ if (profile_length) { ++ tpp->embProfileLength = profile_length; ++ tpp->embProfileData = new unsigned char[profile_length]; ++ fseek (ifp, profile_offset, SEEK_SET); ++ fread (tpp->embProfileData, 1, profile_length, ifp); ++ tpp->embProfile = cmsOpenProfileFromMem (tpp->embProfileData, tpp->embProfileLength); ++ } ++ else { ++ tpp->embProfile = NULL; ++ tpp->embProfileData = NULL; ++ } ++ ++ fclose(ifp); ++ tpp->redMultiplier = pre_mul[0]; ++ tpp->greenMultiplier = pre_mul[1]; ++ tpp->blueMultiplier = pre_mul[2]; ++ ++t3.set (); ++ ++ scale_colors(); ++ pre_interpolate (); ++ ++ unsigned filter = filters; ++ int firstgreen = 1; ++ // locate first green location in the first row ++ while (!FISGREEN(filter,1,firstgreen)) ++ firstgreen++; ++ ++ int skip = 1; ++ if (fixwh==1) // fix height, scale width ++ skip = (::height-firstgreen-1) / h; ++ else ++ skip = (::width-firstgreen-1) / w; ++ if (skip%2) ++ skip--; ++ if (skip<1) ++ skip = 1; ++ ++ int hskip = skip, vskip = skip; ++ if (!strcmp (model, "D1X")) ++ hskip *=2; ++ ++ rml.exifBase = exif_base; ++ rml.ciffBase = ciff_base; ++ rml.ciffLength = ciff_len; ++ tpp->camwbRed = tpp->redMultiplier / pre_mul[0]; ++ tpp->camwbGreen = tpp->greenMultiplier / pre_mul[1]; ++ tpp->camwbBlue = tpp->blueMultiplier / pre_mul[2]; ++ ++ tpp->defGain = 1.0 / MIN(MIN(pre_mul[0],pre_mul[1]),pre_mul[2]); ++ tpp->gammaCorrected = true; ++ ++ int ix = 0; ++ int rofs = 0; ++ int tmpw = (::width-2)/hskip; ++ int tmph = (::height-2)/vskip; ++ Image16* tmpImg = new Image16 (tmpw, tmph); ++ if (filter) { ++ for (int row=1, y=0; row< ::height-1 && y> 1; ++ b = (image[ofs+::width][2] + image[ofs-::width][2]) >> 1; ++ } ++ else { ++ b = (image[ofs+1][2] + image[ofs-1][2]) >> 1; ++ r = (image[ofs+::width][0] + image[ofs-::width][0]) >> 1; ++ } ++ tmpImg->r[y][x] = r; ++ tmpImg->g[y][x] = g; ++ tmpImg->b[y][x] = b; ++ } ++ } ++ } ++ else { ++ for (int row=1, y=0; row< ::height-1 && yr[y][x] = image[ofs][0]; ++ tmpImg->g[y][x] = image[ofs][1]; ++ tmpImg->b[y][x] = image[ofs][2]; ++ } ++ } ++ } ++ ++ if (fuji_width) { ++ int fw = fuji_width / hskip; ++ double step = sqrt(0.5); ++ int wide = fw / step; ++ int high = (tmph - fw) / step; ++ Image16* fImg = new Image16 (wide, high); ++ float r, c; ++ ++ for (int row=0; row < high; row++) ++ for (int col=0; col < wide; col++) { ++ unsigned ur = r = fw + (row-col)*step; ++ unsigned uc = c = (row+col)*step; ++ if (ur > tmph-2 || uc > tmpw-2) ++ continue; ++ double fr = r - ur; ++ double fc = c - uc; ++ int oofs = (ur*tmpw + uc)*3; ++ int fofs = (row*wide+col)*3; ++ fImg->r[row][col] = (tmpImg->r[ur][uc] * (1-fc) + tmpImg->r[ur][uc+1] * fc) * (1-fr) + (tmpImg->r[ur+1][uc] * (1-fc) + tmpImg->r[ur+1][uc+1] * fc) * fr; ++ fImg->g[row][col] = (tmpImg->g[ur][uc] * (1-fc) + tmpImg->g[ur][uc+1] * fc) * (1-fr) + (tmpImg->g[ur+1][uc] * (1-fc) + tmpImg->g[ur+1][uc+1] * fc) * fr; ++ fImg->b[row][col] = (tmpImg->b[ur][uc] * (1-fc) + tmpImg->b[ur][uc+1] * fc) * (1-fr) + (tmpImg->b[ur+1][uc] * (1-fc) + tmpImg->b[ur+1][uc+1] * fc) * fr; ++ } ++ delete tmpImg; ++ tmpImg = fImg; ++ } ++ ++ ++ if (fixwh==1) // fix height, scale width ++ w = tmpw * h / tmph; ++ else ++ h = tmph * w / tmpw; ++ ++ tpp->thumbImg = tmpImg->resize (w, h, TI_Bilinear); ++ delete tmpImg; ++ ++ if (fuji_width) ++ tpp->scale = (double)(::height - fuji_width) / sqrt(0.5) / h; ++ else ++ tpp->scale = (double)::height / h; ++ ++t4.set (); ++ ++ // generate histogram for auto exposure ++ tpp->aeHistCompression = 3; ++ tpp->aeHistogram = new int[65536>>tpp->aeHistCompression]; ++ memset (tpp->aeHistogram, 0, (65536>>tpp->aeHistCompression)*sizeof(int)); ++ int radd = 4; ++ int gadd = 2; ++ int badd = 4; ++ if (!filter) ++ radd = gadd = badd = 1; ++ for (int i=8; i< ::height-8; i++) { ++ int start, end; ++ if (fuji_width) { ++ int fw = fuji_width; ++ start = ABS(fw-i) + 8; ++ end = MIN( ::height+ ::width-fw-i, fw+i) - 8; ++ } ++ else { ++ start = 8; ++ end = ::width-8; ++ } ++ for (int j=start; jaeHistogram[image[i* ::width+j][1]>>tpp->aeHistCompression]+=gadd; ++ else if (FISRED(filter,i,j)) ++ tpp->aeHistogram[image[i* ::width+j][0]>>tpp->aeHistCompression]+=radd; ++ else if (FISBLUE(filter,i,j)) ++ tpp->aeHistogram[image[i* ::width+j][2]>>tpp->aeHistCompression]+=badd; ++ } ++ ++t5.set (); ++ ++ // generate autoWB ++ double avg_r = 0; ++ double avg_g = 0; ++ double avg_b = 0; ++ int rn = 0, gn = 0, bn = 0; ++ ++ for (int i=32; i< ::height-32; i++) { ++ int start, end; ++ if (fuji_width) { ++ int fw = fuji_width; ++ start = ABS(fw-i) + 32; ++ end = MIN( ::height+ ::width-fw-i, fw+i) - 32; ++ } ++ else { ++ start = 32; ++ end = ::width-32; ++ } ++ for (int j=start; jdefGain * image[i* ::width+j][1]; ++ if (d>64000) ++ continue; ++ avg_g += d*d*d*d*d*d; ++ gn++; ++ } ++ if (FISRED(filter,i,j)) { ++ double d = tpp->defGain * image[i* ::width+j][0]; ++ if (d>64000) ++ continue; ++ avg_r += d*d*d*d*d*d; ++ rn++; ++ } ++ if (FISBLUE(filter,i,j)) { ++ double d = tpp->defGain * image[i* ::width+j][2]; ++ if (d>64000) ++ continue; ++ avg_b += d*d*d*d*d*d; ++ bn++; ++ } ++ } ++ } ++ ++ double reds = pow (avg_r/rn, 1.0/6.0) * tpp->camwbRed; ++ double greens = pow (avg_g/gn, 1.0/6.0) * tpp->camwbGreen; ++ double blues = pow (avg_b/bn, 1.0/6.0) * tpp->camwbBlue; ++ ++ double rm = rgb_cam[0][0]*reds + rgb_cam[0][1]*greens + rgb_cam[0][2]*blues; ++ double gm = rgb_cam[1][0]*reds + rgb_cam[1][1]*greens + rgb_cam[1][2]*blues; ++ double bm = rgb_cam[2][0]*reds + rgb_cam[2][1]*greens + rgb_cam[2][2]*blues; ++ ++ ColorTemp::mul2temp (rm, gm, bm, tpp->autowbTemp, tpp->autowbGreen); ++ ++t6.set (); ++ ++if (settings->verbose) printf ("0: %d, 1: %d, 2: %d, 3: %d, 4: %d, 5: %d All: %d\n", t1.etime(t0), t2.etime(t1), t3.etime(t2), t4.etime(t3), t5.etime(t4), t6.etime(t5), t6.etime(t0)); ++ ++ int deg = 0; ++ if (flip==5) ++ deg = 270; ++ else if (flip==3) ++ deg = 180; ++ else if (flip==6) ++ deg = 90; ++ ++ if (deg>0) { ++ Image16* rot = tpp->thumbImg->rotate (deg); ++ delete tpp->thumbImg; ++ tpp->thumbImg = rot; ++ } ++ ++ for (int a=0; a < 3; a++) ++ for (int b=0; b < 3; b++) ++ tpp->colorMatrix[a][b] = rgb_cam[a][b]; ++ ++ tpp->init (); ++ ++ free (image); ++ ++dcrMutex->unlock (); ++ ++ return tpp; ++} ++ ++ ++} ++ diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc new file mode 100644 index 000000000..cc8956099 --- /dev/null +++ b/rtengine/dcrop.cc @@ -0,0 +1,386 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#define CLIPTO(a,b,c) ((a)>b?((a) 0)) + +namespace rtengine { + +extern Settings* settings; + +Crop::Crop (ImProcCoordinator* parent) + : parent(parent), cropAllocated(false), + cropw(-1), croph(-1), trafw(-1), trafh(-1), + cropImageListener(NULL), updating(false), + resizeCrop(NULL), transCrop(NULL), borderRequested(32) +{ + parent->crops.push_back (this); +} + +Crop::~Crop () { + + cropMutex.lock (); + parent->mProcessing.lock (); + std::vector::iterator i = std::find (parent->crops.begin(), parent->crops.end(), this); + if (i!=parent->crops.end ()) + parent->crops.erase (i); + + freeAll (); + parent->mProcessing.unlock (); + cropMutex.unlock (); +} + +void Crop::setListener (DetailedCropListener* il) { + + parent->mProcessing.lock(); + cropImageListener = il; + parent->mProcessing.unlock(); +} + +void Crop::update (int todo, bool internal) { + + if (!internal) + parent->mProcessing.lock (); + + ProcParams& params = parent->params; + cropMutex.lock (); + + if (!params.resize.enabled) + params.resize.scale = 1.0; + else if (params.resize.dataspec==1) + params.resize.scale = (double)params.resize.width / (params.coarse.rotate==90 || params.coarse.rotate==270 ? parent->fh : parent->fw); + else if (params.resize.dataspec==2) + params.resize.scale = (double)params.resize.height / (params.coarse.rotate==90 || params.coarse.rotate==270 ? parent->fw : parent->fh); + + MyTime t1,t2,t3,t4,t5,t6,t7,t8,t9; + + t1.set (); + // give possibility to the listener to modify crop window (as the full image dimensions are already known at this point) + int wx, wy, ww, wh, ws; + bool overrideWindow = false; + if (cropImageListener) + overrideWindow = cropImageListener->getWindow (wx, wy, ww, wh, ws); + // re-allocate sub-images and arrays if their dimensions changed + bool needsinitupdate = false; + if (!overrideWindow) + needsinitupdate = setCropSizes (rqcropx, rqcropy, rqcropw, rqcroph, skip, true); + else + needsinitupdate = setCropSizes (wx, wy, ww, wh, ws, true); + // it something has been reallocated, all processing steps have to be performed + if (needsinitupdate) + todo = ALL; + + if (resizeCrop) + baseCrop = resizeCrop; + else + baseCrop = origCrop; + bool needstransform = fabs(params.rotate.degree)>1e-15 || fabs(params.distortion.amount)>1e-15 || fabs(params.cacorrection.red)>1e-15 || fabs(params.cacorrection.blue)>1e-15; + + if (todo & M_INIT) { + parent->minit.lock (); + int tr = TR_NONE; + if (params.coarse.rotate==90) tr |= TR_R90; + if (params.coarse.rotate==180) tr |= TR_R180; + if (params.coarse.rotate==270) tr |= TR_R270; + if (params.coarse.hflip) tr |= TR_HFLIP; + if (params.coarse.vflip) tr |= TR_VFLIP; + + if (!needsinitupdate) + setCropSizes (rqcropx, rqcropy, rqcropw, rqcroph, skip, true); + PreviewProps pp (trafx, trafy, trafw*skip, trafh*skip, skip); + parent->imgsrc->getImage (parent->currWB, tr, origCrop, pp, params.hlrecovery, params.icm); + + if (fabs(params.resize.scale-1.0)<1e-7) { + if (resizeCrop) { + delete resizeCrop; + resizeCrop = NULL; + } + baseCrop = origCrop; + } + else { + int rcw = trafw*params.resize.scale; + int rch = trafh*params.resize.scale; + if (!needstransform) { + rcw = cropw; + rch = croph; + } + if (resizeCrop && (resizeCrop->width!=rcw || resizeCrop->height!=rch)) { + delete resizeCrop; + resizeCrop = NULL; + } + if (!resizeCrop) + resizeCrop = new Image16 (rcw, rch); + parent->ipf.resize (origCrop, resizeCrop, params.resize); + baseCrop = resizeCrop; + } + parent->minit.unlock (); + } + + t2.set (); + if (settings->verbose) printf ("C-INIT: %d\n", t2.etime(t1)); + + bool needsvignetting = params.vignetting.amount!=0; + + if ((!needstransform && !needsvignetting && transCrop) || (transCrop && (transCrop->width!=cropw || transCrop->height!=croph))) { + delete transCrop; + transCrop = NULL; + } + // check if the transformation has been switched on: + else if ((needstransform || needsvignetting) && !transCrop) + transCrop = new Image16 (cropw, croph); + if ((todo & M_TRANSFORM) && !needstransform && needsvignetting) + parent->ipf.vignetting (baseCrop, transCrop, ¶ms, cropx/skip, cropy/skip, SKIPS(parent->fw,skip), SKIPS(parent->fh,skip)); + else if ((todo & M_TRANSFORM) && needstransform) { + if (skip==1) + parent->ipf.transform (baseCrop, transCrop, ¶ms, cropx/skip, cropy/skip, trafx*params.resize.scale/skip, trafy*params.resize.scale/skip, SKIPS(parent->fw,skip), SKIPS(parent->fh,skip)); + else + parent->ipf.simpltransform (baseCrop, transCrop, ¶ms, cropx/skip, cropy/skip, trafx*params.resize.scale/skip, trafy*params.resize.scale/skip, SKIPS(parent->fw,skip), SKIPS(parent->fh,skip)); + } + if (transCrop) + baseCrop = transCrop; + + t3.set (); + if (settings->verbose) printf ("C-TRANSFORM: %d\n", t3.etime(t2)); + + if ((todo & M_BLURMAP) && params.sh.enabled) { + double radius = sqrt (double(SKIPS(parent->fw,skip)*SKIPS(parent->fw,skip)+SKIPS(parent->fh,skip)*SKIPS(parent->fh,skip))) / 2.0; + double shradius = radius / 1800.0 * params.sh.radius; + cshmap->update (baseCrop, (unsigned short**)cbuffer, shradius, parent->ipf.lumimul, params.sh.hq); + cshmap->forceStat (parent->shmap->max, parent->shmap->min, parent->shmap->avg); + } + + t4.set (); + if (settings->verbose) printf ("C-BLURMAP: %d\n", t4.etime(t3)); + + if (todo & M_RGBCURVE) { + parent->ipf.rgbProc (baseCrop, laboCrop, ¶ms, parent->tonecurve, cshmap); + } + + t5.set (); + if (settings->verbose) printf ("C-RGB: %d\n", t5.etime(t4)); + + if (todo & M_LUMINANCE) { + parent->ipf.luminanceCurve (laboCrop, labnCrop, parent->lumacurve, 0, croph); + if (skip==1) { + parent->ipf.lumadenoise (labnCrop, ¶ms, 1, cbuffer); + parent->ipf.sharpening (labnCrop, ¶ms, 1, (unsigned short**)cbuffer); + } + } + + t6.set (); + if (settings->verbose) printf ("C-LUMINANCE: %d\n", t6.etime(t5)); + + if (todo & M_COLOR) { + parent->ipf.colorCurve (laboCrop, labnCrop, ¶ms); + if (skip==1) + parent->ipf.colordenoise (labnCrop, ¶ms, 1, cbuffer); + } + + t7.set (); + if (settings->verbose) printf ("C-COLOR: %d\n", t7.etime(t6)); + + parent->ipf.lab2rgb (labnCrop, cropImg); + + t8.set (); + if (settings->verbose) printf ("C-RGBCONVERT: %d\n", t8.etime(t7)); + if (cropImageListener) { + int finalW = rqcropw; + if (cropImg->getWidth()-leftBorder < finalW) + finalW = cropImg->getWidth()-leftBorder; + int finalH = rqcroph; + if (cropImg->getHeight()-upperBorder < finalH) + finalH = cropImg->getHeight()-upperBorder; + + Image8* final = new Image8 (finalW, finalH); + for (int i=0; idata + 3*i*finalW, cropImg->data + 3*(i+upperBorder)*cropw + 3*leftBorder, 3*finalW); + cropImageListener->setDetailedCrop (final, params.crop, rqcropx, rqcropy, rqcropw, rqcroph, skip); + delete final; + } + + t9.set (); + if (settings->verbose) printf ("Total crop processing time: %d\n", t9.etime(t1)); + + cropMutex.unlock (); + + if (!internal) + parent->mProcessing.unlock (); +} + +void Crop::freeAll () { + + if (settings->verbose) printf ("freeallcrop starts %d\n", (int)cropAllocated); + + if (cropAllocated) { + delete origCrop; + if (transCrop) + delete transCrop; + transCrop = NULL; + if (resizeCrop) + delete resizeCrop; + resizeCrop = NULL; + delete laboCrop; + delete labnCrop; + delete cropImg; + delete cshmap; + for (int i=0; iverbose) printf ("setcropsizes before lock\n"); + + if (!internal) + cropMutex.lock (); + + bool changed = false; + + rqcropx = rcx; + rqcropy = rcy; + rqcropw = rcw; + rqcroph = rch; + + // store and set requested crop size + int rqx1 = CLIPTO(rqcropx,0,parent->fullw-1); + int rqy1 = CLIPTO(rqcropy,0,parent->fullh-1); + int rqx2 = rqx1 + rqcropw - 1; + int rqy2 = rqy1 + rqcroph - 1; + rqx2 = CLIPTO(rqx2,0,parent->fullw-1); + rqy2 = CLIPTO(rqy2,0,parent->fullh-1); + + this->skip = skip; + + // add border, if possible + int bx1 = rqx1 - skip*borderRequested; + int by1 = rqy1 - skip*borderRequested; + int bx2 = rqx2 + skip*borderRequested; + int by2 = rqy2 + skip*borderRequested; + // clip it to fit into image area + bx1 = CLIPTO(bx1,0,parent->fullw-1); + by1 = CLIPTO(by1,0,parent->fullh-1); + bx2 = CLIPTO(bx2,0,parent->fullw-1); + by2 = CLIPTO(by2,0,parent->fullh-1); + int bw = bx2 - bx1 + 1; + int bh = by2 - by1 + 1; + + // determine which part of the source image is required to compute the crop rectangle + int orx, ory, orw, orh; + ProcParams& params = parent->params; + parent->ipf.transCoord (¶ms, parent->fw, parent->fh, bx1, by1, bw, bh, orx, ory, orw, orh); + + int tr = TR_NONE; + if (params.coarse.rotate==90) tr |= TR_R90; + if (params.coarse.rotate==180) tr |= TR_R180; + if (params.coarse.rotate==270) tr |= TR_R270; + if (params.coarse.hflip) tr |= TR_HFLIP; + if (params.coarse.vflip) tr |= TR_VFLIP; + + PreviewProps cp (orx, ory, orw, orh, skip); + int orW, orH; + parent->imgsrc->getSize (tr, cp, orW, orH); + + int cw = SKIPS(bw,skip); + int ch = SKIPS(bh,skip); + + leftBorder = SKIPS(rqx1-bx1,skip); + upperBorder = SKIPS(rqy1-by1,skip); + + if (settings->verbose) printf ("setsizes starts (%d, %d, %d, %d)\n", orW, orH, trafw, trafh); + + if (cw!=cropw || ch!=croph || orW!=trafw || orH!=trafh) { + + freeAll (); + + cropw = cw; + croph = ch; + trafw = orW; + trafh = orH; + + origCrop = new Image16 (trafw, trafh); + laboCrop = new LabImage (cropw, croph); + labnCrop = new LabImage (cropw, croph); + cropImg = new Image8 (cropw, croph); + cshmap = new SHMap (cropw, croph); + + cbuffer = new int*[croph]; + for (int i=0; iverbose) printf ("setsizes ends\n"); + + if (!internal) + cropMutex.unlock (); + + return changed; +} + +void Crop::fullUpdate () { + + if (updating) { + needsNext = true; + return; + } + + updating = true; + + parent->updaterThreadStart.lock (); + if (parent->updaterRunning && parent->thread) { + parent->changeSinceLast = 0; + parent->thread->join (); + } + + if (parent->plistener) + parent->plistener->setProgressState (1); + + needsNext = true; + while (needsNext) { + needsNext = false; + update (ALL, true); + } + updating = false; + + if (parent->plistener) + parent->plistener->setProgressState (0); + + parent->updaterThreadStart.unlock (); +} + +} + diff --git a/rtengine/dcrop.h b/rtengine/dcrop.h new file mode 100644 index 000000000..71ca82654 --- /dev/null +++ b/rtengine/dcrop.h @@ -0,0 +1,74 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _CROP_H_ +#define _CROP_H_ + +#include +#include +#include +#include +#include +#include +#include + +namespace rtengine { + +using namespace procparams; + +class ImProcCoordinator; + +class Crop : public DetailedCrop { + + protected: + Image16* origCrop, *resizeCrop, *transCrop, *baseCrop; + LabImage *laboCrop, *labnCrop; + Image8 *cropImg; + + int** cbuffer; + SHMap* cshmap; + + bool updating, needsNext; + int skip; + int cropx, cropy, cropw, croph; // size of the detail crop image ('skip' taken into account), with border + int trafx, trafy, trafw, trafh; // the size and position to get from the imagesource that is transformed to the requested crop area + int rqcropx, rqcropy, rqcropw, rqcroph; // size of the requested detail crop image (the image might be smaller) (without border) + int borderRequested, upperBorder, leftBorder; + + + bool cropAllocated; + DetailedCropListener* cropImageListener; + Glib::Mutex cropMutex; + ImProcCoordinator* parent; + + bool setCropSizes (int cx, int cy, int cw, int ch, int skip, bool internal); + void freeAll (); + + public: + Crop (ImProcCoordinator* parent); + ~Crop (); + + bool hasListener () { return cropImageListener; } + void update (int todo, bool internal=false); + void setWindow (int cx, int cy, int cw, int ch, int skip) { setCropSizes (cx, cy, cw, ch, skip, false); } + void fullUpdate (); + void setListener (DetailedCropListener* il); + void destroy () { delete this; } +}; +} +#endif diff --git a/rtengine/ex1simple.cc b/rtengine/ex1simple.cc new file mode 100644 index 000000000..5295df92a --- /dev/null +++ b/rtengine/ex1simple.cc @@ -0,0 +1,83 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +//#include +#include + +class PListener : public rtengine::ProgressListener { + + public: + void setProgressStr (Glib::ustring str) { + std::cout << str << std::endl; + } + void setProgress (double p) { + std::cout << p << std::endl; + } +}; + +int main (int argc, char* argv[]) { + + if (argc<4) { + std::cout << "Usage: rtcmd " << std::endl; + exit(1); + } + + Glib::thread_init (); + + // create and fill settings + rtengine::Settings* s = rtengine::Settings::create (); + s->dualThreadEnabled = true; + s->demosaicMethod = "hphd"; + s->colorCorrectionSteps = 2; + s->iccDirectory = ""; + s->colorimetricIntent = 1; + s->monitorProfile = ""; + // init rtengine + rtengine::init (s); + // the settings can be modified later through the "s" pointer without calling any api function + + // Create a listener object. Any class is appropriate that inherits from rtengine::ProgressListener + PListener pl; + + // Load the image given in the first command line parameter + rtengine::InitialImage* ii; + int errorCode; + ii = rtengine::InitialImage::load (argv[1], true, errorCode, &pl); + if (!ii) + ii = rtengine::InitialImage::load (argv[1], false, errorCode, &pl); + if (!ii) { + std::cout << "Input file not supported." << std::endl; + exit(2); + } + + // create an instance of ProcParams structure that holds the image processing settings. You find the memory map in a separate file and the non-basic types like strings and vectors can be manipulated through helper functions + rtengine::procparams::ProcParams params; + params.load (argv[2]); + +/* First, simplest scenario. Develope image and save it in a file */ + // create a processing job with the loaded image and the current processing parameters + rtengine::ProcessingJob* job = ProcessingJob::create (i, params); + // process image. The error is given back in errorcode. + rtengine::IImage16* res = rtengine::processImage (job, errorCode, &pl); + // save image to disk + res->saveToFile (argv[3]); + // through "res" you can access width/height and pixel data, too +} + diff --git a/rtengine/ex2simple.cc b/rtengine/ex2simple.cc new file mode 100644 index 000000000..941e5787f --- /dev/null +++ b/rtengine/ex2simple.cc @@ -0,0 +1,140 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +//#include +#include + +class PListener : public rtengine::ProgressListener { + + public: + void setProgressStr (Glib::ustring str) { + std::cout << str << std::endl; + } + void setProgress (double p) { + std::cout << p << std::endl; + } +}; + +clas MyPrevImgListener : public rtengine::PreviewImageListener { + + IImage8* i; + + public: + // this method is called when the staged image processor creates a new image to store the resulting preview image (this does not happen too often) + // usually you just have to store it + void setImage (IImage8* img, double scale, procparams::CropParams cp) { + i = img; + } + // if the staged image processor wants to delete the image that stores the preview image, it calls this method. You have to destroy the image. + void delImage (IImage8* img) { + if (img) { + // make sure we dont use this image in an other thread + IImage8* temp = i; + i->getMutex().lock (); + i = NULL; + temp->getMutex().unlock (); + // free it + img->free (); + } + } + // if the preview image changes, this method is called + void imageReady (procparams::CropParams cp) { + // initiate a redraw in the background and return as fast as possible + } + // a possible redraw function: + //void redraw () { + // if (i) { + // i->lock (); + // int w = i->getWidth (); + // int h = i->getHeigt (); + // const char* data = i->getData (); + // ... draw it ... + // i->unlock (); + // } + // } +}; + +int main (int argc, char* argv[]) { + + if (argc<4) { + std::cout << "Usage: rtcmd " << std::endl; + exit(1); + } + + Glib::thread_init (); + + // create and fill settings + rtengine::Settings* s = rtengine::Settings::create (); + s->dualThreadEnabled = true; + s->demosaicMethod = "hphd"; + s->colorCorrectionSteps = 2; + s->iccDirectory = ""; + s->colorimetricIntent = 1; + s->monitorProfile = ""; + // init rtengine + rtengine::init (s); + // the settings can be modified later through the "s" pointer without calling any api function + + // Create a listener object. Any class is appropriate that inherits from rtengine::ProgressListener + PListener pl; + + // Load the image given in the first command line parameter + rtengine::InitialImage* ii; + int errorCode; + ii = rtengine::InitialImage::load (argv[1], true, errorCode, &pl); + if (!ii) + ii = rtengine::InitialImage::load (argv[1], false, errorCode, &pl); + if (!ii) { + std::cout << "Input file not supported." << std::endl; + exit(2); + } + +/* Second scenario. Create a stagedimageprocessor with a preview scale of 1:5 and change few things */ + MyPrevImgListener myPrevImgListener; + + StagedImageProcessor* ipc = StagedImageProcessor::create (ii); + ipc->setProgressListener (&pl); + ipc->setPreviewImageListener (&myPrevImgListener); + ipc->setPreviewScale (5); // preview scale = 1:5 + // you can add a histogram listener, too, that is notified when the histogram changes + // ipc->setHistogramListener (...); + // you can add autoexplistener that is notified about the exposure settings when the auto exp algorithm finishes + // ipc->setAutoExpListener (curve); + // you can add sizelistener if you want to be notified when the size of the final image changes (due to rotation/resize/etc) + // ipc->setSizeListener (crop); + + // if you want to change the settings you have to ask for the procparams structure of the staged image processor + // you have to tell it what has changed. At the first time tell it EvPhotoLoaded so a full processing will be performed + rtengine::procparams::ProcParams* params = ipc->getParamsForUpdate (rtengine::EvPhotoLoaded); + // change this and that... + params->toneCurve.brightness = 1.0; + // you can load it, too, from a file: params->load (argv[2]); + // finally you have to call this non-blocking method, and the image processing starts in the background. When finished, the preview image listener will be notified + ipc->paramsUpdateReady (); + // you can go on with changing of the settings, following the gui actions + // now we know that only the brightness has changed compared to the previous settings, to only a part of the processing has to be repeated + params = ipc->getParamsForUpdate (rtengine::EvBrightness); + params->toneCurve.brightness = 1.2; + ipc->paramsUpdateReady (); + + // ... and so on. If you dont need it any more, you can destroy it (make sure that no processing is happening when you destroy it!) + StagedImageProcessor::destroy (ipc); +} + diff --git a/rtengine/gauss.cc b/rtengine/gauss.cc new file mode 100644 index 000000000..1b208dc9d --- /dev/null +++ b/rtengine/gauss.cc @@ -0,0 +1,49 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include + +void gaussHorizontal_unsigned (unsigned short** src, unsigned short** dst, AlignedBuffer* buffer, int W, int row_from, int row_to, double sigma) { + + gaussHorizontal (src, dst, buffer, W, row_from, row_to, sigma); +} + +void gaussVertical_unsigned (unsigned short** src, unsigned short** dst, AlignedBuffer* buffer, int H, int col_from, int col_to, double sigma) { + + gaussVertical (src, dst, buffer, H, col_from, col_to, sigma); +} + +void gaussHorizontal_signed (short** src, short** dst, AlignedBuffer* buffer, int W, int row_from, int row_to, double sigma) { + + gaussHorizontal (src, dst, buffer, W, row_from, row_to, sigma); +} + +void gaussVertical_signed (short** src, short** dst, AlignedBuffer* buffer, int H, int col_from, int col_to, double sigma) { + + gaussVertical (src, dst, buffer, H, col_from, col_to, sigma); +} + +void gaussHorizontal_float (float** src, float** dst, AlignedBuffer* buffer, int W, int row_from, int row_to, double sigma) { + + gaussHorizontal (src, dst, buffer, W, row_from, row_to, sigma); +} + +void gaussVertical_float (float** src, float** dst, AlignedBuffer* buffer, int H, int col_from, int col_to, double sigma) { + + gaussVertical (src, dst, buffer, H, col_from, col_to, sigma); +} diff --git a/rtengine/gauss.h b/rtengine/gauss.h new file mode 100644 index 000000000..6f708b40f --- /dev/null +++ b/rtengine/gauss.h @@ -0,0 +1,624 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _GAUSS_H_ +#define _GAUSS_H_ + +#include +#include +#include +#include + +#define NOSSE 1 + +#ifndef NOSSE +#include +template void gaussHorizontal3 (T** src, T** dst, T* buffer, int W, int row_from, int row_to, const float c0, const float c1) { + + typedef float pfloat[4]; + pfloat* temp = (pfloat*)buffer + 1; + pfloat* tmp = (pfloat*)buffer; + + __m128 xmm1; xmm1 = _mm_load1_ps (&c0); + __m128 xmm2; xmm2 = _mm_load1_ps (&c1); + __m128 xmm3; __m128 xmm4; __m128 xmm5; __m128 xmm6; + __m128 xmm0; + + int i; + for (i = row_from; i void gaussHorizontal3 (T** src, T** dst, T* buffer, int W, int row_from, int row_to, const int c0, const int c1) { + + time_t t1 = clock (); + + const int csum = c0 + 2 * c1; + for (int i = row_from; i void gaussVertical3 (T** src, T** dst, T* buffer, int H, int col_from, int col_to, const float c0, const float c1) { + + typedef float pfloat[4]; + pfloat* temp = (pfloat*)buffer + 1; + pfloat* tmp = (pfloat*)buffer; + + __m128 xmm1; xmm1 = _mm_load1_ps (&c0); + __m128 xmm2; xmm2 = _mm_load1_ps (&c1); + __m128 xmm3; __m128 xmm4; __m128 xmm5; __m128 xmm6; + __m128 xmm0; + + int i; + for (i = col_from; i void gaussVertical3 (T** src, T** dst, T* buffer, int H, int col_from, int col_to, const float c0, const float c1) { + + time_t t1 = clock (); + + int stride = dst[1] - dst[0]; + for (int j=col_from; j void gaussHorizontal (T** src, T** dst, AlignedBuffer* buffer, int W, int row_from, int row_to, double sigma) { + + if (sigma<0.25) { + // dont perform filtering + if (src!=dst) + for (int i = row_from; i (src, dst, (T*)(buffer->data), W, row_from, row_to, (int) round(c0), 2); + double c1 = exp (-1.0 / (2.0 * sigma * sigma)); + double csum = 2.0 * c1 + 1.0; + c1 /= csum; + double c0 = 1.0 / csum; + gaussHorizontal3 (src, dst, (T*)(buffer->data), W, row_from, row_to, c0, c1); + return; + } + + // horizontal + float q = 0.98711 * sigma - 0.96330; + if (sigma<2.5) + q = 3.97156 - 4.14554 * sqrt (1.0 - 0.26891 * sigma); + float b0 = 1.57825 + 2.44413*q + 1.4281*q*q + 0.422205*q*q*q; + float b1 = 2.44413*q + 2.85619*q*q + 1.26661*q*q*q; + float b2 = -1.4281*q*q - 1.26661*q*q*q; + float b3 = 0.422205*q*q*q; + float B = 1.0 - (b1+b2+b3) / b0; + + b1 /= b0; + b2 /= b0; + b3 /= b0; + + // SSE optimized version: + __m128 xmm1; xmm1 = _mm_load1_ps (&B); + __m128 xmm2; xmm2 = _mm_load1_ps (&b1); + __m128 xmm3; xmm3 = _mm_load1_ps (&b2); + __m128 xmm4; xmm4 = _mm_load1_ps (&b3); + __m128 xmm5; + __m128 xmm6; + + typedef float pfloat[4]; + pfloat* temp = (pfloat*)buffer->data + 1; + pfloat* tmp = (pfloat*)buffer->data; + + memset (temp, 0, W*sizeof(pfloat)); + + int i; + for (i=row_from; i=0; j--) { + xmm5 = _mm_load_ps ((float*)&temp[j]); + xmm5 =_mm_mul_ps (xmm1, xmm5); + xmm6 = _mm_load_ps ((float*)&temp[j+1]); + xmm6 = _mm_mul_ps (xmm2, xmm6); + xmm5 = _mm_add_ps (xmm6, xmm5); + xmm6 = _mm_load_ps ((float*)&temp[j+2]); + xmm6 = _mm_mul_ps (xmm6, xmm3); + xmm5 = _mm_add_ps (xmm5, xmm6); + xmm6 = _mm_load_ps ((float*)&temp[j+3]); + xmm6 = _mm_mul_ps (xmm6, xmm4); + xmm5 = _mm_add_ps (xmm5, xmm6); + _mm_store_ps ((float*)&temp[j], xmm5); + } + for (int j=0; jdata; + for (; i=0; j--) + temp2[j] = B * temp2[j] + b1*temp2[j+1] + b2*temp2[j+2] + b3*temp2[j+3]; + for (int j=0; j void gaussVertical (T** src, T** dst, AlignedBuffer* buffer, int H, int col_from, int col_to, double sigma) { + + if (sigma<0.25) { + // dont perform filtering + if (src!=dst) + for (int i = 0; i (src, dst, (T*)(buffer->data), H, col_from, col_to, c0, c1); +// double c0 = 2.0 / exp (-1.0 / (2.0 * sigma * sigma)); +// gaussVertical3 (src, dst, (T*)(buffer->data), H, col_from, col_to, (int) round(c0), 2); + return; + } + + // vertical + float q = 0.98711 * sigma - 0.96330; + if (sigma<2.5) + q = 3.97156 - 4.14554 * sqrt (1.0 - 0.26891 * sigma); + float b0 = 1.57825 + 2.44413*q + 1.4281*q*q + 0.422205*q*q*q; + float b1 = 2.44413*q + 2.85619*q*q + 1.26661*q*q*q; + float b2 = -1.4281*q*q - 1.26661*q*q*q; + float b3 = 0.422205*q*q*q; + float B = 1.0 - (b1+b2+b3) / b0; + + b1 /= b0; + b2 /= b0; + b3 /= b0; + + // SSE optimized version: + __m128 xmm1; xmm1 = _mm_load1_ps (&B); + __m128 xmm2; xmm2 = _mm_load1_ps (&b1); + __m128 xmm3; xmm3 = _mm_load1_ps (&b2); + __m128 xmm4; xmm4 = _mm_load1_ps (&b3); + __m128 xmm5; + __m128 xmm6; + + typedef float pfloat[4]; + pfloat* temp = (pfloat*)buffer->data + 1; + pfloat* tmp = (pfloat*)buffer->data; + + memset (temp, 0, H*sizeof(pfloat)); + + int i; + for (i=col_from; i=0; j--) { + xmm5 = _mm_load_ps ((float*)&temp[j]); + xmm5 =_mm_mul_ps (xmm1, xmm5); + xmm6 = _mm_load_ps ((float*)&temp[j+1]); + xmm6 = _mm_mul_ps (xmm2, xmm6); + xmm5 = _mm_add_ps (xmm6, xmm5); + xmm6 = _mm_load_ps ((float*)&temp[j+2]); + xmm6 = _mm_mul_ps (xmm6, xmm3); + xmm5 = _mm_add_ps (xmm5, xmm6); + xmm6 = _mm_load_ps ((float*)&temp[j+3]); + xmm6 = _mm_mul_ps (xmm6, xmm4); + xmm5 = _mm_add_ps (xmm5, xmm6); + _mm_store_ps ((float*)&temp[j], xmm5); + } + for (int j=0; jdata; + for (; i=0; j--) + temp2[j] = B * temp2[j] + b1*temp2[j+1] + b2*temp2[j+2] + b3*temp2[j+3]; + for (int j=0; j void gaussHorizontal3 (T** src, T** dst, T* buffer, int W, int row_from, int row_to, const float c0, const float c1) { + + for (int i=row_from; i void gaussVertical3 (T** src, T** dst, T* buffer, int H, int col_from, int col_to, const float c0, const float c1) { + + for (int i=col_from; i void gaussHorizontal (T** src, T** dst, AlignedBuffer* buffer, int W, int row_from, int row_to, double sigma) { + + if (sigma<0.25) { + // dont perform filtering + if (src!=dst) + for (int i = row_from; i (src, dst, (T*)(buffer->data), W, row_from, row_to, c0, c1); + return; + } + + // horizontal + double q = 0.98711 * sigma - 0.96330; + if (sigma<2.5) + q = 3.97156 - 4.14554 * sqrt (1.0 - 0.26891 * sigma); + double b0 = 1.57825 + 2.44413*q + 1.4281*q*q + 0.422205*q*q*q; + double b1 = 2.44413*q + 2.85619*q*q + 1.26661*q*q*q; + double b2 = -1.4281*q*q - 1.26661*q*q*q; + double b3 = 0.422205*q*q*q; + double B = 1.0 - (b1+b2+b3) / b0; + + b1 /= b0; + b2 /= b0; + b3 /= b0; + + // From: Bill Triggs, Michael Sdika: Boundary Conditions for Young-van Vliet Recursive Filtering + double M[3][3]; + M[0][0] = -b3*b1+1.0-b3*b3-b2; + M[0][1] = (b3+b1)*(b2+b3*b1); + M[0][2] = b3*(b1+b3*b2); + M[1][0] = b1+b3*b2; + M[1][1] = -(b2-1.0)*(b2+b3*b1); + M[1][2] = -(b3*b1+b3*b3+b2-1.0)*b3; + M[2][0] = b3*b1+b2+b1*b1-b2*b2; + M[2][1] = b1*b2+b3*b2*b2-b1*b3*b3-b3*b3*b3-b3*b2+b3; + M[2][2] = b3*(b1+b3*b2); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + M[i][j] /= (1.0+b1-b2+b3)*(1.0+b2+(b1-b3)*b3); + + double* temp2 = (double*)buffer->data; + for (int i=row_from; i=0; j--) + temp2[j] = B * temp2[j] + b1*temp2[j+1] + b2*temp2[j+2] + b3*temp2[j+3]; + for (int j=0; j void gaussVertical (T** src, T** dst, AlignedBuffer* buffer, int H, int col_from, int col_to, double sigma) { + + if (sigma<0.25) { + // dont perform filtering + if (src!=dst) + for (int i = 0; i (src, dst, (T*)(buffer->data), H, col_from, col_to, c0, c1); + return; + } + + // vertical + double q = 0.98711 * sigma - 0.96330; + if (sigma<2.5) + q = 3.97156 - 4.14554 * sqrt (1.0 - 0.26891 * sigma); + double b0 = 1.57825 + 2.44413*q + 1.4281*q*q + 0.422205*q*q*q; + double b1 = 2.44413*q + 2.85619*q*q + 1.26661*q*q*q; + double b2 = -1.4281*q*q - 1.26661*q*q*q; + double b3 = 0.422205*q*q*q; + double B = 1.0 - (b1+b2+b3) / b0; + + b1 /= b0; + b2 /= b0; + b3 /= b0; + + // From: Bill Triggs, Michael Sdika: Boundary Conditions for Young-van Vliet Recursive Filtering + double M[3][3]; + M[0][0] = -b3*b1+1.0-b3*b3-b2; + M[0][1] = (b3+b1)*(b2+b3*b1); + M[0][2] = b3*(b1+b3*b2); + M[1][0] = b1+b3*b2; + M[1][1] = -(b2-1.0)*(b2+b3*b1); + M[1][2] = -(b3*b1+b3*b3+b2-1.0)*b3; + M[2][0] = b3*b1+b2+b1*b1-b2*b2; + M[2][1] = b1*b2+b3*b2*b2-b1*b3*b3-b3*b3*b3-b3*b2+b3; + M[2][2] = b3*(b1+b3*b2); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + M[i][j] /= (1.0+b1-b2+b3)*(1.0+b2+(b1-b3)*b3); + + double* temp2 = (double*)buffer->data; + for (int i=col_from; i=0; j--) + temp2[j] = B * temp2[j] + b1*temp2[j+1] + b2*temp2[j+2] + b3*temp2[j+3]; + + for (int j=0; j* buffer, int W, int row_from, int row_to, double sigma); +void gaussVertical_unsigned (unsigned short** src, unsigned short** dst, AlignedBuffer* buffer, int H, int col_from, int col_to, double sigma); +void gaussHorizontal_signed (short** src, short** dst, AlignedBuffer* buffer, int W, int row_from, int row_to, double sigma); +void gaussVertical_signed (short** src, short** dst, AlignedBuffer* buffer, int H, int col_from, int col_to, double sigma); +void gaussHorizontal_float (float** src, float** dst, AlignedBuffer* buffer, int W, int row_from, int row_to, double sigma); +void gaussVertical_float (float** src, float** dst, AlignedBuffer* buffer, int H, int col_from, int col_to, double sigma); + +#endif diff --git a/rtengine/hlmultipliers.cc b/rtengine/hlmultipliers.cc new file mode 100644 index 000000000..eafa43d62 --- /dev/null +++ b/rtengine/hlmultipliers.cc @@ -0,0 +1,350 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +#define MAXVAL 0xffff +#define CLIP(a) ((a)>0?((a)0)// && phase!=4) +// continue; + if (phase==-1 || phase==0 || phase==2) { + if (rec[0][i][j] == INT_MAX && rec[1][i][j] != INT_MAX && rec[1][i][j] >=0 && rec[2][i][j] != INT_MAX && rec[2][i][j] >=0) { + co = 0; + c1 = 1; + c2 = 2; + } + else if (rec[1][i][j] == INT_MAX && rec[0][i][j] != INT_MAX && rec[0][i][j] >=0 && rec[2][i][j] != INT_MAX && rec[2][i][j] >=0) { + co = 1; + c1 = 0; + c2 = 2; + } + else if (rec[2][i][j] == INT_MAX && rec[1][i][j] != INT_MAX && rec[1][i][j] >=0 && rec[0][i][j] != INT_MAX && rec[0][i][j] >=0) { + co = 2; + c1 = 1; + c2 = 0; + } + else + continue; + + double ratio[2] = {0.0, 0.0}; + int count = 0; + double rato = (double)rec[c1][i][j] / rec[c2][i][j]; + double arato = 0.0; + if (phase==2) { + for (int x=-1; x<=1; x++) + for (int y=-1; y<=1; y++) { + // average m/c color ratios in the surrounding pixels + if (rec[co][i+x][j+y]>=0 && rec[co][i+x][j+y]!=INT_MAX && rec[c1][i+x][j+y]>=0 && rec[c1][i+x][j+y]!=INT_MAX && rec[c2][i+x][j+y]>0 && rec[c2][i+x][j+y]!=INT_MAX) { + double ratt = (double)rec[c1][i+x][j+y] / rec[c2][i+x][j+y]; + if (ratt > rato*1.2 || ratt < rato / 1.2 || rec[co][i+x][j+y]=0 && rec[co][i+x][j+y]!=INT_MAX && rec[c1][i+x][j+y]>=0 && rec[c1][i+x][j+y]!=INT_MAX && rec[c2][i+x][j+y]>0 && rec[c2][i+x][j+y]!=INT_MAX) { + double ratt = (double)rec[c1][i+x][j+y] / rec[c2][i+x][j+y]; + if (ratt > rato*1.05 || ratt < rato / 1.05 || rec[co][i+x][j+y]=0 && rec[co][i+x][j+y]!=INT_MAX && rec[c1][i+x][j+y]>=0 && rec[c1][i+x][j+y]!=INT_MAX && rec[c2][i+x][j+y]>0 && rec[c2][i+x][j+y]!=INT_MAX) { + double ratt = (double)rec[c1][i+x][j+y] / rec[c2][i+x][j+y]; + if (ratt > rato*1.1 || ratt < rato / 1.1 || rec[co][i+x][j+y]1) { //(phase==0 && count>1) || (phase==2 && count>1)) { + rec[co][i][j] = -(int)((rec[c1][i][j] / ratio[0] * count + rec[c2][i][j] / ratio[1] * count) / 2); + changed++; + } + } + else if (phase==1 || phase==3) { + if (rec[0][i][j] == INT_MAX && rec[1][i][j] == INT_MAX && rec[2][i][j] != INT_MAX && rec[2][i][j] >=0) { + co = 2; + c1 = 0; + c2 = 1; + } + else if (rec[0][i][j] == INT_MAX && rec[2][i][j] == INT_MAX && rec[1][i][j] != INT_MAX && rec[1][i][j] >=0) { + co = 1; + c1 = 0; + c2 = 2; + } + else if (rec[1][i][j] == INT_MAX && rec[2][i][j] == INT_MAX && rec[0][i][j] != INT_MAX && rec[0][i][j] >=0) { + co = 0; + c1 = 1; + c2 = 2; + } + else + continue; + + double ratio[2] = {0.0, 0.0}; + int count[2] = {0, 0}; + int ix = 0; + for (int x=-1; x<=1; x++) + for (int y=-1; y<=1; y++) { + // average m/c color ratios in the surrounding pixels + if (rec[co][i+x][j+y]>=0 && rec[co][i+x][j+y]!=INT_MAX && rec[c1][i+x][j+y]>0 && rec[c1][i+x][j+y]!=INT_MAX) { + if ((phase==1 && rec[c1][i+x][j+y]=0 && rec[co][i+x][j+y]!=INT_MAX && rec[c2][i+x][j+y]>0 && rec[c2][i+x][j+y]!=INT_MAX) { + if ((phase==1 && rec[c2][i+x][j+y]2) || (phase==3 && count[0]>1)) { + rec[c1][i][j] = - (int) ((double)rec[co][i][j] / ratio[0] * count[0]); + changed++; + } + if ((phase==1 && count[1]>2) || (phase==3 && count[1]>1)) { + rec[c2][i][j] = - (int) ((double)rec[co][i][j] / ratio[1] * count[1]); + changed++; + } + } + else { + int val = 0; + int num = 0; + for (int c=0; c<3; c++) + if (rec[c][i][j]!=INT_MAX) { + val += rec[c][i][j]; + num++; + } + if (num<3 && num>0) { + for (int c=0; c<3; c++) + rec[c][i][j] = val / num; + } + } + } + + + bool change = false; + for (int i=1; i=H/HR_SCALE-2) + return; + double mr1 = 1.0 - ((double)((i+HR_SCALE/2) % HR_SCALE) / HR_SCALE + 0.5 / HR_SCALE); + int jx = 0; + int maxcol = W/HR_SCALE-2; + for (int j=sx1, jx=0; jx=maxcol) + continue; + double mc1 = 1.0 - ((double)((j+HR_SCALE/2) % HR_SCALE) / HR_SCALE + 0.5 / HR_SCALE); + double mulr = mr1*mc1 * hrmap[0][blr][blc] + mr1*(1.0-mc1) * hrmap[0][blr][blc+1] + (1.0-mr1)*mc1 * hrmap[0][blr+1][blc] + (1.0-mr1)*(1.0-mc1) * hrmap[0][blr+1][blc+1]; + double mulg = mr1*mc1 * hrmap[1][blr][blc] + mr1*(1.0-mc1) * hrmap[1][blr][blc+1] + (1.0-mr1)*mc1 * hrmap[1][blr+1][blc] + (1.0-mr1)*(1.0-mc1) * hrmap[1][blr+1][blc+1]; + double mulb = mr1*mc1 * hrmap[2][blr][blc] + mr1*(1.0-mc1) * hrmap[2][blr][blc+1] + (1.0-mr1)*mc1 * hrmap[2][blr+1][blc] + (1.0-mr1)*(1.0-mc1) * hrmap[2][blr+1][blc+1]; + red[jx] = CLIP(red[jx] * mulr); + green[jx] = CLIP(green[jx] * mulg); + blue[jx] = CLIP(blue[jx] * mulb); + } + } +} + +void RawImageSource::updateHLRecoveryMap_ColorPropagation () { + + // detect maximal pixel values + unsigned short* red = new unsigned short[W]; + unsigned short* blue = new unsigned short[W]; + int maxr = 0, maxg = 0, maxb = 0; + for (int i=32; ifilters) && red[j] > maxr) maxr = red[j]; + if ((ISGREEN(ri,i,j) || !ri->filters) && green[i][j] > maxg) maxg = green[i][j]; + if ((ISBLUE(ri,i,j) || !ri->filters) && blue[j] > maxb) maxb = blue[j]; + } + } + delete [] red; + delete [] blue; + + maxr = maxr * 19 / 20; + maxg = maxg * 19 / 20; + maxb = maxb * 19 / 20; + max[0] = maxr; + max[1] = maxg; + max[2] = maxb; + + // downscale image + int dw = W/HR_SCALE; + int dh = H/HR_SCALE; + Image16* ds = new Image16 (dw, dh); + + // overburnt areas + int** rec[3]; + for (int i=0; i<3; i++) + rec[i] = allocArray (dw, dh); + + unsigned short* reds[HR_SCALE]; + unsigned short* blues[HR_SCALE]; + for (int i=0; i(needhr, H); + needhr = allocArray (W, H); + + for (int i=0; i=max[0] || green[HR_SCALE*i+j][k]>=max[1] || blues[j][k]>=max[2]) + needhr[HR_SCALE*i+j][k] = 1; + else + needhr[HR_SCALE*i+j][k] = 0; + } + for (int j=0; jr[i][j] = sumr / HR_SCALE/HR_SCALE; + ds->g[i][j] = sumg / HR_SCALE/HR_SCALE; + ds->b[i][j] = sumb / HR_SCALE/HR_SCALE; + } + } + for (int i=0; i (hrmap[0], dh); + freeArray (hrmap[1], dh); + freeArray (hrmap[2], dh); + } + + hrmap[0] = allocArray (dw, dh); + hrmap[1] = allocArray (dw, dh); + hrmap[2] = allocArray (dw, dh); + + for (int i=0; ir[i][j]>0 ? (double)rec[0][i][j] / ds->r[i][j] : 1.0; + hrmap[1][i][j] = ds->g[i][j]>0 ? (double)rec[1][i][j] / ds->g[i][j] : 1.0; + hrmap[2][i][j] = ds->b[i][j]>0 ? (double)rec[2][i][j] / ds->b[i][j] : 1.0; + } + + delete ds; + + freeArray (rec[0], dh); + freeArray (rec[1], dh); + freeArray (rec[2], dh); +} + +} + diff --git a/rtengine/hlrecovery.cc b/rtengine/hlrecovery.cc new file mode 100644 index 000000000..d19769f92 --- /dev/null +++ b/rtengine/hlrecovery.cc @@ -0,0 +1,287 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ + +namespace rtengine { + +template T** allocArray (int W, int H) { + + T** t = new T*[H]; + for (int i=0; i maxr) maxr = red[j]; + if (green[i][j] > maxg) maxg = green[i][j]; + if (blue[j] > maxb) maxb = blue[j]; + } + } + delete [] red; + delete [] blue; + + maxr = maxr * 19 / 20; + maxg = maxg * 19 / 20; + maxb = maxb * 19 / 20; + int max[3]; + max[0] = maxr; + max[1] = maxg; + max[2] = maxb; + + printf ("Maximum: R: %d, G: %d, B: %d\n", maxr, maxg, maxb); + + // downscale image + int dw = W/SCALE; + int dh = H/SCALE; + Image16* ds = new Image16 (dw, dh); + + // overburnt areas + int** rec[3]; + for (int i=0; i<3; i++) + rec[i] = allocArray (dw, dh); + + unsigned short* reds[SCALE]; + unsigned short* blues[SCALE]; + for (int i=0; ir[i][j] = sumr / SCALE/SCALE; + ds->g[i][j] = sumg / SCALE/SCALE; + ds->b[i][j] = sumb / SCALE/SCALE; + } + } + for (int i=0; i200) + phase2 = true; + for (int i=1; i=0) { + for (int x=-1; x<=1; x++) + for (int y=-1; y<=1; y++) + // average m/c color ratios in the surrounding pixels + if (rec[m][i+x][j+y]>=0 && rec[m][i+x][j+y]!=INT_MAX && rec[c][i+x][j+y]>0 && rec[c][i+x][j+y]!=INT_MAX) { + double ww = 1.0; + if (!phase2 && (/*(double)(rec[m][i+x][j+y] - rec[m][i][j])/max[m]*(rec[m][i+x][j+y] - rec[m][i][j])/max[m] > 1.0/2 || */rec[c][i+x][j+y]200) + phase2 = true; + for (int i=1; i0 && rec[0][i+x][j+y]!=INT_MAX && rec[1][i+x][j+y]>0 && rec[1][i+x][j+y]!=INT_MAX && rec[2][i+x][j+y]>0 && rec[2][i+x][j+y]!=INT_MAX) { + // convert to yiq + double Y = 0.299 * rec[0][i+x][j+y] + 0.587 * rec[1][i+x][j+y] + 0.114 * rec[2][i+x][j+y]; + double I = 0.596 * rec[0][i+x][j+y] - 0.275 * rec[1][i+x][j+y] - 0.321 * rec[2][i+x][j+y]; + double Q = 0.212 * rec[0][i+x][j+y] - 0.523 * rec[1][i+x][j+y] + 0.311 * rec[2][i+x][j+y]; + if (Y > maxY*7/10) { + double w = 1.0;// / (I*I+Q*Q); + yavg += Y*w; + iavg += I*w; + qavg += Q*w; + weight += w; + count++; + } + } + if ((!phase2 && count>5) || (phase2 && count>3)) { + double Y = yavg / weight; + double I = iavg / weight; + double Q = qavg / weight; + rec[0][i][j] = - (Y + 0.956*I + 0.621*Q); + rec[1][i][j] = - (Y - 0.272*I - 0.647*Q); + rec[2][i][j] = - (Y - 1.105*I + 1.702*Q); + } + } + + } + bool change = false; + for (int i=0; imaxval) + maxval = rec[c][i][j]; + + for (int i=0; i (hrmap[0], dh); + freeArray (hrmap[1], dh); + freeArray (hrmap[2], dh); + } + hrmap[0] = allocArray (dw, dh); + hrmap[1] = allocArray (dw, dh); + hrmap[2] = allocArray (dw, dh); + + this->full = full; + + for (int i=0; ir[i][j]; + hrmap[1][i][j] = (double)rec[1][i][j] / ds->g[i][j]; + hrmap[2][i][j] = (double)rec[2][i][j] / ds->b[i][j]; + } + +/* for (int i=0; ir[i][j] = CLIP (rec[0][i][j]); + ds->g[i][j] = CLIP (rec[1][i][j]); + ds->b[i][j] = CLIP (rec[2][i][j]); + } + ds->save ("test.png"); +*/ + delete ds; + freeArray (rec[0], dh); + freeArray (rec[1], dh); + freeArray (rec[2], dh); + + printf ("HLMap vege\n"); +} + +void RawImageSource::hlRecovery (unsigned short* red, unsigned short* green, unsigned short* blue, int i, int sx1, int sx2, int skip) { + + int blr = (i+SCALE/2) / SCALE - 1; + if (blr<0 || blr>=H/SCALE-1) + return; + double mr1 = 1.0 - ((double)((i+SCALE/2) % SCALE) / SCALE + 0.5 / SCALE); + int jx = 0; + int maxcol = W/SCALE; + for (int j=sx1, jx=0; j=maxcol-1) + continue; + double mc1 = 1.0 - ((double)((j+SCALE/2) % SCALE) / SCALE + 0.5 / SCALE); + double mulr = mr1*mc1 * hrmap[0][blr][blc] + mr1*(1.0-mc1) * hrmap[0][blr][blc+1] + (1.0-mr1)*mc1 * hrmap[0][blr+1][blc] + (1.0-mr1)*(1.0-mc1) * hrmap[0][blr+1][blc+1]; + double mulg = mr1*mc1 * hrmap[1][blr][blc] + mr1*(1.0-mc1) * hrmap[1][blr][blc+1] + (1.0-mr1)*mc1 * hrmap[1][blr+1][blc] + (1.0-mr1)*(1.0-mc1) * hrmap[1][blr+1][blc+1]; + double mulb = mr1*mc1 * hrmap[2][blr][blc] + mr1*(1.0-mc1) * hrmap[2][blr][blc+1] + (1.0-mr1)*mc1 * hrmap[2][blr+1][blc] + (1.0-mr1)*(1.0-mc1) * hrmap[2][blr+1][blc+1]; + red[jx] = CLIP(red[jx] * mulr); + green[jx] = CLIP(green[jx] * mulg); + blue[jx] = CLIP(blue[jx] * mulb); + } +} +} + diff --git a/rtengine/iccjpeg.c b/rtengine/iccjpeg.c new file mode 100644 index 000000000..392259373 --- /dev/null +++ b/rtengine/iccjpeg.c @@ -0,0 +1,256 @@ +/* + * iccprofile.c + * + * This file provides code to read and write International Color Consortium + * (ICC) device profiles embedded in JFIF JPEG image files. The ICC has + * defined a standard format for including such data in JPEG "APP2" markers. + * The code given here does not know anything about the internal structure + * of the ICC profile data; it just knows how to put the profile data into + * a JPEG file being written, or get it back out when reading. + * + * This code depends on new features added to the IJG JPEG library as of + * IJG release 6b; it will not compile or work with older IJG versions. + * + * NOTE: this code would need surgery to work on 16-bit-int machines + * with ICC profiles exceeding 64K bytes in size. If you need to do that, + * change all the "unsigned int" variables to "INT32". You'll also need + * to find a malloc() replacement that can allocate more than 64K. + */ + +#include "iccjpeg.h" +#include /* define malloc() */ + + +/* + * Since an ICC profile can be larger than the maximum size of a JPEG marker + * (64K), we need provisions to split it into multiple markers. The format + * defined by the ICC specifies one or more APP2 markers containing the + * following data: + * Identifying string ASCII "ICC_PROFILE\0" (12 bytes) + * Marker sequence number 1 for first APP2, 2 for next, etc (1 byte) + * Number of markers Total number of APP2's used (1 byte) + * Profile data (remainder of APP2 data) + * Decoders should use the marker sequence numbers to reassemble the profile, + * rather than assuming that the APP2 markers appear in the correct sequence. + */ + +#define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */ +#define ICC_OVERHEAD_LEN 14 /* size of non-profile data in APP2 */ +#define MAX_BYTES_IN_MARKER 65533 /* maximum data len of a JPEG marker */ +#define MAX_DATA_BYTES_IN_MARKER (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN) + + +/* + * This routine writes the given ICC profile data into a JPEG file. + * It *must* be called AFTER calling jpeg_start_compress() and BEFORE + * the first call to jpeg_write_scanlines(). + * (This ordering ensures that the APP2 marker(s) will appear after the + * SOI and JFIF or Adobe markers, but before all else.) + */ + +void +write_icc_profile (j_compress_ptr cinfo, + const JOCTET *icc_data_ptr, + unsigned int icc_data_len) +{ + unsigned int num_markers; /* total number of markers we'll write */ + int cur_marker = 1; /* per spec, counting starts at 1 */ + unsigned int length; /* number of bytes to write in this marker */ + + /* Calculate the number of markers we'll need, rounding up of course */ + num_markers = icc_data_len / MAX_DATA_BYTES_IN_MARKER; + if (num_markers * MAX_DATA_BYTES_IN_MARKER != icc_data_len) + num_markers++; + + while (icc_data_len > 0) { + /* length of profile to put in this marker */ + length = icc_data_len; + if (length > MAX_DATA_BYTES_IN_MARKER) + length = MAX_DATA_BYTES_IN_MARKER; + icc_data_len -= length; + + /* Write the JPEG marker header (APP2 code and marker length) */ + jpeg_write_m_header(cinfo, ICC_MARKER, + (unsigned int) (length + ICC_OVERHEAD_LEN)); + + /* Write the marker identifying string "ICC_PROFILE" (null-terminated). + * We code it in this less-than-transparent way so that the code works + * even if the local character set is not ASCII. + */ + jpeg_write_m_byte(cinfo, 0x49); + jpeg_write_m_byte(cinfo, 0x43); + jpeg_write_m_byte(cinfo, 0x43); + jpeg_write_m_byte(cinfo, 0x5F); + jpeg_write_m_byte(cinfo, 0x50); + jpeg_write_m_byte(cinfo, 0x52); + jpeg_write_m_byte(cinfo, 0x4F); + jpeg_write_m_byte(cinfo, 0x46); + jpeg_write_m_byte(cinfo, 0x49); + jpeg_write_m_byte(cinfo, 0x4C); + jpeg_write_m_byte(cinfo, 0x45); + jpeg_write_m_byte(cinfo, 0x0); + + /* Add the sequencing info */ + jpeg_write_m_byte(cinfo, cur_marker); + jpeg_write_m_byte(cinfo, (int) num_markers); + + /* Add the profile data */ + while (length--) { + jpeg_write_m_byte(cinfo, *icc_data_ptr); + icc_data_ptr++; + } + cur_marker++; + } +} + + +/* + * Prepare for reading an ICC profile + */ + +void +setup_read_icc_profile (j_decompress_ptr cinfo) +{ + /* Tell the library to keep any APP2 data it may find */ + jpeg_save_markers(cinfo, ICC_MARKER, 0xFFFF); +} + + +/* + * Handy subroutine to test whether a saved marker is an ICC profile marker. + */ +#ifdef WIN32 +static jboolean +#else +static boolean +#endif +marker_is_icc (jpeg_saved_marker_ptr marker) +{ + return + marker->marker == ICC_MARKER && + marker->data_length >= ICC_OVERHEAD_LEN && + /* verify the identifying string */ + GETJOCTET(marker->data[0]) == 0x49 && + GETJOCTET(marker->data[1]) == 0x43 && + GETJOCTET(marker->data[2]) == 0x43 && + GETJOCTET(marker->data[3]) == 0x5F && + GETJOCTET(marker->data[4]) == 0x50 && + GETJOCTET(marker->data[5]) == 0x52 && + GETJOCTET(marker->data[6]) == 0x4F && + GETJOCTET(marker->data[7]) == 0x46 && + GETJOCTET(marker->data[8]) == 0x49 && + GETJOCTET(marker->data[9]) == 0x4C && + GETJOCTET(marker->data[10]) == 0x45 && + GETJOCTET(marker->data[11]) == 0x0; +} + + +/* + * See if there was an ICC profile in the JPEG file being read; + * if so, reassemble and return the profile data. + * + * TRUE is returned if an ICC profile was found, FALSE if not. + * If TRUE is returned, *icc_data_ptr is set to point to the + * returned data, and *icc_data_len is set to its length. + * + * IMPORTANT: the data at **icc_data_ptr has been allocated with malloc() + * and must be freed by the caller with free() when the caller no longer + * needs it. (Alternatively, we could write this routine to use the + * IJG library's memory allocator, so that the data would be freed implicitly + * at jpeg_finish_decompress() time. But it seems likely that many apps + * will prefer to have the data stick around after decompression finishes.) + * + * NOTE: if the file contains invalid ICC APP2 markers, we just silently + * return FALSE. You might want to issue an error message instead. + */ + +#ifdef WIN32 +jboolean +#else +boolean +#endif +read_icc_profile (j_decompress_ptr cinfo, + JOCTET **icc_data_ptr, + unsigned int *icc_data_len) +{ + jpeg_saved_marker_ptr marker; + int num_markers = 0; + int seq_no; + JOCTET *icc_data; + unsigned int total_length; +#define MAX_SEQ_NO 255 /* sufficient since marker numbers are bytes */ + char marker_present[MAX_SEQ_NO+1]; /* 1 if marker found */ + unsigned int data_length[MAX_SEQ_NO+1]; /* size of profile data in marker */ + unsigned int data_offset[MAX_SEQ_NO+1]; /* offset for data in marker */ + + *icc_data_ptr = NULL; /* avoid confusion if FALSE return */ + *icc_data_len = 0; + + /* This first pass over the saved markers discovers whether there are + * any ICC markers and verifies the consistency of the marker numbering. + */ + + for (seq_no = 1; seq_no <= MAX_SEQ_NO; seq_no++) + marker_present[seq_no] = 0; + + for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { + if (marker_is_icc(marker)) { + if (num_markers == 0) + num_markers = GETJOCTET(marker->data[13]); + else if (num_markers != GETJOCTET(marker->data[13])) + return FALSE; /* inconsistent num_markers fields */ + seq_no = GETJOCTET(marker->data[12]); + if (seq_no <= 0 || seq_no > num_markers) + return FALSE; /* bogus sequence number */ + if (marker_present[seq_no]) + return FALSE; /* duplicate sequence numbers */ + marker_present[seq_no] = 1; + data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN; + } + } + + if (num_markers == 0) + return FALSE; + + /* Check for missing markers, count total space needed, + * compute offset of each marker's part of the data. + */ + + total_length = 0; + for (seq_no = 1; seq_no <= num_markers; seq_no++) { + if (marker_present[seq_no] == 0) + return FALSE; /* missing sequence number */ + data_offset[seq_no] = total_length; + total_length += data_length[seq_no]; + } + + if (total_length <= 0) + return FALSE; /* found only empty markers? */ + + /* Allocate space for assembled data */ + icc_data = (JOCTET *) malloc(total_length * sizeof(JOCTET)); + if (icc_data == NULL) + return FALSE; /* oops, out of memory */ + + /* and fill it in */ + for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { + if (marker_is_icc(marker)) { + JOCTET FAR *src_ptr; + JOCTET *dst_ptr; + unsigned int length; + seq_no = GETJOCTET(marker->data[12]); + dst_ptr = icc_data + data_offset[seq_no]; + src_ptr = marker->data + ICC_OVERHEAD_LEN; + length = data_length[seq_no]; + while (length--) { + *dst_ptr++ = *src_ptr++; + } + } + } + + *icc_data_ptr = icc_data; + *icc_data_len = total_length; + + return TRUE; +} + diff --git a/rtengine/iccjpeg.h b/rtengine/iccjpeg.h new file mode 100644 index 000000000..494c646f7 --- /dev/null +++ b/rtengine/iccjpeg.h @@ -0,0 +1,80 @@ +/* + * iccprofile.h + * + * This file provides code to read and write International Color Consortium + * (ICC) device profiles embedded in JFIF JPEG image files. The ICC has + * defined a standard format for including such data in JPEG "APP2" markers. + * The code given here does not know anything about the internal structure + * of the ICC profile data; it just knows how to put the profile data into + * a JPEG file being written, or get it back out when reading. + * + * This code depends on new features added to the IJG JPEG library as of + * IJG release 6b; it will not compile or work with older IJG versions. + * + * NOTE: this code would need surgery to work on 16-bit-int machines + * with ICC profiles exceeding 64K bytes in size. See iccprofile.c + * for details. + */ + +#include /* needed to define "FILE", "NULL" */ +#include "jpeglib.h" + + +/* + * This routine writes the given ICC profile data into a JPEG file. + * It *must* be called AFTER calling jpeg_start_compress() and BEFORE + * the first call to jpeg_write_scanlines(). + * (This ordering ensures that the APP2 marker(s) will appear after the + * SOI and JFIF or Adobe markers, but before all else.) + */ + +extern void write_icc_profile JPP((j_compress_ptr cinfo, + const JOCTET *icc_data_ptr, + unsigned int icc_data_len)); + + +/* + * Reading a JPEG file that may contain an ICC profile requires two steps: + * + * 1. After jpeg_create_decompress() but before jpeg_read_header(), + * call setup_read_icc_profile(). This routine tells the IJG library + * to save in memory any APP2 markers it may find in the file. + * + * 2. After jpeg_read_header(), call read_icc_profile() to find out + * whether there was a profile and obtain it if so. + */ + + +/* + * Prepare for reading an ICC profile + */ + +extern void setup_read_icc_profile JPP((j_decompress_ptr cinfo)); + + +/* + * See if there was an ICC profile in the JPEG file being read; + * if so, reassemble and return the profile data. + * + * TRUE is returned if an ICC profile was found, FALSE if not. + * If TRUE is returned, *icc_data_ptr is set to point to the + * returned data, and *icc_data_len is set to its length. + * + * IMPORTANT: the data at **icc_data_ptr has been allocated with malloc() + * and must be freed by the caller with free() when the caller no longer + * needs it. (Alternatively, we could write this routine to use the + * IJG library's memory allocator, so that the data would be freed implicitly + * at jpeg_finish_decompress() time. But it seems likely that many apps + * will prefer to have the data stick around after decompression finishes.) + */ + +#ifdef WIN32 +extern jboolean read_icc_profile JPP((j_decompress_ptr cinfo, + JOCTET **icc_data_ptr, + unsigned int *icc_data_len)); +#else +extern boolean read_icc_profile JPP((j_decompress_ptr cinfo, + JOCTET **icc_data_ptr, + unsigned int *icc_data_len)); +#endif + diff --git a/rtengine/iccmatrices.h b/rtengine/iccmatrices.h new file mode 100644 index 000000000..66d25cb6d --- /dev/null +++ b/rtengine/iccmatrices.h @@ -0,0 +1,74 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _ICCMATRICES_ +#define _ICCMATRICES_ + +const double sRGB_d50[3][3] = {{0.435859, 0.222385, 0.0139162}, + {0.385336, 0.717021, 0.0971389}, + {0.143023, 0.0605936, 0.713817}}; + +const double d50_sRGB[3][3] = {{3.13593293538656, -0.978702373022194, 0.0720490013929888}, + {-1.61878246026431, 1.91609508555177, -0.22919049060526}, + {-0.490913888760734, 0.0334453372795315, 1.40593851447263}}; + +/*const double sRGB_d50[3][3] = {{0.4360520246092, 0.2224915978656, 0.0139291219896}, + {0.38508159282, 0.716886060114, 0.09709700166}, + {0.1430874138552, 0.0606214863936, 0.714185469944}}; + +const double d50_sRGB[3][3] = {{3.13405134405167,-0.978762729953942, 0.0719425766617001}, + {-1.61702771153574,1.91614222810656, -0.228971178679309}, + {-0.49065220876631,0.0334496273068589, 1.40521830559074}};*/ + +const double adobe_d50[3][3] = {{0.6097395054954, 0.3111142944042, 0.0194773131652}, + {0.2052518325737, 0.6256618480686, 0.0608872306106}, + {0.1492308013399, 0.0632241329247, 0.744846530711}}; +const double d50_adobe[3][3] = {{1.9624959949628, -0.978762712052774, 0.0286904764959749}, + {-0.610587687828765,1.91614073756734, -0.140667763143042}, + {-0.34136021627766, 0.0334501217627688, 1.34875045144924}}; +const double prophoto_d50[3][3] = {{0.797675, 0.288040, 0.000000}, + {0.135192, 0.711874, 0.000000}, + {0.0313534,0.000086, 0.825210}}; +const double d50_prophoto[3][3] = {{1.34594335079331, -0.544598514291158, 0}, + {-0.255608118122657, 1.50816768465213, 0}, + {-0.0511117387775285, 0.0205345459181255, 1.21181275069376}}; +const double widegamut_d50[3][3] = {{0.716105, 0.258187, 0.000000}, + {0.100930, 0.724938, 0.0517813}, + {0.147186, 0.0168748, 0.773429}}; +const double d50_widegamut[3][3] = {{1.46280597103052, -0.521792197260068, 0.0349341417298585}, + {-0.184062984909417, 1.44723786022891, -0.0968930022172314}, + {-0.27436071519732, 0.0677226440980744,1.28840945122198}}; +const double bruce_d50[3][3] = {{0.4941607255908, 0.2521412970174, 0.0157852934504}, + {0.3204990468435, 0.684494580042, 0.062927176507}, + {0.1495612990809, 0.0633643619597, 0.746498914581}}; +const double d50_bruce[3][3] = {{2.65042308164152, -0.978762745761462, 0.0264609493245811}, + {-1.20155941925411, 1.9161402914007, -0.136115844662896}, + {-0.42902228923717, 0.0334495071197919, 1.34583900936772}}; +const double beta_d50[3][3] = {{0.671254, 0.303273, 0.000000}, + {0.174583, 0.663786, 0.040701}, + {0.118383, 0.0329413, 0.784509}}; +const double d50_beta[3][3] = {{1.68322591962771, -0.771023599950842, 0.0400013658754702}, + {-0.428235060337656, 1.70655704781303, -0.0885376438040078}, + {-0.236018598193503, 0.0446902191738489,1.27236406897742}}; +const double best_d50[3][3] = {{0.632670, 0.228457, 0.000000}, + {0.204556, 0.737352, 0.00951424}, + {0.126995, 0.0341908, 0.815696}}; +const double d50_best[3][3] = {{1.75525923340349, -0.544133953997468, 0.00634675299435191}, + {-0.483679025800866, 1.50687975713407, -0.017576175021718}, + {-0.253000840399762, 0.0215532098817316,1.22569552576991}}; +#endif diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc new file mode 100644 index 000000000..dccf950a5 --- /dev/null +++ b/rtengine/iccstore.cc @@ -0,0 +1,314 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#ifdef WIN32 +#include +#else +#include +#endif +#include +#include + +namespace rtengine { + +ICCStore iccStore; + +const double (*wprofiles[])[3] = {sRGB_d50, adobe_d50, prophoto_d50, widegamut_d50, bruce_d50, beta_d50, best_d50}; +const double (*iwprofiles[])[3] = {d50_sRGB, d50_adobe, d50_prophoto, d50_widegamut, d50_bruce, d50_beta, d50_best}; +const char* wpnames[] = {"sRGB", "Adobe RGB", "ProPhoto", "WideGamut", "BruceRGB", "Beta RGB", "BestRGB"}; + +std::vector getWorkingProfiles () { + + std::vector res; + for (int i=0; i getOutputProfiles () { + + return iccStore.getOutputProfiles (); +} + +std::vector ICCStore::getOutputProfiles () { + + std::vector res; + for (std::map::iterator i=fileProfiles.begin(); i!=fileProfiles.end(); i++) + res.push_back (i->first); + return res; +} + + +ICCStore::ICCStore () { + + cmsErrorAction (LCMS_ERROR_SHOW); + + int N = sizeof(wpnames)/sizeof(wpnames[0]); + for (int i=0; i::iterator r = wMatrices.find (name); + if (r!=wMatrices.end()) + return r->second; + else + return wMatrices["sRGB"]; +} + +TMatrix ICCStore::workingSpaceInverseMatrix (Glib::ustring name) { + + std::map::iterator r = iwMatrices.find (name); + if (r!=iwMatrices.end()) + return r->second; + else + return iwMatrices["sRGB"]; +} + +cmsHPROFILE ICCStore::workingSpace (Glib::ustring name) { + + std::map::iterator r = wProfiles.find (name); + if (r!=wProfiles.end()) + return r->second; + else + return wProfiles["sRGB"]; +} + +cmsHPROFILE ICCStore::workingSpaceGamma (Glib::ustring name) { + + std::map::iterator r = wProfilesGamma.find (name); + if (r!=wProfilesGamma.end()) + return r->second; + else + return wProfilesGamma["sRGB"]; +} + +cmsHPROFILE ICCStore::getProfile (Glib::ustring name) { + + + std::map::iterator r = fileProfiles.find (name); + if (r!=fileProfiles.end()) + return r->second; + else { + if (!name.compare (0, 5, "file:") && Glib::file_test (name.substr(5), Glib::FILE_TEST_EXISTS) && !Glib::file_test (name.substr(5), Glib::FILE_TEST_IS_DIR)) { + ProfileContent pc (name.substr(5)); + if (pc.data) { + cmsHPROFILE profile = pc.toProfile (); + if (profile) { + fileProfiles[name] = profile; + fileProfileContents[name] = pc; + return profile; + } + } + } + } + return NULL; +} + +ProfileContent ICCStore::getContent (Glib::ustring name) { + + return fileProfileContents[name]; +} + +std::vector ICCStore::parseDir (Glib::ustring pdir) { + + fileProfiles.clear (); + fileProfileContents.clear (); + std::vector result; + if (pdir!="") { + // process directory + Glib::ustring dirname = pdir; + Glib::Dir* dir = NULL; + try { + if (!Glib::file_test (dirname, Glib::FILE_TEST_IS_DIR)) + return result; + dir = new Glib::Dir (dirname); + } + catch (Glib::Exception& fe) { + return result; + } + dirname = dirname + "/"; + for (Glib::DirIterator i = dir->begin(); i!=dir->end(); ++i) { + Glib::ustring fname = dirname + *i; + Glib::ustring sname = *i; + // ignore directories + if (!Glib::file_test (fname, Glib::FILE_TEST_IS_DIR)) { + int lastdot = sname.find_last_of ('.'); + if (lastdot!=Glib::ustring::npos && lastdot<=sname.size()-4 && (!sname.casefold().compare (lastdot, 4, ".icm") || !sname.casefold().compare (lastdot, 4, ".icc"))) { +// printf ("processing file %s...\n", fname.c_str()); + Glib::ustring name = sname.substr(0,lastdot); + ProfileContent pc (fname); + if (pc.data) { + cmsHPROFILE profile = pc.toProfile (); + if (profile) { + fileProfiles[name] = profile; + fileProfileContents[name] = pc; + result.push_back (name); + } + } + } + } + } + delete dir; + } + return result; +} + +ProfileContent::ProfileContent (Glib::ustring fileName) { + + data = NULL; + FILE* f = g_fopen (fileName.c_str(), "rb"); + if (!f) + return; + fseek (f, 0, SEEK_END); + length = ftell (f); + fseek (f, 0, SEEK_SET); + data = new char[length+1]; + fread (data, length, 1, f); + data[length] = 0; + fclose (f); +} + +ProfileContent::ProfileContent (const ProfileContent& other) { + + length = other.length; + if (other.data) { + data = new char[length+1]; + memcpy (data, other.data, length+1); + } + else + data = NULL; +} + +ProfileContent& ProfileContent::operator= (const ProfileContent other) { + + length = other.length; + if (data) + delete [] data; + if (other.data) { + data = new char[length+1]; + memcpy (data, other.data, length+1); + } + else + data = NULL; + return *this; +} + +ProfileContent::~ProfileContent () { + + if (data) + delete [] data; +} + +cmsHPROFILE ProfileContent::toProfile () { + + if (data) + return cmsOpenProfileFromMem (data, length); + else + return NULL; +} + +cmsHPROFILE ICCStore::createFromMatrix (const double matrix[3][3], bool gamma, Glib::ustring name) { + + static const unsigned phead[] = + { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0, + 0x61637370, 0, 0, 0, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d }; + unsigned pbody[] = + { 10, 0x63707274, 0, 36, /* cprt */ + 0x64657363, 0, 40, /* desc */ + 0x77747074, 0, 20, /* wtpt */ + 0x626b7074, 0, 20, /* bkpt */ + 0x72545243, 0, 14, /* rTRC */ + 0x67545243, 0, 14, /* gTRC */ + 0x62545243, 0, 14, /* bTRC */ + 0x7258595a, 0, 20, /* rXYZ */ + 0x6758595a, 0, 20, /* gXYZ */ + 0x6258595a, 0, 20 }; /* bXYZ */ + static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc }; + // 0x63757276 : curveType, 0 : reserved, 1 : entries (1=gamma, 0=identity), 0x1000000=1.0 + unsigned pcurve[] = { 0x63757276, 0, 0, 0x1000000 }; +// unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 }; + + if (gamma) { + pcurve[2] = 1; + pcurve[3] = 0x1f00000; + } + + // constructing profile header + unsigned* oprof = new unsigned [phead[0]/sizeof(unsigned)]; + memset (oprof, 0, phead[0]); + memcpy (oprof, phead, sizeof(phead)); + + oprof[0] = 132 + 12*pbody[0]; + + // constructing tag directory (pointers inside the file), and types + // 0x74657874 : text + // 0x64657363 : description tag + for (int i=0; i < pbody[0]; i++) { + oprof[oprof[0]/4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874; + pbody[i*3+2] = oprof[0]; + oprof[0] += (pbody[i*3+3] + 3) & -4; + } + memcpy (oprof+32, pbody, sizeof(pbody)); + + // wtpt + memcpy ((char *)oprof+pbody[8]+8, pwhite, sizeof(pwhite)); + + // r/g/b TRC + for (int i=4; i < 7; i++) + memcpy ((char *)oprof+pbody[i*3+2], pcurve, sizeof(pcurve)); + + // r/g/b XYZ +// pseudoinverse ((double (*)[3]) out_rgb[output_color-1], inverse, 3); + for (int i=0; i < 3; i++) + for (int j=0; j < 3; j++) { + oprof[pbody[j*3+23]/4+i+2] = matrix[j][i] * 0x10000 + 0.5; +// for (num = k=0; k < 3; k++) +// num += xyzd50_srgb[i][k] * inverse[j][k]; + } + + // convert to network byte order + for (int i=0; i < phead[0]/4; i++) + oprof[i] = htonl(oprof[i]); + + // cprt + strcpy ((char *)oprof+pbody[2]+8, "--rawtherapee profile--"); + + // desc + oprof[pbody[5]/4+2] = name.size() + 1; + strcpy ((char *)oprof+pbody[5]+12, name.c_str()); + + + return cmsOpenProfileFromMem (oprof, ntohl(oprof[0])); +} +} diff --git a/rtengine/iccstore.h b/rtengine/iccstore.h new file mode 100644 index 000000000..a7434bec6 --- /dev/null +++ b/rtengine/iccstore.h @@ -0,0 +1,82 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef __ICCSTORE__ +#define __ICCSTORE__ + +#include +#include +#include +#include + +namespace rtengine { + +typedef const double (*TMatrix)[3]; + +class ProfileContent { + + public: + char* data; + int length; + + ProfileContent (): data(NULL), length(0) {} + ProfileContent (Glib::ustring fileName); + ProfileContent (const ProfileContent& other); + ~ProfileContent (); + ProfileContent& operator= (const ProfileContent other); + cmsHPROFILE toProfile (); +}; + +class ICCStore { + + std::map wProfiles; + std::map wProfilesGamma; + std::map wMatrices; + std::map iwMatrices; + + std::map fileProfiles; + std::map fileProfileContents; + + cmsHPROFILE xyz; + cmsHPROFILE srgb; + + public: + ICCStore (); + + int numOfWProfiles (); + cmsHPROFILE createFromMatrix (const double matrix[3][3], bool gamma=false, Glib::ustring name=""); + cmsHPROFILE workingSpace (Glib::ustring name); + cmsHPROFILE workingSpaceGamma (Glib::ustring name); + TMatrix workingSpaceMatrix (Glib::ustring name); + TMatrix workingSpaceInverseMatrix (Glib::ustring name); + + cmsHPROFILE getProfile (Glib::ustring name); + std::vector parseDir (Glib::ustring pdir); + ProfileContent getContent (Glib::ustring name); + + cmsHPROFILE getXYZProfile () { return xyz; } + cmsHPROFILE getsRGBProfile () { return srgb; } + std::vector getOutputProfiles (); +}; + +extern ICCStore iccStore; + +//extern const char* wpnames[]; +} +#endif + diff --git a/rtengine/iimage.h b/rtengine/iimage.h new file mode 100644 index 000000000..03ef519e9 --- /dev/null +++ b/rtengine/iimage.h @@ -0,0 +1,96 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _IIMAGE_ +#define _IIMAGE_ + +#include +#include + +namespace rtengine { + + class ProgressListener; + + /** This class represents an image (the result of the image processing) */ + class IImage { + public: + /** Returns a mutex that can is useful in many situations. No image operations shuold be performed without locking this mutex. + * @return The mutex */ + virtual Glib::Mutex& getMutex ()=0; + virtual cmsHPROFILE getProfile ()=0; + /** Returns the width of the image. + * @return The width of the image */ + virtual int getWidth ()=0; + /** Returns the height of the image. + * @return The height of the image */ + virtual int getHeight ()=0; + /** Returns the bits per pixel of the image. + * @return The bits per pixel of the image */ + virtual int getBitsPerPixel ()=0; + /** Saves the image to file. It autodetects the format (jpg, tif, png are supported). + * @param fname is the name of the file + @return the error code, 0 if none */ + virtual int saveToFile (Glib::ustring fname)=0; + /** Saves the image to file in a png format. + * @param fname is the name of the file + * @param compression is the amount of compression (0-6), -1 corresponds to the default + * @param bps can be 8 or 16 depending on the bits per pixels the output file will have + @return the error code, 0 if none */ + virtual int saveAsPNG (Glib::ustring fname, int compression = -1, int bps = -1)=0; + /** Saves the image to file in a jpg format. + * @param fname is the name of the file + * @param quality is the quality of the jpeg (0...100), set it to -1 to use default + @return the error code, 0 if none */ + virtual int saveAsJPEG (Glib::ustring fname, int quality = 100)=0; + /** Saves the image to file in a tif format. + * @param fname is the name of the file + * @param bps can be 8 or 16 depending on the bits per pixels the output file will have + @return the error code, 0 if none */ + virtual int saveAsTIFF (Glib::ustring fname, int bps = -1)=0; + /** Sets the progress listener if you want to follow the progress of the image saving operations (optional). + * @param pl is the pointer to the class implementing the ProgressListener interface */ + virtual void setSaveProgressListener (ProgressListener* pl)=0; + /** Free the image */ + virtual void free ()=0; + }; + + /** This class represents an image having a classical 8 bits/pixel representation */ + class IImage8 : public IImage { + public: + /** Returns the pixel data, in r/g/b order from top left to bottom right continously. + * @return a pointer to the pixel data */ + virtual const unsigned char* getData ()=0; + }; + + /** This class represents an image having a 16 bits/pixel planar representation. + The planes are stored as two dimensional arrays. All the rows have a 8-byte alignment. */ + class IImage16 : public IImage { + public: + /** Returns the "red" plane data. + * @return the two dimensional array of the red plane */ + virtual unsigned short** getRPlane ()=0; + /** Returns the "green" plane data. + * @return the two dimensional array of the green plane */ + virtual unsigned short** getGPlane ()=0; + /** Returns the "blue" plane data. + * @return the two dimensional array of the blue plane */ + virtual unsigned short** getBPlane ()=0; + }; +} + +#endif diff --git a/rtengine/image16.cc b/rtengine/image16.cc new file mode 100644 index 000000000..6da578a38 --- /dev/null +++ b/rtengine/image16.cc @@ -0,0 +1,241 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +using namespace rtengine; + +Image16::Image16 () + : r (NULL), g (NULL), b (NULL), data (NULL), unaligned (NULL) { +} + +Image16::Image16 (int w, int h) + : width(w), height (h), r (NULL), g (NULL), b (NULL), data (NULL), unaligned (NULL) { + + allocate (w, h); +} + +Image16::~Image16 () { + + if (data!=NULL) { + delete [] unaligned; + delete [] r; + delete [] g; + delete [] b; + } +} + +void Image16::allocate (int width, int height) { + + if (data!=NULL) { + delete [] unaligned; + delete [] r; + delete [] g; + delete [] b; + } + + int lsize = width + 8 - width % 8; + unaligned = new unsigned char[16 + 3 * lsize * sizeof(short) * height]; + memset(unaligned, 0, (16 + 3 * lsize * sizeof(short) * height) * sizeof(unsigned char)); + + unsigned long poin = (unsigned long)unaligned + 16 - (unsigned long)unaligned % 16; + data = (unsigned short*) (poin); + + rowstride = lsize * sizeof(unsigned short); + planestride = rowstride * height; + + unsigned long redstart = poin + 0*planestride; + unsigned long greenstart = poin + 1*planestride; + unsigned long bluestart = poin + 2*planestride; + + r = new unsigned short*[height]; + g = new unsigned short*[height]; + b = new unsigned short*[height]; + for (int i=0; iwidth = width; + this->height = height; +} + +void Image16::getScanline (int row, unsigned char* buffer, int bps) { + + if (data==NULL) + return; + + if (bps==16) { + int ix = 0; + unsigned short* sbuffer = (unsigned short*) buffer; + for (int i=0; i> 8; + buffer[ix++] = g[row][i] >> 8; + buffer[ix++] = b[row][i] >> 8; + } + } +} + +void Image16::setScanline (int row, unsigned char* buffer, int bps) { + + if (data==NULL) + return; + + if (bps==8) { + int ix = 0; + for (int i=0; ir[i], r[i], width*sizeof(unsigned short)); + memcpy (cp->g[i], g[i], width*sizeof(unsigned short)); + memcpy (cp->b[i], b[i], width*sizeof(unsigned short)); + } + + return cp; +} + +Image16* Image16::rotate (int deg) { + + if (deg==90) { + Image16* result = new Image16 (height, width); + for (int i=0; ir[i][j] = r[height-1-j][i]; + result->g[i][j] = g[height-1-j][i]; + result->b[i][j] = b[height-1-j][i]; + } + return result; + } + else if (deg==270) { + Image16* result = new Image16 (height, width); + for (int i=0; ir[i][j] = r[j][width-1-i]; + result->g[i][j] = g[j][width-1-i]; + result->b[i][j] = b[j][width-1-i]; + } + return result; + } + else if (deg==180) { + Image16* result = new Image16 (width, height); + for (int i=0; ir[i][j] = r[height-1-i][width-1-j]; + result->g[i][j] = g[height-1-i][width-1-j]; + result->b[i][j] = b[height-1-i][width-1-j]; + } + return result; + } + else + return NULL; +} + +Image16* Image16::hflip () { + + Image16* result = new Image16 (width, height); + for (int i=0; ir[i][j] = r[i][width-1-j]; + result->g[i][j] = g[i][width-1-j]; + result->b[i][j] = b[i][width-1-j]; + } + return result; + +} + +Image16* Image16::vflip () { + + Image16* result = new Image16 (width, height); + for (int i=0; ir[i][j] = r[height-1-i][j]; + result->g[i][j] = g[height-1-i][j]; + result->b[i][j] = b[height-1-i][j]; + } + return result; + +} + +Image16* Image16::resize (int nw, int nh, TypeInterpolation interp) { + + if (interp == TI_Nearest) { + Image16* res = new Image16 (nw, nh); + for (int i=0; ir[i][j] = r[ri][ci]; + res->g[i][j] = g[ri][ci]; + res->b[i][j] = b[ri][ci]; + } + } + return res; + } + else if (interp == TI_Bilinear) { + Image16* res = new Image16 (nw, nh); + for (int i=0; i=height) sy = height-1; + double dy = (double)i*height/nh - sy; + int ny = sy+1; + if (ny>=height) ny = sy; + for (int j=0; j=width) sx = width; + double dx = (double)j*width/nw - sx; + int nx = sx+1; + if (nx>=width) nx = sx; + res->r[i][j] = r[sy][sx]*(1-dx)*(1-dy) + r[sy][nx]*dx*(1-dy) + r[ny][sx]*(1-dx)*dy + r[ny][nx]*dx*dy; + res->g[i][j] = g[sy][sx]*(1-dx)*(1-dy) + g[sy][nx]*dx*(1-dy) + g[ny][sx]*(1-dx)*dy + g[ny][nx]*dx*dy; + res->b[i][j] = b[sy][sx]*(1-dx)*(1-dy) + b[sy][nx]*dx*(1-dy) + b[ny][sx]*(1-dx)*dy + b[ny][nx]*dx*dy; + } + } + return res; + } + return NULL; +} diff --git a/rtengine/image16.h b/rtengine/image16.h new file mode 100644 index 000000000..256c8b8eb --- /dev/null +++ b/rtengine/image16.h @@ -0,0 +1,86 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +// +// A class representing a 16 bit rgb image with separate planes and 16 byte aligned data +// +#ifndef _IMAGE16_ +#define _IMAGE16_ + +#include +#include + +namespace rtengine { + +enum TypeInterpolation { TI_Nearest, TI_Bilinear }; + +class Image16 : public ImageIO, public IImage16 { + + private: + unsigned char* unaligned; + + public: + int rowstride; + int planestride; + + int width; + int height; + + unsigned short* data; + + unsigned short** r; + unsigned short** g; + unsigned short** b; + + + Image16 (); + Image16 (int width, int height); + ~Image16 (); + + Image16* copy (); + + Image16* rotate (int deg); + Image16* hflip (); + Image16* vflip (); + Image16* resize (int nw, int nh, TypeInterpolation interp); + + virtual int getW () { return width; } + virtual int getH () { return height; } + virtual void allocate (int width, int height); + virtual int getBPS () { return 16; } + virtual void getScanline (int row, unsigned char* buffer, int bps); + virtual void setScanline (int row, unsigned char* buffer, int bps); + + // functions inherited from IImage16: + virtual Glib::Mutex& getMutex () { return mutex (); } + virtual cmsHPROFILE getProfile () { return getEmbeddedProfile (); } + virtual int getWidth () { return width; } + virtual int getHeight () { return height; } + virtual int getBitsPerPixel () { return 16; } + virtual int saveToFile (Glib::ustring fname) { return save (fname); } + virtual int saveAsPNG (Glib::ustring fname, int compression = -1, int bps = -1) { return savePNG (fname, compression, bps); } + virtual int saveAsJPEG (Glib::ustring fname, int quality = 100) { return saveJPEG (fname, quality); } + virtual int saveAsTIFF (Glib::ustring fname, int bps = -1) { return saveTIFF (fname, bps); } + virtual void setSaveProgressListener (ProgressListener* pl) { return setProgressListener (pl); } + virtual void free () { delete this; } + virtual unsigned short** getRPlane () { return r; } + virtual unsigned short** getGPlane () { return g; } + virtual unsigned short** getBPlane () { return b; } +}; +}; +#endif diff --git a/rtengine/image8.cc b/rtengine/image8.cc new file mode 100644 index 000000000..697b31c9f --- /dev/null +++ b/rtengine/image8.cc @@ -0,0 +1,108 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +using namespace rtengine; + + +Image8::Image8 () + : width(-1), height(-1), data(NULL) { +} + +Image8::Image8 (int w, int h) + : width(w), height (h), data(NULL) { + + allocate (w, h); +} + +void Image8::allocate (int width, int height) { + + if (data!=NULL) + delete [] data; + + data = new unsigned char [width * height * 3]; + this->width = width; + this->height = height; +} + +Image8::~Image8 () { + + if (data!=NULL) + delete [] data; +} + +void Image8::getScanline (int row, unsigned char* buffer, int bps) { + + if (data==NULL) + return; + + if (bps==8) + memcpy (buffer, data + row*width*3, width*3); + else if (bps==16) { + unsigned short* sbuffer = (unsigned short*) buffer; + for (int i=0, ix = row*width*3; i> 8; + } +} + +unsigned char Image8::r (int row, int col) { + + return data[3*(row*width+col)]; +} + +unsigned char Image8::g (int row, int col) { + + return data[3*(row*width+col)+1]; +} + +unsigned char Image8::b (int row, int col) { + + return data[3*(row*width+col)+2]; +} + +void Image8::r (int row, int col, unsigned char val) { + + data[3*(row*width+col)] = val; +} + +void Image8::g (int row, int col, unsigned char val) { + + data[3*(row*width+col)+1] = val; +} + +void Image8::b (int row, int col, unsigned char val) { + + data[3*(row*width+col)+2] = val; +} + diff --git a/rtengine/image8.h b/rtengine/image8.h new file mode 100644 index 000000000..289b82009 --- /dev/null +++ b/rtengine/image8.h @@ -0,0 +1,71 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +// +// A class representing a 8 bit rgb image without alpha channel +// +#ifndef _IMAGE8_ +#define _IMAGE8_ + +#include +#include + +namespace rtengine { + +class Image8 : public ImageIO, public IImage8 { + + public: + unsigned char* data; + int width; + int height; + + Image8 (); + Image8 (int width, int height); + ~Image8 (); + + unsigned char r (int row, int col); + unsigned char g (int row, int col); + unsigned char b (int row, int col); + void r (int row, int col, unsigned char val); + void g (int row, int col, unsigned char val); + void b (int row, int col, unsigned char val); + + virtual int getW () { return width; } + virtual int getH () { return height; } + virtual void allocate (int width, int height); + virtual int getBPS () { return 8; } + virtual void getScanline (int row, unsigned char* buffer, int bps); + virtual void setScanline (int row, unsigned char* buffer, int bps); + + // functions inherited from IImage*: + virtual Glib::Mutex& getMutex () { return mutex (); } + virtual cmsHPROFILE getProfile () { return getEmbeddedProfile (); } + virtual int getWidth () { return width; } + virtual int getHeight () { return height; } + virtual int getBitsPerPixel () { return 16; } + virtual int saveToFile (Glib::ustring fname) { return save (fname); } + virtual int saveAsPNG (Glib::ustring fname, int compression = -1, int bps = -1) { return savePNG (fname, compression, bps); } + virtual int saveAsJPEG (Glib::ustring fname, int quality = 100) { return saveJPEG (fname, quality); } + virtual int saveAsTIFF (Glib::ustring fname, int bps = -1) { return saveTIFF (fname, bps); } + virtual void setSaveProgressListener (ProgressListener* pl) { setProgressListener (pl); } + virtual void free () { delete this; } + virtual const unsigned char* getData () { return data; } + +}; +}; +#endif diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc new file mode 100644 index 000000000..88f1354e7 --- /dev/null +++ b/rtengine/imagedata.cc @@ -0,0 +1,431 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#ifdef RAWZOR_SUPPORT +#include +#endif + +#ifndef GLIBMM_EXCEPTIONS_ENABLED +#include +#endif + +using namespace rtengine; + +extern "C" IptcData *iptc_data_new_from_jpeg_file (FILE* infile); + +ImageMetaData* ImageMetaData::fromFile (const Glib::ustring& fname, RawMetaDataLocation* rml) { + + return new ImageData (fname, rml); +} + +ImageData::ImageData (Glib::ustring fname, RawMetaDataLocation* ri) { + + int dotpos = fname.find_last_of ('.'); + root = NULL; + iptc = NULL; +#ifdef RAWZOR_SUPPORT + // RAWZOR support begin + if (dotposexifBase>=0 || ri->ciffBase>=0)) { + FILE* f = g_fopen (fname.c_str (), "rb"); + if (f) { + fseek (f, 0, SEEK_END); + int rzwSize = ftell (f); + char* rzwData = new char [rzwSize]; + fseek (f, 0, SEEK_SET); + fread (rzwData, 1, rzwSize, f); + fclose(f); + int rawSize; + if (!m_rwz_check (rzwData, rzwSize, &rawSize)) { + char* rawData = new char [rawSize]; + if (!m_rwz_get_meta_only (rzwData, rzwSize, rawData, rawSize)) { + std::string tfname; + int fd = Glib::file_open_tmp (tfname, ""); + FILE* tf = fdopen (fd, "w+b"); + fwrite (rawData, 1, rawSize, tf); + if (ri->exifBase>=0) + root = rtexif::ExifManager::parse (tf, ri->exifBase); + else if (ri->ciffBase>=0) + root = rtexif::ExifManager::parseCIFF (tf, ri->ciffBase, ri->ciffLength); + fclose (tf); + ::g_remove (tfname.c_str()); + extractInfo (); + } + delete [] rawData; + + } + delete [] rzwData; + } + } + // RAWZOR support end + else +#endif + if (ri && (ri->exifBase>=0 || ri->ciffBase>=0)) { + FILE* f = g_fopen (fname.c_str(), "rb"); + if (f) { + if (ri->exifBase>=0) { + root = rtexif::ExifManager::parse (f, ri->exifBase); + if (root) { + rtexif::Tag* t = root->getTag (0x83BB); + if (t) + iptc = iptc_data_new_from_data ((unsigned char*)t->getValue (), (unsigned)t->getValueSize ()); + } + } + else if (ri->ciffBase>=0) + root = rtexif::ExifManager::parseCIFF (f, ri->ciffBase, ri->ciffLength); + fclose (f); + extractInfo (); + } + } + else if (dotposgetTag (0x83BB); + if (t) + iptc = iptc_data_new_from_data ((unsigned char*)t->getValue (), (unsigned)t->getValueSize ()); + } + } + } + else { + root = new rtexif::TagDirectory (); + shutter = 0; + aperture = 0; + iso_speed = 0; + lens = "Unknown"; + make = "Unknown"; + model = "Unknown"; + focal_len = 0; + memset (&time, 0, sizeof(time)); + } +} + +void ImageData::extractInfo () { + + if (!root) + return; + + char buffer[256]; + + make = ""; + model = ""; + shutter = 0; + aperture = 0; + focal_len = 0; + iso_speed = 0; + memset (&time, 0, sizeof(time)); + + if (root->getTag ("Make")) + make = root->getTag ("Make")->valueToString (); + if (root->getTag ("Model")) + model = root->getTag ("Model")->valueToString (); + + rtexif::TagDirectory* exif = NULL; + if (root->getTag ("Exif")) + exif = root->getTag ("Exif")->getDirectory (); + + if (exif) { + + // standard exif tags + if (exif->getTag ("ShutterSpeedValue")) + shutter = exif->getTag ("ShutterSpeedValue")->toDouble (); + if (exif->getTag ("ExposureTime")) + shutter = exif->getTag ("ExposureTime")->toDouble (); + if (exif->getTag ("ApertureValue")) + aperture = exif->getTag ("ApertureValue")->toDouble (); + if (exif->getTag ("FNumber")) + aperture = exif->getTag ("FNumber")->toDouble (); + if (exif->getTag ("FocalLength")) + focal_len = exif->getTag ("FocalLength")->toDouble (); + if (exif->getTag ("ISOSpeedRatings")) + iso_speed = exif->getTag ("ISOSpeedRatings")->toDouble (); + if (exif->getTag ("DateTimeOriginal")) { + if (sscanf ((const char*)exif->getTag("DateTimeOriginal")->getValue(), "%d:%d:%d %d:%d:%d", &time.tm_year, &time.tm_mon, &time.tm_mday, &time.tm_hour, &time.tm_min, &time.tm_sec) == 6) { + time.tm_year -= 1900; + time.tm_mon -= 1; + } + } + // guess lens... + lens = "Unknown"; + + if (exif->getTag ("MakerNote")) { + rtexif::TagDirectory* mnote = exif->getTag ("MakerNote")->getDirectory(); + if (mnote && !make.compare (0, 5, "NIKON")) { + bool lensOk = false; + if (mnote->getTag ("LensData")) { + std::string ldata = mnote->getTag ("LensData")->valueToString (); + int pos; + if (ldata.size()>10 && (pos=ldata.find ("Lens = "))!=Glib::ustring::npos) { + lens = ldata.substr (pos + 7); + if (lens.compare (0, 7, "Unknown")) + lensOk = true; + } + } + if (!lensOk && mnote->getTag ("Lens")) { + std::string ldata = mnote->getTag ("Lens")->valueToString (); + int i=0, j=0; + double n[4]; + for (int m=0; m<4; m++) { + while (igetTag ("LensType")) { + std::string ldata = mnote->getTag ("LensType")->valueToString (); + if (ldata.size()>1) { + lens = ldata; + lensOk = true; + } + } + if (!lensOk && mnote->getTag ("CanonCameraSettings")) { + std::string ccs = mnote->getTag ("CanonCameraSettings")->valueToString (); + int i = ccs.find ("LongFocal = "); + double a = 0; + if (i!=ccs.npos) { + i += 12; + int j = i; + while (j!=ccs.npos && ccs[j]!='\n' && ccs[j]!=' ') j++; + a = atof (ccs.substr (i, j-i).c_str()); + } + i = ccs.find ("ShortFocal = "); + double b = 0; + if (i!=ccs.npos) { + i += 13; + int j = i; + while (j!=ccs.npos && ccs[j]!='\n' && ccs[j]!=' ') j++; + b = atof (ccs.substr (i, j-i).c_str()); + } + if (a>0 && b>0) { + std::ostringstream str; + if (a==b) + str << "Unknown " << a << "mm"; + else + str << "Unknown " << b << "-" << a << "mm"; + lens = str.str(); + } + } + } + else if (mnote && !make.compare (0, 6, "PENTAX")) { + if (mnote->getTag ("LensType")) + lens = mnote->getTag ("LensType")->valueToString (); + } + else if (mnote && (!make.compare (0, 4, "SONY") || !make.compare (0, 6, "KONICA"))) { + if (mnote->getTag ("LensID")) + lens = mnote->getTag ("LensID")->valueToString (); + } + else if (mnote && !make.compare (0, 7, "OLYMPUS")) { + if (mnote->getTag ("Equipment")) { + rtexif::TagDirectory* eq = mnote->getTag ("Equipment")->getDirectory (); + if (eq->getTag ("LensType")) + lens = eq->getTag ("LensType")->valueToString (); + } + } + } + } +} + +ImageData::~ImageData () { + + delete root; + if (iptc) + iptc_data_free (iptc); +} + +Glib::ustring safe_locale_to_utf8 (const std::string& src) +{ + Glib::ustring utf8_str; +#ifdef GLIBMM_EXCEPTIONS_ENABLED + try { + utf8_str = Glib::locale_to_utf8(src); + } + catch (const Glib::ConvertError& e) { + utf8_str = Glib::convert_with_fallback(src, "UTF8", "LATIN1","?"); + } +#else + { + std::auto_ptr error; + utf8_str = locale_to_utf8(src, error); + if (error.get()) + utf8_str = Glib::convert_with_fallback(src, "UTF8", "LATIN1","?", error); + } +#endif //GLIBMM_EXCEPTIONS_ENABLED + return utf8_str; +} + +const std::vector ImageData::getIPTCData () const { + + std::vector iptcc; + if (!iptc) + return iptcc; + + unsigned char buffer[2100]; + for (int i=0; i<16; i++) { + IptcDataSet* ds = iptc_data_get_next_dataset (iptc, NULL, IPTC_RECORD_APP_2, strTags[i].tag); + if (ds) { + iptc_dataset_get_data (ds, buffer, 2100); + procparams::IPTCPair ic; + ic.field = strTags[i].field; + ic.values.push_back (safe_locale_to_utf8((char*)buffer)); + + iptcc.push_back (ic); + iptc_dataset_unref (ds); + } + } + IptcDataSet* ds = NULL; + procparams::IPTCPair ickw; + ickw.field = "Keywords"; + while (ds=iptc_data_get_next_dataset (iptc, ds, IPTC_RECORD_APP_2, IPTC_TAG_KEYWORDS)) { + iptc_dataset_get_data (ds, buffer, 2100); + ickw.values.push_back (safe_locale_to_utf8((char*)buffer)); + } + iptcc.push_back (ickw); + ds = NULL; + procparams::IPTCPair icsc; + icsc.field = "SupplementalCategories"; + while (ds=iptc_data_get_next_dataset (iptc, ds, IPTC_RECORD_APP_2, IPTC_TAG_SUPPL_CATEGORY)) { + iptc_dataset_get_data (ds, buffer, 2100); + icsc.values.push_back (safe_locale_to_utf8((char*)buffer)); + iptc_dataset_unref (ds); + } + iptcc.push_back (icsc); +} + +//------inherited functions--------------// + + +std::string ImageMetaData::apertureToString (double aperture) { + + char buffer[256]; + sprintf (buffer, "%0.1f", aperture); + return buffer; +} + +std::string ImageMetaData::shutterToString (double shutter) { + + char buffer[256]; + if (shutter > 0.0 && shutter < 0.9) + sprintf (buffer, "1/%0.0f", 1.0 / shutter); + else + sprintf (buffer, "%0.1f", shutter); + return buffer; +} + +double ImageMetaData::shutterFromString (std::string s) { + + int i = s.find_first_of ('/'); + if (i==std::string::npos) + return atof (s.c_str()); + else + return atof (s.substr(0,i).c_str()) / atof (s.substr(i+1).c_str()); +} + +double ImageMetaData::apertureFromString (std::string s) { + + return atof (s.c_str()); +} + +extern "C" { + +#include +#include + +struct _IptcDataPrivate +{ + unsigned int ref_count; + + IptcLog *log; + IptcMem *mem; +}; + +IptcData * +iptc_data_new_from_jpeg_file (FILE *infile) +{ + IptcData *d; + unsigned char * buf; + int buf_len = 256*256; + int len, offset; + unsigned int iptc_len; + + if (!infile) + return NULL; + + d = iptc_data_new (); + if (!d) + return NULL; + + buf = (unsigned char*)iptc_mem_alloc (d->priv->mem, buf_len); + if (!buf) { + iptc_data_unref (d); + return NULL; + } + + len = iptc_jpeg_read_ps3 (infile, buf, buf_len); + + if (len <= 0) { + goto failure; + } + + offset = iptc_jpeg_ps3_find_iptc (buf, len, &iptc_len); + if (offset <= 0) { + goto failure; + } + + iptc_data_load (d, buf + offset, iptc_len); + + iptc_mem_free (d->priv->mem, buf); + return d; + +failure: + iptc_mem_free (d->priv->mem, buf); + iptc_data_unref (d); + return NULL; +} + +} diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h new file mode 100644 index 000000000..553b43ebd --- /dev/null +++ b/rtengine/imagedata.h @@ -0,0 +1,70 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef __IMAGEDATA_H__ +#define __IMAGEDATA_H__ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rtengine { + +class ImageData : public ImageMetaData { + + protected: + rtexif::TagDirectory* root; + IptcData* iptc; + + struct tm time; + int iso_speed; + double aperture; + double focal_len; + double shutter; + std::string make, model; + std::string lens; + + void extractInfo (); + + public: + + ImageData (Glib::ustring fname, RawMetaDataLocation* rml=NULL); + ~ImageData (); + + const rtexif::TagDirectory* getExifData () const { return root; } + const std::vector getIPTCData () const; + + bool hasExif () const { return root && root->getCount(); } + bool hasIPTC () const { return iptc; } + + struct tm getDateTime () const { return time; } + int getISOSpeed () const { return iso_speed; } + double getFNumber () const { return aperture; } + double getFocalLen () const { return focal_len; } + double getShutterSpeed () const { return shutter; } + std::string getMake () const { return make; } + std::string getModel () const { return model; } + std::string getLens () const { return lens; } +}; +}; +#endif diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc new file mode 100644 index 000000000..ecc93cc09 --- /dev/null +++ b/rtengine/imageio.cc @@ -0,0 +1,749 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include +extern "C" { +#include "jdatasrc.c" +#include +#include +} +#ifdef WIN32 +#include +#else +#include +#endif +#include +#include + +Glib::ustring safe_locale_to_utf8 (const std::string& src); + +using namespace rtengine; +using namespace rtengine::procparams; + +Glib::ustring ImageIO::errorMsg[6] = {"Success", "Cannot read file.", "Invalid header.","Error while reading header.","File reading error", "Image format not supported."}; + +void ImageIO::setMetadata (const rtexif::TagDirectory* eroot, const std::vector& exif, const std::vector& iptcc) { + + // store exif info + exifChange.resize (exif.size()); + for (int i=0; iclone (NULL); + + if (iptc) + iptc_data_free (iptc); + iptc = NULL; + + // build iptc structures for libiptcdata + if (iptcc.size()==0) + return; + + iptc = iptc_data_new (); + for (int i=0; i0) { + for (int j=0; j0) { + for (int j=0; j0) { + IptcDataSet * ds = iptc_dataset_new (); + iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2, strTags[j].tag); + std::string loc = safe_locale_to_utf8(iptcc[i].values[0]); + iptc_dataset_set_data (ds, (unsigned char*)loc.c_str(), MIN(strTags[j].size,loc.size()), IPTC_DONT_VALIDATE); + iptc_data_add_dataset (iptc, ds); + iptc_dataset_unref (ds); + } + } + iptc_data_sort (iptc); +} + +void ImageIO::setOutputProfile (char* pdata, int plen) { + + delete [] profileData; + if (pdata) { + profileData = new char [plen]; + memcpy (profileData, pdata, plen); + } + else + profileData = NULL; + profileLength = plen; +} + +ImageIO::~ImageIO () { + + if (embProfile) + cmsCloseProfile(embProfile); + delete loadedProfileData; + delete exifRoot; + delete profileData; +} + +void png_read_data(png_struct_def *png_ptr, unsigned char *data, size_t length); +void png_write_data(png_struct_def *png_ptr, unsigned char *data, size_t length); +void png_flush(png_struct_def *png_ptr); + +int ImageIO::loadPNG (Glib::ustring fname) { + + FILE *file = g_fopen (fname.c_str(),"rb"); + if (!file) + return IMIO_CANNOTREADFILE; + + if (pl) { + pl->setProgressStr ("Loading PNG file..."); + pl->setProgress (0.0); + } + + //reading PNG header + unsigned char header[8]; + fread (header, 1, 8, file); + if (!png_sig_cmp (header, 0, 8)) { + fclose(file); + return IMIO_HEADERERROR; + } + //initializing main structures + png_structp png = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0); + if (!png) { + fclose (file); + return IMIO_HEADERERROR; + } + png_infop info = png_create_info_struct (png); + png_infop end_info = png_create_info_struct (png); + if (!end_info || !info) { + png_destroy_read_struct (&png, &info, &end_info); + fclose (file); + return IMIO_HEADERERROR; + } + + if (setjmp (png_jmpbuf(png))) { + png_destroy_read_struct (&png, &info, &end_info); + fclose (file); + return IMIO_READERROR; + } + + //set up png read + png_set_read_fn (png, file, png_read_data); + png_set_sig_bytes (png,8); + + png_read_info(png,info); + + embProfile = NULL; + + //retrieving image information + png_uint_32 width,height; + int bit_depth,color_type,interlace_type,compression_type,filter_method; + png_get_IHDR(png,info,&width,&height,&bit_depth,&color_type,&interlace_type, + &compression_type, &filter_method); + + //converting to 32bpp format + if (color_type==PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png); + + if (color_type==PNG_COLOR_TYPE_GRAY || color_type==PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png); + + if (png_get_valid(png,info,PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png); + + if (interlace_type!=PNG_INTERLACE_NONE) { + png_destroy_read_struct (&png, &info, &end_info); + fclose (file); + return IMIO_VARIANTNOTSUPPORTED; + } + + if (color_type & PNG_COLOR_MASK_ALPHA) + png_set_strip_alpha(png); + + //setting gamma + double gamma; + if (png_get_gAMA(png,info,&gamma)) + png_set_gamma(png, 2.0, gamma); + else + png_set_gamma(png,2.0, 0.45455); + + int bps = getBPS (); + + +// if (bps==8 && bit_depth==16) png_set_strip_16(png); + + //updating png info struct + png_read_update_info(png,info); + png_get_IHDR(png,info,&width,&height,&bit_depth,&color_type,&interlace_type, + &compression_type, &filter_method); + + if (color_type & PNG_COLOR_MASK_ALPHA) + png_set_strip_alpha(png); + + png_read_update_info(png,info); + png_get_IHDR(png,info,&width,&height,&bit_depth,&color_type,&interlace_type, + &compression_type, &filter_method); + + allocate (width, height); + + int rowlen = width*3*bit_depth/8; + unsigned char *row = new unsigned char [rowlen]; + + for (unsigned int i=0;isetProgress ((double)(i+1)/height); + } + + png_read_end (png, 0); + png_destroy_read_struct (&png, &info, &end_info); + + delete [] row; + fclose(file); + if (pl) { + pl->setProgressStr ("Ready."); + pl->setProgress (1.0); + } + return IMIO_SUCCESS; +} + +extern jmp_buf jpeg_jmp_buf; + +int ImageIO::loadJPEG (Glib::ustring fname) { + + FILE *file=g_fopen(fname.c_str(),"rb"); + if (!file) + return IMIO_CANNOTREADFILE; + + jpeg_decompress_struct cinfo; + jpeg_error_mgr jerr; + cinfo.err = my_jpeg_std_error(&jerr); + jpeg_create_decompress(&cinfo); + my_jpeg_stdio_src (&cinfo,file); + + if (pl) { + pl->setProgressStr ("Loading JPEG file..."); + pl->setProgress (0.0); + + } + + setup_read_icc_profile (&cinfo); + + if (!setjmp(jpeg_jmp_buf)) { + jpeg_stdio_src(&cinfo,file); + jpeg_read_header(&cinfo, TRUE); + + unsigned int proflen; + delete loadedProfileData; + loadedProfileData = NULL; + bool hasprofile = read_icc_profile (&cinfo, (JOCTET**)&loadedProfileData, (unsigned int*)&loadedProfileLength); + if (hasprofile) + embProfile = cmsOpenProfileFromMem (loadedProfileData, loadedProfileLength); + else + embProfile = NULL; + + jpeg_start_decompress(&cinfo); + + int width = cinfo.output_width; + int height = cinfo.output_height; + + allocate (width, height); + + unsigned char *row=new unsigned char[width*3]; + while (cinfo.output_scanline < height) { + if (jpeg_read_scanlines(&cinfo,&row,1) < 1) { + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + delete [] row; + return IMIO_READERROR; + } + setScanline (cinfo.output_scanline-1, row, 8); + + if (pl && !(cinfo.output_scanline%100)) + pl->setProgress ((double)(cinfo.output_scanline)/cinfo.output_height); + } + delete [] row; + + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + fclose(file); + if (pl) { + pl->setProgressStr ("Ready."); + pl->setProgress (1.0); + } + return IMIO_SUCCESS; + } + else { + jpeg_destroy_decompress(&cinfo); + return IMIO_READERROR; + } +} + +int ImageIO::loadTIFF (Glib::ustring fname) { + +#ifdef WIN32 + wchar_t *wfilename = (wchar_t*)g_utf8_to_utf16 (fname.c_str(), -1, NULL, NULL, NULL); + TIFF* in = TIFFOpenW (wfilename, "r"); + g_free (wfilename); +#else + TIFF* in = TIFFOpen(fname.c_str(), "r"); +#endif + if (in == NULL) + return IMIO_CANNOTREADFILE; + + if (pl) { + pl->setProgressStr ("Loading TIFF file..."); + pl->setProgress (0.0); + } + + int width, height; + TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width); + TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height); + + uint16 bitspersample, samplesperpixel; + TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample); + TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); + uint16 photometric; + if (!TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &photometric) || + photometric != PHOTOMETRIC_RGB || samplesperpixel < 3) { + TIFFClose(in); + return IMIO_VARIANTNOTSUPPORTED; + } + + uint16 config; + TIFFGetField(in, TIFFTAG_PLANARCONFIG, &config); + if (config != PLANARCONFIG_CONTIG) { + TIFFClose(in); + return IMIO_VARIANTNOTSUPPORTED; + } + + char* profdata; + delete loadedProfileData; + loadedProfileData = NULL; + if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &loadedProfileLength, &profdata)) { + embProfile = cmsOpenProfileFromMem (profdata, loadedProfileLength); + loadedProfileData = new char [loadedProfileLength]; + memcpy (loadedProfileData, profdata, loadedProfileLength); + } + else + embProfile = NULL; + + + allocate (width, height); + + unsigned char* linebuffer = new unsigned char[TIFFScanlineSize(in)]; + for (int row = 0; row < height; row++) { + if (TIFFReadScanline(in, linebuffer, row, 0) <0) { + TIFFClose(in); + delete [] linebuffer; + return IMIO_READERROR; + } + if (samplesperpixel>3) + for (int i=0; isetProgress ((double)(row+1)/height); + } + TIFFClose(in); + delete [] linebuffer; + + if (pl) { + pl->setProgressStr ("Ready."); + pl->setProgress (1.0); + } + + return IMIO_SUCCESS; +} + + +int ImageIO::savePNG (Glib::ustring fname, int compression, int bps) { + + FILE* file=g_fopen(fname.c_str (),"wb"); + + if (!file) + return IMIO_CANNOTREADFILE; + + if (pl) { + pl->setProgressStr ("Saving PNG file..."); + pl->setProgress (0.0); + } + + png_structp png = png_create_write_struct (PNG_LIBPNG_VER_STRING,0,0,0); + if (!png) { + fclose (file); + return IMIO_HEADERERROR; + } + png_infop info = png_create_info_struct(png); + if (!info) { + png_destroy_write_struct (&png,0); + fclose (file); + return IMIO_HEADERERROR; + } + + if (setjmp(png_jmpbuf(png))) { + png_destroy_write_struct (&png,&info); + fclose(file); + return IMIO_READERROR; + } + + png_set_write_fn (png, file, png_write_data, png_flush); + + png_set_compression_level(png,compression); + + int width = getW (); + int height = getH (); + if (bps<0) + bps = getBPS (); + + png_set_IHDR(png, info, width, height, bps, PNG_COLOR_TYPE_RGB, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_BASE); + + + int rowlen = width*3*bps/8; + unsigned char *row = new unsigned char [rowlen]; + + png_write_info(png,info); + for (unsigned int i=0;isetProgress ((double)(i+1)/height); + } + + png_write_end(png,info); + png_destroy_write_struct(&png,&info); + + delete [] row; + fclose (file); + + if (pl) { + pl->setProgressStr ("Ready."); + pl->setProgress (1.0); + } + + return IMIO_SUCCESS; +} + + +int ImageIO::saveJPEG (Glib::ustring fname, int quality) { + + jpeg_compress_struct cinfo; + jpeg_error_mgr jerr; + + cinfo.err = jpeg_std_error (&jerr); + jpeg_create_compress (&cinfo); + + FILE *file = g_fopen (fname.c_str (), "wb"); + + if (!file) + return IMIO_CANNOTREADFILE; + + if (pl) { + pl->setProgressStr ("Saving JPEG file..."); + pl->setProgress (0.0); + } + + jpeg_stdio_dest (&cinfo, file); + + int width = getW (); + int height = getH (); + + cinfo.image_width = width; + cinfo.image_height = height; + cinfo.in_color_space = JCS_RGB; + cinfo.input_components = 3; + jpeg_set_defaults (&cinfo); + cinfo.write_JFIF_header = FALSE; + + + if (quality>=0 && quality<=100) + jpeg_set_quality (&cinfo, quality, true); + + jpeg_start_compress(&cinfo, TRUE); + + // buffer for exif and iptc markers + unsigned char buffer[165535]; + unsigned int size; + // assemble and write exif marker + if (exifRoot) { + int size = rtexif::ExifManager::createJPEGMarker (exifRoot, exifChange, cinfo.image_width, cinfo.image_height, buffer); + if (size>0 && size<65530) + jpeg_write_marker(&cinfo, JPEG_APP0+1, buffer, size); + } + // assemble and write iptc marker + if (iptc) { + unsigned char* iptcdata; + bool error = false; + if (iptc_data_save (iptc, &iptcdata, &size)) { + if (iptcdata) + iptc_data_free_buf (iptc, iptcdata); + error = true; + } + int bytes = 0; + if (!error && (bytes = iptc_jpeg_ps3_save_iptc (NULL, 0, iptcdata, size, buffer, 65532)) < 0) { + if (iptcdata) + iptc_data_free_buf (iptc, iptcdata); + error = true; + } + if (!error) + jpeg_write_marker(&cinfo, JPEG_APP0+13, buffer, bytes); + } + // write icc profile to the output + if (profileData) + write_icc_profile (&cinfo, (JOCTET*)profileData, profileLength); + + // write image data + int rowlen = width*3; + unsigned char *row = new unsigned char [rowlen]; + + while (cinfo.next_scanline < cinfo.image_height) { + + getScanline (cinfo.next_scanline, row, 8); + + if (jpeg_write_scanlines (&cinfo, &row, 1) < 1) { + jpeg_finish_compress (&cinfo); + jpeg_destroy_compress (&cinfo); + fclose (file); + return IMIO_READERROR; + } + + if (pl && !(cinfo.next_scanline%100)) + pl->setProgress ((double)(cinfo.next_scanline)/cinfo.image_height); + } + + jpeg_finish_compress (&cinfo); + jpeg_destroy_compress (&cinfo); + + delete [] row; + fclose (file); + + if (pl) { + pl->setProgressStr ("Ready."); + pl->setProgress (1.0); + } + + return IMIO_SUCCESS; +} + +int ImageIO::saveTIFF (Glib::ustring fname, int bps) { + + int width = getW (); + int height = getH (); + + if (bps<0) + bps = getBPS (); + + int lineWidth = width*3*bps/8; + unsigned char* linebuffer = new unsigned char[lineWidth]; + + if (exifRoot) { + FILE *file = g_fopen (fname.c_str (), "wb"); + + if (!file) + return IMIO_CANNOTREADFILE; + + if (pl) { + pl->setProgressStr ("Saving TIFF file..."); + pl->setProgress (0.0); + } + + // buffer for the exif and iptc + unsigned char buffer[165535]; + unsigned char* iptcdata = NULL; + unsigned int iptclen = 0; + if (iptc && iptc_data_save (iptc, &iptcdata, &iptclen) && iptcdata) { + iptc_data_free_buf (iptc, iptcdata); + iptcdata = NULL; + } + int size = rtexif::ExifManager::createTIFFHeader (exifRoot, exifChange, width, height, bps, profileData, profileLength, (char*)iptcdata, iptclen, buffer); + if (iptcdata) + iptc_data_free_buf (iptc, iptcdata); + if (size>0 && size<165530) + fwrite (buffer, size, 1, file); + + bool needsReverse = bps==16 && exifRoot->getOrder()==rtexif::MOTOROLA; + + for (int i=0; isetProgress ((double)(i+1)/height); + } + + fclose (file); + } + else { + #ifdef WIN32 + wchar_t *wfilename = (wchar_t*)g_utf8_to_utf16 (fname.c_str(), -1, NULL, NULL, NULL); + TIFF* out = TIFFOpenW (wfilename, "w"); + g_free (wfilename); + #else + TIFF* out = TIFFOpen(fname.c_str(), "w"); + #endif + if (!out) + return IMIO_CANNOTREADFILE; + + if (pl) { + pl->setProgressStr ("Saving TIFF file..."); + pl->setProgress (0.0); + } + + TIFFSetField (out, TIFFTAG_IMAGEWIDTH, width); + TIFFSetField (out, TIFFTAG_IMAGELENGTH, height); + TIFFSetField (out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); + TIFFSetField (out, TIFFTAG_SAMPLESPERPIXEL, 3); + TIFFSetField (out, TIFFTAG_BITSPERSAMPLE, bps); + TIFFSetField (out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + TIFFSetField (out, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); + TIFFSetField (out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); + TIFFSetField (out, TIFFTAG_COMPRESSION, COMPRESSION_NONE); + + if (profileData) + TIFFSetField (out, TIFFTAG_ICCPROFILE, profileLength, profileData); + + for (int row = 0; row < height; row++) { + getScanline (row, linebuffer, bps); + + if (TIFFWriteScanline (out, linebuffer, row, 0) < 0) { + TIFFClose (out); + delete [] linebuffer; + return IMIO_READERROR; + } + if (pl && !(row%100)) + pl->setProgress ((double)(row+1)/height); + } + TIFFClose (out); + } + + delete [] linebuffer; + if (pl) { + pl->setProgressStr ("Ready."); + pl->setProgress (1.0); + } + + return IMIO_SUCCESS; +} + +// PNG read and write routines: + +void png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { + png_size_t check; + + /* fread() returns 0 on error, so it is OK to store this in a png_size_t + * instead of an int, which is what fread() actually returns. + */ + check = (png_size_t)fread(data, (png_size_t)1, length, (FILE *)png_ptr->io_ptr); + + if (check != length) + { + png_error(png_ptr, "Read Error"); + } +} + +void png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { + png_uint_32 check; + + check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr)); + if (check != length) + { + png_error(png_ptr, "Write Error"); + } +} + +void png_flush(png_structp png_ptr) { + FILE *io_ptr; + io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr)); + if (io_ptr != NULL) + fflush(io_ptr); +} + +int ImageIO::load (Glib::ustring fname) { + + int lastdot = fname.find_last_of ('.'); + + if (!fname.casefold().compare (lastdot, 4, ".png")) + return loadPNG (fname); + else if (!fname.casefold().compare (lastdot, 4, ".jpg")) + return loadJPEG (fname); + else if (!fname.casefold().compare (lastdot, 4, ".tif")) + return loadTIFF (fname); +} + +int ImageIO::save (Glib::ustring fname) { + + int lastdot = fname.find_last_of ('.'); + + if (!fname.casefold().compare (lastdot, 4, ".png")) + return savePNG (fname); + else if (!fname.casefold().compare (lastdot, 4, ".jpg")) + return saveJPEG (fname); + else if (!fname.casefold().compare (lastdot, 4, ".tif")) + return saveTIFF (fname); +} + diff --git a/rtengine/imageio.h b/rtengine/imageio.h new file mode 100644 index 000000000..a48bd819e --- /dev/null +++ b/rtengine/imageio.h @@ -0,0 +1,87 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _IMAGEIO_ +#define _IMAGEIO_ + +#define IMIO_SUCCESS 0 +#define IMIO_CANNOTREADFILE 1 +#define IMIO_INVALIDHEADER 2 +#define IMIO_HEADERERROR 3 +#define IMIO_READERROR 4 +#define IMIO_VARIANTNOTSUPPORTED 5 + +#include +#include +#include +#include +#include + +namespace rtengine { + +class ImageIO { + + protected: + ProgressListener* pl; + cmsHPROFILE embProfile; + char* profileData; + int profileLength; + char* loadedProfileData; + int loadedProfileLength; + std::vector > exifChange; + IptcData* iptc; + const rtexif::TagDirectory* exifRoot; + Glib::Mutex imutex; + + public: + static Glib::ustring errorMsg[6]; + + ImageIO () : pl (NULL), embProfile(NULL), profileData(NULL), exifRoot (NULL), iptc(NULL), loadedProfileData(NULL), loadedProfileLength(0) {} + + virtual ~ImageIO (); + + void setProgressListener (ProgressListener* l) { pl = l; } + + virtual int getW () =0; + virtual int getH () =0; + virtual void allocate (int width, int height) =0; + virtual int getBPS () =0; + virtual void getScanline (int row, unsigned char* buffer, int bps) {} + virtual void setScanline (int row, unsigned char* buffer, int bps) {} + + int load (Glib::ustring fname); + int save (Glib::ustring fname); + + int loadPNG (Glib::ustring fname); + int loadJPEG (Glib::ustring fname); + int loadTIFF (Glib::ustring fname); + + int savePNG (Glib::ustring fname, int compression = -1, int bps = -1); + int saveJPEG (Glib::ustring fname, int quality = 100); + int saveTIFF (Glib::ustring fname, int bps = -1); + + cmsHPROFILE getEmbeddedProfile () { return embProfile; } + void getEmbeddedProfileData (int& length, unsigned char*& pdata) { length = loadedProfileLength; pdata = (unsigned char*)loadedProfileData; } + + void setMetadata (const rtexif::TagDirectory* eroot, const std::vector& exif, const std::vector& iptcc); + void setOutputProfile (char* pdata, int plen); + Glib::Mutex& mutex () { return imutex; } +}; + +}; +#endif diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h new file mode 100644 index 000000000..c9795abeb --- /dev/null +++ b/rtengine/imagesource.h @@ -0,0 +1,95 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _IMAGESOURCE_ +#define _IMAGESOURCE_ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rtengine { + +using namespace procparams; + +#define TR_NONE 0 +#define TR_R90 1 +#define TR_R180 2 +#define TR_R270 3 +#define TR_VFLIP 4 +#define TR_HFLIP 8 +#define TR_ROT 3 + +class PreviewProps { + + public: + + int x, y, w, h, skip; + + PreviewProps (int _x, int _y, int _w, int _h, int _skip) + : x(_x), y(_y), w(_w), h(_h), skip(_skip) {} + +}; + +class ImageSource : public InitialImage { + + private: + int references; + + protected: + cmsHPROFILE embProfile; + Glib::ustring fileName; + ImageData* idata; + + public: + ImageSource () : references (1), embProfile(NULL), idata(NULL) {} + + virtual ~ImageSource () {} + virtual int load (Glib::ustring fname) =0; + virtual void getImage (ColorTemp ctemp, int tran, Image16* image, PreviewProps pp, HRecParams hlp, ColorManagementParams cmp) {} + virtual ColorTemp getWB () =0; + virtual ColorTemp getAutoWB () =0; + virtual ColorTemp getSpotWB (std::vector red, std::vector green, std::vector& blue, int tran) =0; + + virtual double getDefGain () { return 1.0; } + + virtual double getGamma () { return 0.0; } + + virtual void getFullSize (int& w, int& h, int tr = TR_NONE) {} + virtual void getSize (int tran, PreviewProps pp, int& w, int& h) {} + + virtual ImageData* getImageData () =0; + virtual void setProgressListener (ProgressListener* pl) {} + + void increaseRef () { references++; } + void decreaseRef () { references--; if (!references) delete this; } + virtual int getAEHistogram (unsigned int* histogram, int& histcompr) {return 0;} + + // functions inherited from the InitialImage interface + virtual Glib::ustring getFileName () { return fileName; } + virtual cmsHPROFILE getEmbeddedProfile () { return embProfile; } + virtual const ImageMetaData* getMetaData () { return idata; } + virtual ImageSource* getImageSource () { return this; } +}; +}; +#endif diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc new file mode 100644 index 000000000..ebbad1bc4 --- /dev/null +++ b/rtengine/improccoordinator.cc @@ -0,0 +1,577 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#define CLIPTO(a,b,c) ((a)>b?((a)imgsrc = imgsrc; +} + +ImProcCoordinator::~ImProcCoordinator () { + + destroying = true; + updaterThreadStart.lock (); + if (updaterRunning && thread) + thread->join (); + mProcessing.lock(); + mProcessing.unlock(); + freeAll (); + + std::vector toDel = crops; + for (int i=0; idecreaseRef (); + ipf.release (); + updaterThreadStart.unlock (); +} + +DetailedCrop* ImProcCoordinator::createCrop () { + + return new Crop (this); +} + +void ImProcCoordinator::updatePreviewImage (int todo) { + + mProcessing.lock (); + MyTime t1,t2,t3,t4,t5,t6,t7,t8,t9; + t1.set (); + + int numofphases = 10; + int readyphase = 0; + + if (!params.resize.enabled) + params.resize.scale = 1.0; + else if (params.resize.dataspec==1) + params.resize.scale = (double)params.resize.width / (params.coarse.rotate==90 || params.coarse.rotate==270 ? fh : fw); + else if (params.resize.dataspec==2) + params.resize.scale = (double)params.resize.height / (params.coarse.rotate==90 || params.coarse.rotate==270 ? fw : fh); + + progress ("Applying white balance, color correction & sRBG conversion...",100*readyphase/numofphases); + if (todo & M_INIT) { + minit.lock (); + if (settings->verbose) printf ("Applying white balance, color correction & sRBG conversion...\n"); + currWB = ColorTemp (params.wb.temperature, params.wb.green); + if (params.wb.method=="Camera") + currWB = imgsrc->getWB (); + else if (params.wb.method=="Auto") { + if (!awbComputed) { + autoWB = imgsrc->getAutoWB (); + awbComputed = true; + } + currWB = autoWB; + } + params.wb.temperature = currWB.getTemp (); + params.wb.green = currWB.getGreen (); + + int tr = TR_NONE; + if (params.coarse.rotate==90) tr |= TR_R90; + if (params.coarse.rotate==180) tr |= TR_R180; + if (params.coarse.rotate==270) tr |= TR_R270; + if (params.coarse.hflip) tr |= TR_HFLIP; + if (params.coarse.vflip) tr |= TR_VFLIP; + + imgsrc->getFullSize (fw, fh, tr); + PreviewProps pp (0, 0, fw, fh, scale); + setScale (scale, true); + imgsrc->getImage (currWB, tr, orig_prev, pp, params.hlrecovery, params.icm); + ipf.firstAnalysis (orig_prev, ¶ms, vhist16, imgsrc->getGamma()); + minit.unlock (); + } + + t2.set (); + if (settings->verbose) printf ("INIT: %d\n", t2.etime(t1)); + readyphase++; + + progress ("Rotate / Distortion...",100*readyphase/numofphases); +// printf ("ROTSTAT: %g, %g, %d, %d\n", params.rotate.degree, params.distortion.amount, (int)orig_prev, (int)oprevi); + // check if the transformation has been switched off: + bool needstransform = fabs(params.rotate.degree)>1e-15 || fabs(params.distortion.amount)>1e-15 || fabs(params.cacorrection.red)>1e-15 || fabs(params.cacorrection.blue)>1e-15; + bool needsvignetting = params.vignetting.amount!=0; + if (!needstransform && !needsvignetting && orig_prev!=oprevi) { + delete oprevi; + oprevi = orig_prev; + } + // check if the transformation has been switched on: + else if ((needstransform || needsvignetting) && orig_prev==oprevi) { + oprevi = new Image16 (pW, pH); + } + if ((todo & M_TRANSFORM) && !needstransform && needsvignetting) + ipf.vignetting (orig_prev, oprevi, ¶ms, 0, 0, pW, pH); + else if ((todo & M_TRANSFORM) && needstransform) + if (scale==1) + ipf.transform (orig_prev, oprevi, ¶ms, 0, 0, 0, 0, pW, pH); + else + ipf.simpltransform (orig_prev, oprevi, ¶ms, 0, 0, 0, 0, pW, pH); + + t3.set (); + if (settings->verbose) printf ("TRANSFORM: %d\n", t3.etime(t2)); + readyphase++; + + + progress ("Preparing shadow/highlight map...",100*readyphase/numofphases); + if ((todo & M_BLURMAP) && params.sh.enabled) { + double radius = sqrt (double(pW*pW+pH*pH)) / 2.0; + double shradius = radius / 1800.0 * params.sh.radius; + shmap->update (oprevi, (unsigned short**)buffer, shradius, ipf.lumimul, params.sh.hq); + } + + t4.set (); + if (settings->verbose) printf ("BLURMAP: %d\n", t4.etime(t3)); + readyphase++; + + if (todo & M_AUTOEXP) { + if (params.toneCurve.autoexp) { + unsigned int aehist[65536]; int aehistcompr; + imgsrc->getAEHistogram (aehist, aehistcompr); + ipf.getAutoExp (aehist, aehistcompr, imgsrc->getDefGain(), params.toneCurve.clip, params.toneCurve.expcomp, params.toneCurve.black); + if (aeListener) + aeListener->autoExpChanged (params.toneCurve.expcomp, params.toneCurve.black); + } + } + progress ("Exposure curve & CIELAB conversion...",100*readyphase/numofphases); + if (todo & M_RGBCURVE) { + CurveFactory::complexCurve (params.toneCurve.expcomp, params.toneCurve.black/65535.0, params.toneCurve.hlcompr, params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, imgsrc->getDefGain(), imgsrc->getGamma(), true, params.toneCurve.curve, vhist16, tonecurve, bcrgbhist, scale==1 ? 1 : 1); + ipf.rgbProc (oprevi, oprevl, ¶ms, tonecurve, shmap); + + // recompute luminance histogram + memset (lhist16, 0, 65536*sizeof(int)); + for (int i=0; iL[i][j]]++; + } + t5.set (); + if (settings->verbose) printf ("RGB: %d\n", t5.etime(t4)); + readyphase++; + + if (todo & M_LUMACURVE) { + CurveFactory::complexCurve (0.0, 0.0, 0.0, 0.0, params.lumaCurve.brightness, params.lumaCurve.contrast, 0.0, 0.0, false, params.lumaCurve.curve, lhist16, lumacurve, bcLhist, scale==1 ? 1 : 16); + } + + if (todo & M_LUMINANCE) { + progress ("Applying Luminance Curve...",100*readyphase/numofphases); + ipf.luminanceCurve (oprevl, nprevl, lumacurve, 0, pH); + readyphase++; + if (scale==1) { + progress ("Denoising luminance...",100*readyphase/numofphases); + ipf.lumadenoise (nprevl, ¶ms, scale*params.resize.scale, buffer); + } + readyphase++; + if (scale==1) { + progress ("Sharpening...",100*readyphase/numofphases); + ipf.sharpening (nprevl, ¶ms, scale*params.resize.scale, (unsigned short**)buffer); + } + readyphase++; + } + + t6.set (); + if (settings->verbose) printf ("LUMINANCE: %d\n", t6.etime(t5)); + + if (todo & M_COLOR) { + progress ("Applying Color Boost...",100*readyphase/numofphases); + ipf.colorCurve (oprevl, nprevl, ¶ms); + readyphase++; + if (scale==1) { + progress ("Denoising color...",100*readyphase/numofphases); + ipf.colordenoise (nprevl, ¶ms, scale*params.resize.scale, buffer); + } + readyphase++; + } + + t7.set (); + if (settings->verbose) printf ("COLOR: %d\n", t7.etime(t6)); + + // process crop, if needed + for (int i=0; ihasListener ()) + crops[i]->update (todo, true); + + progress ("Conversion to RGB...",100*readyphase/numofphases); + if (todo!=CROP) { + previmg->getMutex().lock(); + ipf.lab2rgb (nprevl, previmg); + previmg->getMutex().unlock(); + } + if (!resultValid) { + resultValid = true; + if (imageListener) + imageListener->setImage (previmg, scale*params.resize.scale, params.crop); + } + if (imageListener) + imageListener->imageReady (params.crop); + + readyphase++; + + t8.set (); + if (settings->verbose) printf ("RGBCONVERT: %d\n", t8.etime(t7)); + + if (hListener) { + int hx1 = 0, hx2 = pW, hy1 = 0, hy2 = pH; + if (params.crop.enabled) { + hx1 = MIN(pW-1,MAX(0,params.crop.x / scale)); + hy1 = MIN(pH-1,MAX(0,params.crop.y / scale)); + hx2 = MIN(pW,MAX(0,(params.crop.x+params.crop.w) / scale)); + hy2 = MIN(pH,MAX(0,(params.crop.y+params.crop.h) / scale)); + } + updateHistograms (hx1, hy1, hx2, hy2); + hListener->histogramChanged (rhist, ghist, bhist, Lhist, bcrgbhist, bcLhist); + } + + t9.set (); + if (settings->verbose) printf ("Total processing time: %d\n", t9.etime(t1)); + progress ("Ready",100*readyphase/numofphases); + + mProcessing.unlock (); +} + + +void ImProcCoordinator::freeAll () { + + if (settings->verbose) printf ("freeall starts %d\n", (int)allocated); + + if (allocated) { + if (orig_prev!=oprevi) + delete oprevi; + delete orig_prev; + delete oprevl; + delete nprevl; + if (imageListener) { + imageListener->delImage (previmg); + } + else + delete previmg; + delete shmap; + for (int i=0; iverbose) printf ("setscale before lock\n"); + + if (!internal) + mProcessing.lock (); + + tr = TR_NONE; + if (params.coarse.rotate==90) tr |= TR_R90; + if (params.coarse.rotate==180) tr |= TR_R180; + if (params.coarse.rotate==270) tr |= TR_R270; + if (params.coarse.hflip) tr |= TR_HFLIP; + if (params.coarse.vflip) tr |= TR_VFLIP; + + int nW, nH; + imgsrc->getFullSize (fw, fh, tr); + + PreviewProps pp (0, 0, fw, fh, prevscale); + imgsrc->getSize (tr, pp, nW, nH); + + if (settings->verbose) printf ("setscale starts (%d, %d)\n", nW, nH); + + if (nW!=pW || nH!=pH) { + + freeAll (); + + pW = nW; + pH = nH; + + orig_prev = new Image16 (pW, pH); + oprevi = orig_prev; + oprevl = new LabImage (pW, pH); + nprevl = new LabImage (pW, pH); + previmg = new Image8 (pW, pH); + shmap = new SHMap (pW, pH); + + buffer = new int*[pH]; + for (int i=0; iverbose) printf ("setscale ends\n"); + if (sizeListeners.size()>0) + for (int i=0; isizeChanged (fullw, fullh, fw, fh); + if (settings->verbose) printf ("setscale ends2\n"); + + if (!internal) + mProcessing.unlock (); +} + + +void ImProcCoordinator::updateHistograms (int x1, int y1, int x2, int y2) { + + memset (rhist, 0, 256*sizeof(int)); + memset (ghist, 0, 256*sizeof(int)); + memset (bhist, 0, 256*sizeof(int)); + + for (int i=y1; idata[ofs++]]++; + ghist[previmg->data[ofs++]]++; + bhist[previmg->data[ofs++]]++; + } + } + + memset (Lhist, 0, 256*sizeof(int)); + for (int i=y1; iL[i][j]/256]++; +} + +void ImProcCoordinator::progress (Glib::ustring str, int pr) { + +/* if (plistener) { + plistener->setProgressStr (str); + plistener->setProgress ((double)pr / 100.0); + }*/ +} + +void ImProcCoordinator::getAutoWB (double& temp, double& green) { + + if (imgsrc) { + if (!awbComputed) { + minit.lock (); + autoWB = imgsrc->getAutoWB (); + minit.unlock (); + awbComputed = true; + } + temp = autoWB.getTemp (); + green = autoWB.getGreen (); + } +} + +void ImProcCoordinator::getCamWB (double& temp, double& green) { + + if (imgsrc) { + temp = imgsrc->getWB().getTemp (); + green = imgsrc->getWB().getGreen (); + } +} + +void ImProcCoordinator::getSpotWB (int x, int y, int rect, double& temp, double& tgreen) { + + mProcessing.lock (); + std::vector points, red, green, blue; + for (int i=y-rect; i<=y+rect; i++) + for (int j=x-rect; j<=x+rect; j++) + points.push_back (Coord2D (j, i)); + + ipf.transCoord (¶ms, fw, fh, points, red, green, blue); + int tr = TR_NONE; + if (params.coarse.rotate==90) tr |= TR_R90; + if (params.coarse.rotate==180) tr |= TR_R180; + if (params.coarse.rotate==270) tr |= TR_R270; + if (params.coarse.hflip) tr |= TR_HFLIP; + if (params.coarse.vflip) tr |= TR_VFLIP; + + ColorTemp ret = imgsrc->getSpotWB (red, green, blue, tr); + mProcessing.unlock (); + temp = ret.getTemp (); + tgreen = ret.getGreen (); +} + +void ImProcCoordinator::getAutoCrop (double ratio, int &x, int &y, int &w, int &h) { + + mProcessing.lock (); + w = fullw; + bool clipped = true; + while (clipped && w>16) { + if (ratio>0) + h = w / ratio; + else + h = w * fullh / fullw; + x = (fullw - w) / 2; + y = (fullh - h) / 2; + int orx, ory, orw, orh; + clipped = ipf.transCoord (¶ms, fw, fh, x, y, w, h, orx, ory, orw, orh); + w -= 4; + } + if (ratio>0) + h = w / ratio; + else + h = w * fullh / fullw; + x = (fullw - w) / 2; + y = (fullh - h) / 2; + mProcessing.unlock (); +} + +void ImProcCoordinator::fullUpdatePreviewImage () { + + if (destroying) + return; + + updaterThreadStart.lock (); + if (updaterRunning && thread) { + changeSinceLast = 0; + thread->join (); + } + + if (plistener) + plistener->setProgressState (1); + + updatePreviewImage (ALL); + + if (plistener) + plistener->setProgressState (0); + + updaterThreadStart.unlock (); +} + +void ImProcCoordinator::fullUpdateDetailedCrops () { + + if (destroying) + return; + + updaterThreadStart.lock (); + if (updaterRunning && thread) { + changeSinceLast = 0; + thread->join (); + } + + if (plistener) + plistener->setProgressState (1); + + for (int i=0; iupdate (ALL, true); + + if (plistener) + plistener->setProgressState (0); + + updaterThreadStart.unlock (); +} + + +void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname) { + + mProcessing.lock (); + + int fW, fH; + imgsrc->getFullSize (fW, fH, 0); + PreviewProps pp (0, 0, fW, fH, 1); + ProcParams ppar = params; + ppar.hlrecovery.enabled = false; + ppar.icm.input = "(none)"; + Image16* im = new Image16 (fW, fH); + imgsrc->getImage (imgsrc->getWB(), 0, im, pp, ppar.hlrecovery, ppar.icm); + im->saveJPEG (fname, 85); + mProcessing.unlock (); +} + +void ImProcCoordinator::stopProcessing () { + + updaterThreadStart.lock (); + if (updaterRunning && thread) { + changeSinceLast = 0; + thread->join (); + } + updaterThreadStart.unlock (); +} + +void ImProcCoordinator::startProcessing () { + + #undef THREAD_PRIORITY_NORMAL + + if (!destroying) { + updaterThreadStart.lock (); + if (!updaterRunning) { + thread = NULL; + updaterRunning = true; + updaterThreadStart.unlock (); + thread = Glib::Thread::create(sigc::mem_fun(*this, &ImProcCoordinator::process), 0, false, true, Glib::THREAD_PRIORITY_NORMAL); + } + else + updaterThreadStart.unlock (); + } +} + +void ImProcCoordinator::process () { + + if (plistener) + plistener->setProgressState (1); + + paramsUpdateMutex.lock (); + while (changeSinceLast) { + params = nextParams; + int ch = changeSinceLast; + changeSinceLast = 0; + paramsUpdateMutex.unlock (); + if (ch&32767) + updatePreviewImage (ch); + paramsUpdateMutex.lock (); + } + paramsUpdateMutex.unlock (); + updaterRunning = false; + + if (plistener) + plistener->setProgressState (0); +} + +ProcParams* ImProcCoordinator::getParamsForUpdate (ProcEvent change) { + + paramsUpdateMutex.lock (); + changeSinceLast |= refreshmap[(int)change]; + return &nextParams; +} + +void ImProcCoordinator::paramsUpdateReady () { + + paramsUpdateMutex.unlock (); + startProcessing (); +} + + +} diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h new file mode 100644 index 000000000..1324bf5a2 --- /dev/null +++ b/rtengine/improccoordinator.h @@ -0,0 +1,152 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _IMPROCCOORDINATOR_H_ +#define _IMPROCCOORDINATOR_H_ + +#include +#include +#include +#include +#include +#include +#include + +namespace rtengine { + +using namespace procparams; + +class Crop; + +class ImProcCoordinator : public StagedImageProcessor { + + friend class Crop; + + protected: + Image16 *orig_prev; + Image16 *oprevi; + LabImage *oprevl; + LabImage *nprevl; + Image8 *previmg; + ImageSource* imgsrc; + + int** buffer; + + SHMap* shmap; + + ColorTemp currWB; + ColorTemp autoWB; + + bool awbComputed; + + ImProcFunctions ipf; + + int scale; + bool allocated; + + void freeAll (); + + int tonecurve [65536]; + int lumacurve [65536]; + + unsigned int vhist16[65536]; + unsigned int lhist16[65536]; + + unsigned int rhist[256], ghist[256], bhist[256], Lhist[256], bcrgbhist[256], bcLhist[256]; + + int fw, fh, tr, fullw, fullh; + int pW, pH; + + ProgressListener* plistener; + PreviewImageListener* imageListener; + AutoExpListener* aeListener; + HistogramListener* hListener; + std::vector sizeListeners; + + std::vector crops; + + bool resultValid; + + Glib::Mutex minit; + + void progress (Glib::ustring str, int pr); + void reallocAll (); + void updateHistograms (int x1, int y1, int x2, int y2); + void setScale (int prevscale, bool internal=false); + void updatePreviewImage (int todo); + + Glib::Mutex mProcessing; + ProcParams params; + + // members of the updater: + Glib::Thread* thread; + Glib::Mutex updaterThreadStart; + Glib::Mutex paramsUpdateMutex; + int changeSinceLast; + bool updaterRunning; + ProcParams nextParams; + bool destroying; + + void startProcessing (); + void process (); + + public: + + ImProcCoordinator (); + ~ImProcCoordinator (); + void assign (ImageSource* imgsrc); + + void getParams (procparams::ProcParams* dst) { *dst = params; } + + ProcParams* getParamsForUpdate (ProcEvent change); + void paramsUpdateReady (); + void stopProcessing (); + + + void setPreviewScale (int scale) { setScale (scale); } + int getPreviewScale () { return scale; } + + void fullUpdatePreviewImage (); + void fullUpdateDetailedCrops (); + + int getFullWidth () { return fullw; } + int getFullHeight () { return fullh; } + + int getPreviewWidth () { return pW; } + int getPreviewHeight () { return pH; } + + DetailedCrop* createCrop (); + + void getAutoWB (double& temp, double& green); + void getCamWB (double& temp, double& green); + void getSpotWB (int x, int y, int rectSize, double& temp, double& green); + void getAutoCrop (double ratio, int &x, int &y, int &w, int &h); + + void setProgressListener (ProgressListener* pl) { plistener = pl; } + void setPreviewImageListener (PreviewImageListener* il) {imageListener = il; } + void setSizeListener (SizeListener* il) {sizeListeners.push_back (il); } + void delSizeListener (SizeListener* il) {std::vector::iterator it = std::find (sizeListeners.begin(), sizeListeners.end(), il); if (it!=sizeListeners.end()) sizeListeners.erase (it); } + void setAutoExpListener (AutoExpListener* ael) {aeListener = ael; } + void setHistogramListener(HistogramListener *h) {hListener = h; } + + void saveInputICCReference (const Glib::ustring& fname); + + InitialImage* getInitialImage () { return imgsrc; } +}; +} +#endif diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc new file mode 100644 index 000000000..beae7850d --- /dev/null +++ b/rtengine/improcfun.cc @@ -0,0 +1,2259 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rtengine { + +using namespace procparams; + +#undef MAX +#undef MIN +#undef MAXVAL +#undef CLIP +#undef CLIPS +#undef CLIPC +#undef CLIPTO +#undef CLIPTOC +#undef THREAD_PRIORITY_NORMAL + +#define MAXVAL 0xffff +#define CLIP(a) ((a)>0?((a)-32768?((a)<32767?(a):32767):-32768) +#define CLIPC(a) ((a)>-32000?((a)<32000?(a):32000):-32000) +#define MAX(a,b) ((a)<(b)?(b):(a)) +#define MIN(a,b) ((a)>(b)?(b):(a)) +#define CLIPTO(a,b,c) ((a)>(b)?((a)<(c)?(a):(c)):(b)) +#define CLIPTOC(a,b,c,d) ((a)>=(b)?((a)<=(c)?(a):((c),d=true)):((b),d=true)) + +extern const Settings* settings; + +// +// STRUCTURES FOR THE SHADOW MAP AND LAB SPACE IMAGE +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +LabImage::LabImage (int w, int h) : W(w), H(h), fromImage(false) { + + L = new unsigned short*[H]; + for (int i=0; iwidth; + H = im->height; + L = im->r; + a = (short**) im->g; + b = (short**) im->b; + fromImage = true; +} + +LabImage::~LabImage () { + + if (!fromImage) { + for (int i=0; i0?((a)(c)?(c):(a))) + +#define MAX(a,b) ((a)<(b)?(b):(a)) +#define MIN(a,b) ((a)>(b)?(b):(a)) + +#define MAXL 65535 +#define ABS(a) ((a)<0?-(a):(a)) + + +int* ImProcFunctions::cacheL; +int* ImProcFunctions::cachea; +int* ImProcFunctions::cacheb; +int* ImProcFunctions::xcache; +int* ImProcFunctions::ycache; +int* ImProcFunctions::zcache; +unsigned short ImProcFunctions::gamma2curve[65536]; + +/*const int c00 = (int) (32768.0 * 0.412453 / 0.950456); +const int c01 = (int) (32768.0 * 0.357580 / 0.950456); +const int c02 = (int) (32768.0 * 0.180423 / 0.950456); +const int c10 = (int) (32768.0 * 0.212671); +const int c11 = (int) (32768.0 * 0.715160); +const int c12 = (int) (32768.0 * 0.072169); +const int c20 = (int) (32768.0 * 0.019334 / 1.088754); +const int c21 = (int) (32768.0 * 0.119193 / 1.088754); +const int c22 = (int) (32768.0 * 0.950227 / 1.088754); +*/ + +void ImProcFunctions::initCache () { + + int maxindex = 2*65536; + cacheL = new int[maxindex]; + cachea = new int[maxindex]; + cacheb = new int[maxindex]; + + int threshold = (int)(0.008856*CMAXVAL); + for (int i=0; ithreshold) { + cacheL[i] = (int)round(655.35 * (116.0 * exp(1.0/3.0 * log((double)i / CMAXVAL)) - 16.0)); + cachea[i] = (int)round(32768.0 * 500.0 * exp(1.0/3.0 * log((double)i / CMAXVAL))); + cacheb[i] = (int)round(32768.0 * 200.0 * exp(1.0/3.0 * log((double)i / CMAXVAL))); + } + else { + cacheL[i] = (int)round(9033.0 * (double)i / 1000.0); // assuming CMAXVAL = 65535 + cachea[i] = (int)round(32768.0 * 500.0 * (7.787*i/CMAXVAL+16.0/116.0)); + cacheb[i] = (int)round(32768.0 * 200.0 * (7.787*i/CMAXVAL+16.0/116.0)); + } + + double fY; + ycache = new int[0x10000]; + for (int i=0; i<0x10000; i++) + ycache[i] = (int)round(65536.0 * ((fY=((double)i/655.35+16)/116) > 2.0689655172413793e-1 ? fY*fY*fY : 1.107056459879453852e-3*(double)i/655.35)); + for (int i=0; i<0x10000; i++) + ycache[i] = CLIP(ycache[i]); + xcache = new int[369621]; + for (int i=-141556; i<228064; i++) + xcache[i+141556] = (int)round(65536.0 * (i > 15728 ? ((double)i/76021)*((double)i/76021)*((double)i/76021)*0.96422 : (1.2841854934601665e-1*(double)i/76021-1.7712903358071262e-2)*0.96422)); + for (int i=0; i<369620; i++) + xcache[i] = CLIP(xcache[i]); + zcache = new int[825747]; + for (int i=-369619; i<456128; i++) + zcache[i+369619] = (int)round(65536.0 * (i > 15728 ? ((double)i/76021)*((double)i/76021)*((double)i/76021)*0.82521 : (1.2841854934601665e-1*(double)i/76021-1.7712903358071262e-2)*0.82521)); + for (int i=0; i<825747; i++) + zcache[i] = CLIP(zcache[i]); + + for (int i=0; i<65536; i++) { + int g = (int)(CurveFactory::gamma2(i/65535.0) * 65535.0); + gamma2curve[i] = CLIP(g); + } +} + +void ImProcFunctions::release () { + + if (monitorTransform!=NULL) + cmsDeleteTransform (monitorTransform); + monitorTransform = NULL; +} + +void ImProcFunctions::firstAnalysis_ (Image16* original, Glib::ustring wprofile, unsigned int* histogram, int* chroma_radius, int row_from, int row_to) { + + TMatrix wprof = iccStore.workingSpaceMatrix (wprofile); + int toxyz[3][3]; + toxyz[0][0] = round(32768.0 * wprof[0][0] / 0.96422); + toxyz[1][0] = round(32768.0 * wprof[1][0] / 0.96422); + toxyz[2][0] = round(32768.0 * wprof[2][0] / 0.96422); + toxyz[0][1] = round(32768.0 * wprof[0][1]); + toxyz[1][1] = round(32768.0 * wprof[1][1]); + toxyz[2][1] = round(32768.0 * wprof[2][1]); + toxyz[0][2] = round(32768.0 * wprof[0][2] / 0.82521); + toxyz[1][2] = round(32768.0 * wprof[1][2] / 0.82521); + toxyz[2][2] = round(32768.0 * wprof[2][2] / 0.82521); + + lumimul[0] = wprof[0][1]; + lumimul[1] = wprof[1][1]; + lumimul[2] = wprof[2][1]; + + int W = original->width; + int cradius = 1; + for (int i=row_from; ir[i][j]; + int g = original->g[i][j]; + int b = original->b[i][j]; + + int x = (toxyz[0][0] * r + toxyz[1][0] * g + toxyz[2][0] * b) >> 15; + int y = (toxyz[0][1] * r + toxyz[1][1] * g + toxyz[2][1] * b) >> 15; + int z = (toxyz[0][2] * r + toxyz[1][2] * g + toxyz[2][2] * b) >> 15; + + x = CLIPTO(x,0,2*65536-1); + y = CLIPTO(y,0,2*65536-1); + z = CLIPTO(z,0,2*65536-1); + + int oa = cachea[x] - cachea[y]; + int ob = cacheb[y] - cacheb[z]; + + if (oa<0) oa = -oa; + if (ob<0) ob = -ob; + + if (oa > cradius) + cradius = oa; + if (ob > cradius) + cradius = ob; + + if (histogram) { + int hval = CLIP(y); //(306 * original->r[i][j] + 601 * original->g[i][j] + 117 * original->b[i][j]) >> 10; + histogram[hval]++; + } + } + } + *chroma_radius = cradius; +} + +void ImProcFunctions::firstAnalysis (Image16* original, const ProcParams* params, unsigned int* histogram, double gamma) { + + int cr1, cr2; + unsigned int* hist1 = new unsigned int[65536]; memset (hist1, 0, 65536*sizeof(int)); + unsigned int* hist2 = new unsigned int[65536]; memset (hist2, 0, 65536*sizeof(int)); + + int H = original->height; + + Glib::ustring wprofile = params->icm.working; + if (monitorTransform) + cmsDeleteTransform (monitorTransform); + monitorTransform = NULL; + cmsHPROFILE monitor = iccStore.getProfile ("file:"+settings->monitorProfile); + if (monitor) { + cmsHPROFILE iprof = iccStore.getXYZProfile (); + cmsHPROFILE oprof = iccStore.getProfile (params->icm.output); + if (!oprof) + oprof = iccStore.getsRGBProfile (); + lcmsMutex->lock (); + monitorTransform = cmsCreateTransform (iprof, TYPE_RGB_16, monitor, TYPE_RGB_8, settings->colorimetricIntent, 0); + lcmsMutex->unlock (); + } + + if (settings->dualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::firstAnalysis_), original, wprofile, hist1, &cr1, 0, H/2), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::firstAnalysis_), original, wprofile, hist2, &cr2, H/2, H), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else { + firstAnalysis_ (original, wprofile, hist1, &cr1, 0, H/2); + firstAnalysis_ (original, wprofile, hist2, &cr2, H/2, H); + } + + if (cr1dualThreadEnabled) { + + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::rgbProc_), working, lab, params, tonecurve, shmap, 0, working->height/2), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::rgbProc_), working, lab, params, tonecurve, shmap, working->height/2, working->height), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else + rgbProc_ (working, lab, params, tonecurve, shmap, 0, working->height); +} + +void ImProcFunctions::rgbProc_ (Image16* working, LabImage* lab, const ProcParams* params, int* tonecurve, SHMap* shmap, int row_from, int row_to) { + + int r, g, b; + + int h_th, s_th; + if (shmap) { + h_th = shmap->max - params->sh.htonalwidth * (shmap->max - shmap->avg) / 100; + s_th = params->sh.stonalwidth * (shmap->avg - shmap->min) / 100; + } + + bool processSH = params->sh.enabled && shmap!=NULL && (params->sh.highlights>0 || params->sh.shadows>0); + bool processLCE = params->sh.enabled && shmap!=NULL && params->sh.localcontrast>0; + double lceamount = params->sh.localcontrast / 200.0; + + TMatrix wprof = iccStore.workingSpaceMatrix (params->icm.working); + int toxyz[3][3] = { + floor(32768.0 * wprof[0][0] / 0.96422), + floor(32768.0 * wprof[0][1]), + floor(32768.0 * wprof[0][2] / 0.82521), + floor(32768.0 * wprof[1][0] / 0.96422), + floor(32768.0 * wprof[1][1]), + floor(32768.0 * wprof[1][2] / 0.82521), + floor(32768.0 * wprof[2][0] / 0.96422), + floor(32768.0 * wprof[2][1]), + floor(32768.0 * wprof[2][2] / 0.82521)}; + + bool mixchannels = params->chmixer.red[0]!=100 || params->chmixer.red[1]!=0 || params->chmixer.red[2]!=0 || params->chmixer.green[0]!=0 || params->chmixer.green[1]!=100 || params->chmixer.green[2]!=0 || params->chmixer.blue[0]!=0 || params->chmixer.blue[1]!=0 || params->chmixer.blue[2]!=100; + + int mapval; + double factor; + int tW = working->width; + for (int i=row_from; ir[i][j]; + g = working->g[i][j]; + b = working->b[i][j]; + + if (mixchannels) { + int newr = (r*params->chmixer.red[0] + g*params->chmixer.red[1] + b*params->chmixer.red[2]) / 100; + int newg = (r*params->chmixer.green[0] + g*params->chmixer.green[1] + b*params->chmixer.green[2]) / 100; + int newb = (r*params->chmixer.blue[0] + g*params->chmixer.blue[1] + b*params->chmixer.blue[2]) / 100; + r = CLIP(newr); + g = CLIP(newg); + b = CLIP(newb); + } + + if (processSH || processLCE) { + mapval = shmap->map[i][j]; + factor = 1.0; + + if (processSH) { + if (mapval > h_th) + factor = (h_th + (100.0 - params->sh.highlights) * (mapval - h_th) / 100.0) / mapval; + else if (mapval < s_th) + factor = (s_th - (100.0 - params->sh.shadows) * (s_th - mapval) / 100.0) / mapval; + } + if (processLCE) { + double sub = lceamount*(mapval-factor*(r*lumimul[0] + g*lumimul[1] + b*lumimul[2])); + r = CLIP((int)(factor*r-sub)); + g = CLIP((int)(factor*g-sub)); + b = CLIP((int)(factor*b-sub)); + } + else { + r = CLIP((int)(factor*r)); + g = CLIP((int)(factor*g)); + b = CLIP((int)(factor*b)); + } + } + r = tonecurve[r]; + g = tonecurve[g]; + b = tonecurve[b]; + +// int x = (14219 * r + 12328 * g + 6220 * b) >> 15; +// int y = ( 6968 * r + 23434 * g + 2365 * b) >> 15; +// int z = ( 582 * r + 3587 * g + 28598 * b) >> 15; + int x = (toxyz[0][0] * r + toxyz[1][0] * g + toxyz[2][0] * b) >> 15; + int y = (toxyz[0][1] * r + toxyz[1][1] * g + toxyz[2][1] * b) >> 15; + int z = (toxyz[0][2] * r + toxyz[1][2] * g + toxyz[2][2] * b) >> 15; + + x = CLIPTO(x,0,2*65536-1); + y = CLIPTO(y,0,2*65536-1); + z = CLIPTO(z,0,2*65536-1); + + int L = cacheL[y]; + lab->L[i][j] = L; + lab->a[i][j] = CLIPC(((cachea[x] - cachea[y]) * chroma_scale) >> 15); + lab->b[i][j] = CLIPC(((cacheb[y] - cacheb[z]) * chroma_scale) >> 15); + } + } + } + +void ImProcFunctions::luminanceCurve (LabImage* lold, LabImage* lnew, int* curve, int row_from, int row_to) { + + int W = lold->W; + int H = lold->H; + for (int i=row_from; iL[i][j] = curve[lold->L[i][j]]; +} + +#include "cubic.cc" + +void ImProcFunctions::colorCurve (LabImage* lold, LabImage* lnew, const ProcParams* params) { + + double* cmultiplier = new double [181021]; + + double boost_a = (params->colorBoost.amount + 100.0) / 100.0; + double boost_b = (params->colorBoost.amount + 100.0) / 100.0; + + double c, amul = 1.0, bmul = 1.0; + if (boost_a > boost_b) { + c = boost_a; + if (boost_a > 0) + bmul = boost_b / boost_a; + } + else { + c = boost_b; + if (boost_b > 0) + amul = boost_a / boost_b; + } + + if (params->colorBoost.enable_saturationlimiter && c>1) { + // re-generate color multiplier lookup table + double d = params->colorBoost.saturationlimit * chroma_scale / 3.0; + double alpha = 0.5; + double threshold1 = alpha * d; + double threshold2 = c*d*(alpha+1.0) - d; + for (int i=0; i<=181020; i++) { // lookup table stores multipliers with a 0.25 chrominance resolution + double chrominance = (double)i/4; + if (chrominance < threshold1) + cmultiplier[i] = c; + else if (chrominance < d) + cmultiplier[i] = (c / (2.0*d*(alpha-1.0)) * (chrominance-d)*(chrominance-d) + c*d/2.0 * (alpha+1.0) ) / chrominance; + else if (chrominance < threshold2) + cmultiplier[i] = (1.0 / (2.0*d*(c*(alpha+1.0)-2.0)) * (chrominance-d)*(chrominance-d) + c*d/2.0 * (alpha+1.0) ) / chrominance; + else + cmultiplier[i] = 1.0; + } + } + + if (settings->dualThreadEnabled) { + + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::colorCurve_), lold, lnew, params, 0, lnew->H/2, cmultiplier), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::colorCurve_), lold, lnew, params, lnew->H/2, lnew->H, cmultiplier), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else + colorCurve_ (lold, lnew, params, 0, lnew->H, cmultiplier); + + delete [] cmultiplier; +} + +void ImProcFunctions::colorCurve_ (LabImage* lold, LabImage* lnew, const ProcParams* params, int row_from, int row_to, double* cmultiplier) { + + double boost_a = (params->colorBoost.amount + 100.0) / 100.0; + double boost_b = (params->colorBoost.amount + 100.0) / 100.0; + + double c, amul = 1.0, bmul = 1.0; + if (boost_a > boost_b) { + c = boost_a; + if (boost_a > 0) + bmul = boost_b / boost_a; + } + else { + c = boost_b; + if (boost_b > 0) + amul = boost_a / boost_b; + } + + int nna, nnb; + double shift_a = params->colorShift.a * chroma_scale, shift_b = params->colorShift.b * chroma_scale; + + short** oa = lold->a; + short** ob = lold->b; + + for (int i=row_from; iW; j++) { + + double wanted_c = c; + if (params->colorBoost.enable_saturationlimiter && c>1) { + int chroma = (int)(4.0 * sqrt((oa[i][j]+shift_a)*(oa[i][j]+shift_a) + (ob[i][j]+shift_b)*(ob[i][j]+shift_b))); + wanted_c = cmultiplier [MIN(chroma,181020)]; + } + + double real_c = wanted_c; + if (wanted_c >= 1.0 && params->colorBoost.avoidclip) { + double cclip = 100000; + double cr = tightestroot ((double)lnew->L[i][j]/655.35, (double)(oa[i][j]+shift_a)/chroma_scale*amul, (double)(ob[i][j]+shift_b)/chroma_scale*bmul, 3.079935, -1.5371515, -0.54278342); + double cg = tightestroot ((double)lnew->L[i][j]/655.35, (double)(oa[i][j]+shift_a)/chroma_scale*amul, (double)(ob[i][j]+shift_b)/chroma_scale*bmul, -0.92123418, 1.87599, 0.04524418); + double cb = tightestroot ((double)lnew->L[i][j]/655.35, (double)(oa[i][j]+shift_a)/chroma_scale*amul, (double)(ob[i][j]+shift_b)/chroma_scale*bmul, 0.052889682, -0.20404134, 1.15115166); + if (cr>1.0 && cr1.0 && cg1.0 && cba[i][j] = CLIPV(nna,-32000,32000); + lnew->b[i][j] = CLIPV(nnb,-32000,32000); + } +} + +void blur (float** src, float** dst, int W, int H, int r) { + + float** tmpI = new float*[H]; + for (int i=0; i=H-r) + tmpI[i][j] = src[i][j]; + else { + int num = 0; + float sum = 0.0; + for (int x=-r; x<=r; x++) + for (int y=-r; y<=r; y++) + if (x*x+y*y<=r*r) { + sum += src[i+x][j+y]; + num++; + } + tmpI[i][j] = sum / num; + } + } + for (int i=0; isharpening.enabled==false || params->sharpening.deconvamount<1) + return; + + int W = lab->W, H = lab->H; + + float** tmpI = new float*[H]; + for (int i=0; iL[i][j]; + } + + float** tmp = (float**)b2; + + AlignedBuffer* buffer1 = new AlignedBuffer (MAX(W,H)*5); + AlignedBuffer* buffer2 = new AlignedBuffer (MAX(W,H)*5); + + float damping = params->sharpening.deconvdamping / 5.0; + bool needdamp = params->sharpening.deconvdamping > 0; + for (int k=0; ksharpening.deconviter; k++) { + +// gaussHorizontal (tmpI, tmp, buffer1, W, 0, H, params->sharpening.deconvradius / scale); +// gaussVertical (tmp, tmp, buffer1, H, 0, W, params->sharpening.deconvradius / scale); + // apply blur function (gaussian blur) + if (settings->dualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussHorizontal_float), tmpI, tmp, buffer1, W, 0, H/2, params->sharpening.deconvradius / scale), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussHorizontal_float), tmpI, tmp, buffer2, W, H/2, H, params->sharpening.deconvradius / scale), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else + gaussHorizontal_float (tmpI, tmp, buffer1, W, 0, H, params->sharpening.deconvradius / scale); + if (settings->dualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussVertical_float), tmp, tmp, buffer1, H, 0, W/2, params->sharpening.deconvradius / scale), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussVertical_float), tmp, tmp, buffer2, H, W/2, W, params->sharpening.deconvradius / scale), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else + gaussVertical_float (tmp, tmp, buffer1, H, 0, W, params->sharpening.deconvradius / scale); + +// blur (tmpI, tmp, W, H, params->sharpening.radius / scale); + if (!needdamp) { + for (int i=0; i0) + tmp[i][j] = (float)lab->L[i][j] / tmp[i][j]; + } + else { + if (settings->dualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::damping_), tmp, lab->L, damping, W, 0, H/2), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::damping_), tmp, lab->L, damping, W, H/2, H), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else + damping_ (tmp, lab->L, damping, W, 0, H); + } +// gaussHorizontal (tmp, tmp, buffer1, W, 0, H, params->sharpening.deconvradius / scale); +// gaussVertical (tmp, tmp, buffer1, H, 0, W, params->sharpening.deconvradius / scale); + // apply blur function (gaussian blur) + if (settings->dualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussHorizontal_float), tmp, tmp, buffer1, W, 0, H/2, params->sharpening.deconvradius / scale), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussHorizontal_float), tmp, tmp, buffer2, W, H/2, H, params->sharpening.deconvradius / scale), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else + gaussHorizontal_float (tmp, tmp, buffer1, W, 0, H, params->sharpening.deconvradius / scale); + if (settings->dualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussVertical_float), tmp, tmp, buffer1, H, 0, W/2, params->sharpening.deconvradius / scale), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussVertical_float), tmp, tmp, buffer2, H, W/2, W, params->sharpening.deconvradius / scale), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else + gaussVertical_float (tmp, tmp, buffer1, H, 0, W, params->sharpening.deconvradius / scale); + +// blur (tmp, tmp, W, H, params->sharpening.radius / scale); + + for (int i=0; iL[i][j] = lab->L[i][j]*(100-params->sharpening.deconvamount) / 100 + (int)CLIP(tmpI[i][j])*params->sharpening.deconvamount / 100; + + for (int i=0; isharpening.method=="rld") { + deconvsharpening (lab, params, scale, b2); + return; + } + + if (params->sharpening.enabled==false || params->sharpening.amount<1 || lab->W<8 || lab->H<8) + return; + + int W = lab->W, H = lab->H; + unsigned short** b3; + if (params->sharpening.edgesonly==false) { + + AlignedBuffer* buffer1 = new AlignedBuffer (MAX(W,H)*5); + AlignedBuffer* buffer2 = new AlignedBuffer (MAX(W,H)*5); + + MyTime t1, t2, t3; + t1.set (); + if (settings->dualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussHorizontal_unsigned), lab->L, b2, buffer1, W, 0, H/2, params->sharpening.radius / scale), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussHorizontal_unsigned), lab->L, b2, buffer2, W, H/2, H, params->sharpening.radius / scale), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else + gaussHorizontal_unsigned (lab->L, b2, buffer1, W, 0, H, params->sharpening.radius / scale); + + t2.set (); +// printf ("Horizontal: %d\n", t2.etime (t1)); + + if (settings->dualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussVertical_unsigned), b2, b2, buffer1, H, 0, W/2, params->sharpening.radius / scale), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussVertical_unsigned), b2, b2, buffer2, H, W/2, W, params->sharpening.radius / scale), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else + gaussVertical_unsigned (b2, b2, buffer1, H, 0, W, params->sharpening.radius / scale); + + t3.set (); +// printf ("Vertical: %d\n", t3.etime (t2)); + + delete buffer1; + delete buffer2; + } + else { + b3 = new unsigned short*[H]; + for (int i=0; i* buffer1 = new AlignedBuffer (MAX(W,H)*5); + AlignedBuffer* buffer2 = new AlignedBuffer (MAX(W,H)*5); + + if (settings->dualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(bilateral_unsigned), lab->L, b3, b2, dim1, params->sharpening.edges_radius / scale, params->sharpening.edges_tolerance), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(bilateral_unsigned), lab->L, b3, b2, dim2, params->sharpening.edges_radius / scale, params->sharpening.edges_tolerance), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + thread1 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussHorizontal_unsigned), b3, b2, buffer1, W, 0, H/2, params->sharpening.radius / scale), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread2 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussHorizontal_unsigned), b3, b2, buffer2, W, H/2, H, params->sharpening.radius / scale), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + thread1 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussVertical_unsigned), b2, b2, buffer1, H, 0, W/2, params->sharpening.radius / scale), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread2 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussVertical_unsigned), b2, b2, buffer2, H, W/2, W, params->sharpening.radius / scale), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else { + bilateral_unsigned (lab->L, (unsigned short**)b2, b3, dim1, params->sharpening.edges_radius / scale, params->sharpening.edges_tolerance); + bilateral_unsigned (lab->L, (unsigned short**)b2, b3, dim2, params->sharpening.edges_radius / scale, params->sharpening.edges_tolerance); + gaussHorizontal_unsigned (b2, b2, buffer1, W, 0, H, params->sharpening.radius / scale); + gaussVertical_unsigned (b2, b2, buffer1, H, 0, W, params->sharpening.radius / scale); + } + + delete buffer1; + delete buffer2; + } + unsigned short** base = lab->L; + if (params->sharpening.edgesonly) + base = b3; + + if (params->sharpening.halocontrol==false) { + for (int i=0; iparams->sharpening.threshold) { + int val = lab->L[i][j] + params->sharpening.amount * diff / 100; + lab->L[i][j] = CLIP(val); + } + } + } + else { + if (settings->dualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::sharpenHaloCtrl), lab, params, b2, base, W, 2, H/2), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::sharpenHaloCtrl), lab, params, b2, base, W, H/2, H-2), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else + sharpenHaloCtrl (lab, params, b2, base, W, 2, H-2); + } + + if (params->sharpening.edgesonly) { + for (int i=0; isharpening.halocontrol_amount); + unsigned short** nL = base; + for (int i=row_from; i params->sharpening.threshold) { + // compute maximum/minimum in a delta environment + np1 = 2*(nL[i-2][j] + nL[i-2][j+1] + nL[i-2][j+2] + nL[i-1][j] + nL[i-1][j+1] + nL[i-1][j+2] + nL[i][j] + nL[i][j+1] + nL[i][j+2]) / 27 + nL[i-1][j+1] / 3; + np2 = 2*(nL[i-1][j] + nL[i-1][j+1] + nL[i-1][j+2] + nL[i][j] + nL[i][j+1] + nL[i][j+2] + nL[i+1][j] + nL[i+1][j+1] + nL[i+1][j+2]) / 27 + nL[i][j+1] / 3; + np3 = 2*(nL[i][j] + nL[i][j+1] + nL[i][j+2] + nL[i+1][j] + nL[i+1][j+1] + nL[i+1][j+2] + nL[i+2][j] + nL[i+2][j+1] + nL[i+2][j+2]) / 27 + nL[i+1][j+1] / 3; + MINMAX3(np1,np2,np3,maxn,minn); + MAX3(max1,max2,maxn,max); + MIN3(min1,min2,minn,min); + max1 = max2; max2 = maxn; + min1 = min2; min2 = minn; + if (max < lab->L[i][j]) + max = lab->L[i][j]; + if (min > lab->L[i][j]) + min = lab->L[i][j]; + int val = lab->L[i][j] + params->sharpening.amount * diff / 100; + int newL = CLIP(val); + // applying halo control + if (newL > max) + newL = max + (newL-max) * scale / 10000; + else if (newLL[i][j] = newL; + } + } + } +} + +void ImProcFunctions::lumadenoise (LabImage* lab, const ProcParams* params, double scale, int** b2) { + +// MyTime t1, t2; +// t1.set (); + + if (params->lumaDenoise.enabled && lab->W>=8 && lab->H>=8) { + + Dim dim1 (lab->W, lab->H, 0, lab->H/2); + Dim dim2 (lab->W, lab->H, lab->H/2, lab->H); + + if (settings->dualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(bilateral_unsigned), lab->L, lab->L, (unsigned short**)b2, dim1, params->lumaDenoise.radius / scale, params->lumaDenoise.edgetolerance), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(bilateral_unsigned), lab->L, lab->L, (unsigned short**)b2, dim2, params->lumaDenoise.radius / scale, params->lumaDenoise.edgetolerance), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else { + bilateral_unsigned (lab->L, lab->L, (unsigned short**)b2, dim1, params->lumaDenoise.radius / scale, params->lumaDenoise.edgetolerance); + bilateral_unsigned (lab->L, lab->L, (unsigned short**)b2, dim2, params->lumaDenoise.radius / scale, params->lumaDenoise.edgetolerance); + } + } +// t2.set (); +// printf ("Luminance denoising time = %d\n", t2.etime (t1)); +} + +void ImProcFunctions::colordenoise (LabImage* lab, const ProcParams* params, double scale, int** b2) { + + if (params->colorDenoise.enabled && lab->W>=8 && lab->H>=8) { + +/* if (params->colorDenoise.edgesensitive) { + + short** buffer1 = (short**)b2; + short** buffer2 = new short*[lab->H]; + for (int i=0; iH; i++) + buffer2[i] = buffer1[i]+lab->W; + Dim dim (lab->W, lab->H, 0, lab->H); + if (settings->dualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(bilateral_signed), lab->a, lab->a, buffer1, dim, params->colorDenoise.radius / scale, params->colorDenoise.edgetolerance), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(bilateral_signed), lab->b, lab->b, buffer2, dim, params->colorDenoise.radius / scale, params->colorDenoise.edgetolerance), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else { + bilateral_signed (lab->a, lab->a, buffer1, dim, params->colorDenoise.radius / scale, params->colorDenoise.edgetolerance); + bilateral_signed (lab->b, lab->b, buffer1, dim, params->colorDenoise.radius / scale, params->colorDenoise.edgetolerance); + } + delete [] buffer2; + } + else { +*/ + AlignedBuffer* buffer1 = new AlignedBuffer (MAX(lab->W,lab->H)*5); + AlignedBuffer* buffer2 = new AlignedBuffer (MAX(lab->W,lab->H)*5); + + if (settings->dualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussHorizontal_signed), lab->a, lab->a, buffer1, lab->W, 0, lab->H, params->colorDenoise.amount / 10.0 / scale), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussHorizontal_signed), lab->b, lab->b, buffer2, lab->W, 0, lab->H, params->colorDenoise.amount / 10.0 / scale), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + thread1 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussVertical_signed), lab->a, lab->a, buffer1, lab->H, 0, lab->W, params->colorDenoise.amount / 10.0 / scale), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread2 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussVertical_signed), lab->b, lab->b, buffer2, lab->H, 0, lab->W, params->colorDenoise.amount / 10.0 / scale), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else { + gaussHorizontal_signed (lab->a, lab->a, buffer1, lab->W, 0, lab->H, params->colorDenoise.amount / 10.0 / scale); + gaussHorizontal_signed (lab->b, lab->b, buffer1, lab->W, 0, lab->H, params->colorDenoise.amount / 10.0 / scale); + gaussVertical_signed (lab->a, lab->a, buffer1, lab->H, 0, lab->W, params->colorDenoise.amount / 10.0 / scale); + gaussVertical_signed (lab->b, lab->b, buffer1, lab->H, 0, lab->W, params->colorDenoise.amount / 10.0 / scale); + } + delete buffer1; + delete buffer2; +// } + } +} + +void ImProcFunctions::vignetting_ (Image16* original, Image16* transformed, const ProcParams* params, STemp sizes, int row_from, int row_to) { + + int oW = sizes.oW; + int oH = sizes.oH; + int cx = sizes.cx; + int cy = sizes.cy; + + double w2 = (double) oW / 2.0 - 0.5; + double h2 = (double) oH / 2.0 - 0.5; + + double maxRadius = sqrt( (double)( oW*oW + oH*oH ) ) / 2; + + double v = 1.0 - params->vignetting.amount * 3.0 / 400.0; + double b = 1.0 + params->vignetting.radius * 7.0 / 100.0; + + double mul = (1.0-v) / tanh(b); + + int val; + for (int y=row_from; ywidth; x++) { + double x_d = (double) (x + cx) - w2 ; + double r = sqrt(x_d*x_d + y_d*y_d); + double vign = v + mul * tanh (b*(maxRadius-r) / maxRadius); + val = original->r[y][x] / vign; + transformed->r[y][x] = CLIP(val); + val = original->g[y][x] / vign; + transformed->g[y][x] = CLIP(val); + val = original->b[y][x] / vign; + transformed->b[y][x] = CLIP(val); + } + } +} + +void ImProcFunctions::vignetting (Image16* original, Image16* transformed, const ProcParams* params, int cx, int cy, int oW, int oH) { + + STemp sizes; + sizes.cx = cx; + sizes.cy = cy; + sizes.oW = oW; + sizes.oH = oH; + + if (settings->dualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::vignetting_), original, transformed, params, sizes, 0, transformed->height/2), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::vignetting_), original, transformed, params, sizes, transformed->height/2, transformed->height), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else + vignetting_ (original, transformed, params, sizes, 0, transformed->height); +} + +#include "cubint.cc" +void ImProcFunctions::transform_ (Image16* original, Image16* transformed, const ProcParams* params, STemp sizes, int row_from, int row_to) { + + int oW = sizes.oW; + int oH = sizes.oH; + int cx = sizes.cx; + int cy = sizes.cy; + int sx = sizes.sx; + int sy = sizes.sy; + + double w2 = (double) oW / 2.0 - 0.5; + double h2 = (double) oH / 2.0 - 0.5; + + double cost = cos(params->rotate.degree * 3.14/180.0); + double sint = sin(params->rotate.degree * 3.14/180.0); + + double max_x = (double) (sx + original->width - 1); + double max_y = (double) (sy + original->height - 1); + double min_x = (double) sx; + double min_y = (double) sy; + + const int n2 = 2; + const int n = 4; + + int mix = original->width - 1; // maximum x-index src + int miy = original->height - 1;// maximum y-index src + int mix2 = mix +1 - n; + int miy2 = miy +1 - n; + + double scale = (oW>oH) ? (double)oW / 2.0 : (double)oH / 2.0 ; + double radius = sqrt( (double)( oW*oW + oH*oH ) ); + radius /= (oWdistortion.amount; + + double d = 1.0 - a; + + // magnify image to keep size + double rotmagn = 1.0; + if (params->rotate.fill) { + double beta = atan((double)MIN(oH,oW)/MAX(oW,oH)); + rotmagn = sin(beta) / sin(fabs(params->rotate.degree) * 3.14/180.0 + beta); + } + // 1. check upper and lower border + double d1 = rotmagn - a*h2/scale; + double d2 = rotmagn - a*w2/scale; + double d3 = rotmagn - a*sqrt(h2*h2+w2*w2) / scale; + d = MIN(d,MIN(d1,MIN(d2,d3))); + + // auxilary variables for vignetting + double maxRadius = sqrt( (double)( oW*oW + oH*oH ) ) / 2 / scale; + + double v = 1.0 - params->vignetting.amount * 3.0 / 400.0; + double b = 1.0 + params->vignetting.radius * 7.0 / 100.0; + + double mul = (1.0-v) / tanh(b); + + // main cycle + double eps = 1e-10; + bool calc_r=( (fabs(a)>eps) || (fabs(1.0-v)>eps) ); + bool do_vign = (fabs(1.0-v)>eps); + + for (int y=row_from; ywidth; x++) { + double x_d = (double) (x + cx) - w2 ; + + double r=0.0; + double s = d;//10000.0; + if (calc_r) + { + r=(sqrt(x_d*x_d + y_d*y_d)) / scale; + if (r= max_x) || (Dy >= max_y) || (Dx < min_x) || (Dy < min_y)); + + // Convert only valid pixels + if (valid) { + // Extract integer and fractions of source screen coordinates + int xc = (int) (Dx); Dx -= (double)xc; + int yc = (int) (Dy); Dy -= (double)yc; + int ys = yc +1 - n2 - sy; // smallest y-index used for interpolation + int xs = xc +1 - n2 - sx; // smallest x-index used for interpolation + + double vignmul = 1.0; + if (do_vign) vignmul /= (v + mul * tanh (b*(maxRadius-s*r) / maxRadius)); + + if (ys >= 0 && ys <= miy2 && xs >= 0 && xs <= mix2) // all interpolation pixels inside image + cubint (original, xs, ys, Dx, Dy, &(transformed->r[y][x]), &(transformed->g[y][x]), &(transformed->b[y][x]), vignmul); + else { // edge pixels + int y1 = (yc>0) ? yc : 0; + if (y1>miy) y1 = miy; + int y2 = (yc0) ? xc : 0; + if (x1>mix) x1 = mix; + int x2 = (xcr[y1][x1]*(1.0-Dx)*(1.0-Dy) + original->r[y1][x2]*Dx*(1.0-Dy) + original->r[y2][x1]*(1.0-Dx)*Dy + original->r[y2][x2]*Dx*Dy); + int g = vignmul*(original->g[y1][x1]*(1.0-Dx)*(1.0-Dy) + original->g[y1][x2]*Dx*(1.0-Dy) + original->g[y2][x1]*(1.0-Dx)*Dy + original->g[y2][x2]*Dx*Dy); + int b = vignmul*(original->b[y1][x1]*(1.0-Dx)*(1.0-Dy) + original->b[y1][x2]*Dx*(1.0-Dy) + original->b[y2][x1]*(1.0-Dx)*Dy + original->b[y2][x2]*Dx*Dy); + transformed->r[y][x] = CLIP(r); + transformed->g[y][x] = CLIP(g); + transformed->b[y][x] = CLIP(b); + } + } + else { + // not valid (source pixel x,y not inside source image, etc.) + transformed->r[y][x] = 0; + transformed->g[y][x] = 0; + transformed->b[y][x] = 0; + } + } + } +} + +void ImProcFunctions::simpltransform_ (Image16* original, Image16* transformed, const ProcParams* params, STemp sizes, int row_from, int row_to) { + + int oW = sizes.oW; + int oH = sizes.oH; + int cx = sizes.cx; + int cy = sizes.cy; + int sx = sizes.sx; + int sy = sizes.sy; + + double w2 = (double) oW / 2.0 - 0.5; + double h2 = (double) oH / 2.0 - 0.5; + + double cost = cos(params->rotate.degree * 3.14/180.0); + double sint = sin(params->rotate.degree * 3.14/180.0); + + double max_x = (double) (sx + original->width - 1); + double max_y = (double) (sy + original->height - 1); + double min_x = (double) sx; + double min_y = (double) sy; + + const int n2 = 2; + const int n = 2; + + int mix = original->width - 1; // maximum x-index src + int miy = original->height - 1;// maximum y-index src + int mix2 = mix +1 - n; + int miy2 = miy +1 - n; + + double scale = (oW>oH) ? (double)oW / 2.0 : (double)oH / 2.0 ; + double radius = sqrt( (double)( oW*oW + oH*oH ) ); + radius /= (oWdistortion.amount; + + double d = 1.0 - a; + + + // magnify image to keep size + double rotmagn = 1.0; + if (params->rotate.fill) { + double beta = atan((double)MIN(oH,oW)/MAX(oW,oH)); + rotmagn = sin(beta) / sin(fabs(params->rotate.degree) * 3.14/180.0 + beta); + } + // 1. check upper and lower border + double d1r = rotmagn - a*h2/scale - params->cacorrection.red; + double d2r = rotmagn - a*w2/scale - params->cacorrection.red; + double d3r = rotmagn - a*sqrt(h2*h2+w2*w2) / scale - params->cacorrection.red; + double dr = MIN(d,MIN(d1r,MIN(d2r,d3r))); + double d1b = rotmagn - a*h2/scale - params->cacorrection.blue; + double d2b = rotmagn - a*w2/scale - params->cacorrection.blue; + double d3b = rotmagn - a*sqrt(h2*h2+w2*w2) / scale - params->cacorrection.blue; + double db = MIN(d,MIN(d1b,MIN(d2b,d3b))); + double d1g = rotmagn - a*h2/scale; + double d2g = rotmagn - a*w2/scale; + double d3g = rotmagn - a*sqrt(h2*h2+w2*w2) / scale; + double dg = MIN(d,MIN(d1g,MIN(d2g,d3g))); + + d = MIN(dg,MIN(dr,db)); + + // auxilary variables for vignetting + double maxRadius = sqrt( (double)( oW*oW + oH*oH ) ) / 2 / scale; + + double v = 1.0 - params->vignetting.amount * 3.0 / 400.0; + double b = 1.0 + params->vignetting.radius * 7.0 / 100.0; + + double mul = (1.0-v) / tanh(b); + + // main cycle + double eps = 1e-10; + bool calc_r=( (fabs(a)>eps) || (fabs(1.0-v)>eps) ); + bool do_vign = (fabs(1.0-v)>eps); + + for (int y=row_from; ywidth; x++) { + double x_d = (double) (x + cx) - w2 ; + + double r=0.0; + double s = d;//10000.0; + if (calc_r) + { + r=(sqrt(x_d*x_d + y_d*y_d)) / scale; + if (r= max_x) || (Dy >= max_y) || (Dx < min_x) || (Dy < min_y)); + + // Convert only valid pixels + if (valid) { + // Extract integer and fractions of source screen coordinates + int xc = (int) (Dx); Dx -= (double)xc; + int yc = (int) (Dy); Dy -= (double)yc; + int ys = yc +1 - n2 - sy; // smallest y-index used for interpolation + int xs = xc +1 - n2 - sx; // smallest x-index used for interpolation + + double vignmul = 1.0; + if (do_vign) vignmul /= (v + mul * tanh (b*(maxRadius-s*r) / maxRadius)); + + if (ys >= 0 && ys <= miy2 && xs >= 0 && xs <= mix2 && yc < miy-1) { // all interpolation pixels inside image + + int r = vignmul*(original->r[yc][xc]*(1.0-Dx)*(1.0-Dy) + original->r[yc][xc+1]*Dx*(1.0-Dy) + original->r[yc+1][xc]*(1.0-Dx)*Dy + original->r[yc+1][xc+1]*Dx*Dy); + int g = vignmul*(original->g[yc][xc]*(1.0-Dx)*(1.0-Dy) + original->g[yc][xc+1]*Dx*(1.0-Dy) + original->g[yc+1][xc]*(1.0-Dx)*Dy + original->g[yc+1][xc+1]*Dx*Dy); + int b = vignmul*(original->b[yc][xc]*(1.0-Dx)*(1.0-Dy) + original->b[yc][xc+1]*Dx*(1.0-Dy) + original->b[yc+1][xc]*(1.0-Dx)*Dy + original->b[yc+1][xc+1]*Dx*Dy); + transformed->r[y][x] = CLIP(r); + transformed->g[y][x] = CLIP(g); + transformed->b[y][x] = CLIP(b); + } + else { // edge pixels + int y1 = (yc>0) ? yc : 0; + if (y1>miy) y1 = miy; + int y2 = (yc0) ? xc : 0; + if (x1>mix) x1 = mix; + int x2 = (xcr[y1][x1]*(1.0-Dx)*(1.0-Dy) + original->r[y1][x2]*Dx*(1.0-Dy) + original->r[y2][x1]*(1.0-Dx)*Dy + original->r[y2][x2]*Dx*Dy); + int g = vignmul*(original->g[y1][x1]*(1.0-Dx)*(1.0-Dy) + original->g[y1][x2]*Dx*(1.0-Dy) + original->g[y2][x1]*(1.0-Dx)*Dy + original->g[y2][x2]*Dx*Dy); + int b = vignmul*(original->b[y1][x1]*(1.0-Dx)*(1.0-Dy) + original->b[y1][x2]*Dx*(1.0-Dy) + original->b[y2][x1]*(1.0-Dx)*Dy + original->b[y2][x2]*Dx*Dy); + transformed->r[y][x] = CLIP(r); + transformed->g[y][x] = CLIP(g); + transformed->b[y][x] = CLIP(b); + } + } + else { + // not valid (source pixel x,y not inside source image, etc.) + transformed->r[y][x] = 0; + transformed->g[y][x] = 0; + transformed->b[y][x] = 0; + } + } + } +} + + +#include "cubintch.cc" +void ImProcFunctions::transform_sep_ (Image16* original, Image16* transformed, const ProcParams* params, STemp sizes, int row_from, int row_to) { + + int oW = sizes.oW; + int oH = sizes.oH; + int cx = sizes.cx; + int cy = sizes.cy; + int sx = sizes.sx; + int sy = sizes.sy; + + double w2 = (double) oW / 2.0 - 0.5; + double h2 = (double) oH / 2.0 - 0.5; + + double cost = cos(params->rotate.degree * 3.14/180.0); + double sint = sin(params->rotate.degree * 3.14/180.0); + + double max_x = (double) (sx + original->width - 1); + double max_y = (double) (sy + original->height - 1); + double min_x = (double) sx; + double min_y = (double) sy; + + const int n2 = 2; + const int n = 4; + + int mix = original->width - 1; // maximum x-index src + int miy = original->height - 1;// maximum y-index src + int mix2 = mix +1 - n; + int miy2 = miy +1 - n; + + double scale = (oW>oH) ? (double)oW / 2.0 : (double)oH / 2.0 ; + double radius = sqrt( (double)( oW*oW + oH*oH ) ); + radius /= (oWdistortion.amount; + double d = 1.0 - a; + + double cdist[3]; + cdist[0] = params->cacorrection.red; + cdist[1] = 0.0; + cdist[2] = params->cacorrection.blue; + + // magnify image to keep size + double rotmagn = 1.0; + if (params->rotate.fill) { + double beta = atan((double)MIN(oH,oW)/MAX(oW,oH)); + rotmagn = sin(beta) / sin(fabs(params->rotate.degree) * 3.14/180.0 + beta); + } + // 1. check upper and lower border + double d1r = rotmagn - a*h2/scale - params->cacorrection.red; + double d2r = rotmagn - a*w2/scale - params->cacorrection.red; + double d3r = rotmagn - a*sqrt(h2*h2+w2*w2) / scale - params->cacorrection.red; + double dr = MIN(d,MIN(d1r,MIN(d2r,d3r))); + double d1b = rotmagn - a*h2/scale - params->cacorrection.blue; + double d2b = rotmagn - a*w2/scale - params->cacorrection.blue; + double d3b = rotmagn - a*sqrt(h2*h2+w2*w2) / scale - params->cacorrection.blue; + double db = MIN(d,MIN(d1b,MIN(d2b,d3b))); + double d1g = rotmagn - a*h2/scale; + double d2g = rotmagn - a*w2/scale; + double d3g = rotmagn - a*sqrt(h2*h2+w2*w2) / scale; + double dg = MIN(d,MIN(d1g,MIN(d2g,d3g))); + + d = MIN(dg,MIN(dr,db)); + + unsigned short** chorig[3]; + chorig[0] = original->r; + chorig[1] = original->g; + chorig[2] = original->b; + + unsigned short** chtrans[3]; + chtrans[0] = transformed->r; + chtrans[1] = transformed->g; + chtrans[2] = transformed->b; + + + // auxilary variables for vignetting + double maxRadius = sqrt( (double)( oW*oW + oH*oH ) ) / 2 / scale; + + double v = 1.0 - params->vignetting.amount * 3.0 / 400.0; + double b = 1.0 + params->vignetting.radius * 7.0 / 100.0; + + double mul = (1.0-v) / tanh(b); + + // main cycle + double eps = 1e-10; + for (int y=row_from; ywidth; x++) { + double x_d = (double) (x + cx) - w2 ; + + double r = (sqrt(x_d*x_d + y_d*y_d)) / scale; + double s = 10000.0; + if (r= max_x) || (Dy >= max_y) || (Dx < min_x) || (Dy < min_y)); + + // Convert only valid pixels + if (valid) { + // Extract integer and fractions of source screen coordinates + int xc = (int) (Dx); Dx -= (double)xc; + int yc = (int) (Dy); Dy -= (double)yc; + int ys = yc +1 - n2 - sy; // smallest y-index used for interpolation + int xs = xc +1 - n2 - sx; // smallest x-index used for interpolation + + if (ys >= 0 && ys <= miy2 && xs >= 0 && xs <= mix2) // all interpolation pixels inside image + cubintch (chorig[c], xs, ys, Dx, Dy, &(chtrans[c][y][x]), vignmul); + else {// edge pixels, linear interpolation + int y1 = (yc>0) ? yc : 0; + if (y1>miy) y1 = miy; + int y2 = (yc0) ? xc : 0; + if (x1>mix) x1 = mix; + int x2 = (xc &src, std::vector &red, std::vector &green, std::vector &blue) { + + bool clipresize = true; + bool clipped = false; + + red.clear (); + green.clear (); + blue.clear (); + bool needstransform = 0;// fabs(params->rotate.degree)>1e-15 || fabs(params->distortion.amount)>1e-15 || fabs(params->cacorrection.red)>1e-15 || fabs(params->cacorrection.blue)>1e-15; + if (!needstransform) { + if (clipresize) { + // Apply resizing + if (fabs(params->resize.scale-1.0)>=1e-7) { + for (int i=0; iresize.scale, src[i].y / params->resize.scale)); + green.push_back (Coord2D (src[i].x / params->resize.scale, src[i].y / params->resize.scale)); + blue.push_back (Coord2D (src[i].x / params->resize.scale, src[i].y / params->resize.scale)); + } + for (int i=0; iresize.scale; + double rH = H*params->resize.scale; + double w2 = (double) rW / 2.0 - 0.5; + double h2 = (double) rH / 2.0 - 0.5; + double cost = cos(params->rotate.degree * 3.14/180.0); + double sint = sin(params->rotate.degree * 3.14/180.0); + + double scale = (rW>rH) ? rW / 2.0 : rH / 2.0 ; + double radius = sqrt ((double)(rW*rW + rH*rH )); + radius /= (rWdistortion.amount; + double d = 1.0 - a; + + // magnify image to keep size + double rotmagn = 1.0; + if (params->rotate.fill) { + double beta = atan(MIN(rH,rW)/MAX(rW,rH)); + rotmagn = sin(beta) / sin(fabs(params->rotate.degree) * 3.14/180.0 + beta); + } + if (params->cacorrection.red==0 && params->cacorrection.blue==0) { + // 1. check upper and lower border + double d1 = rotmagn - a*h2/scale; + double d2 = rotmagn - a*w2/scale; + double d3 = rotmagn - a*sqrt(h2*h2+w2*w2) / scale; + d = MIN(d,MIN(d1,MIN(d2,d3))); + + for (int i=0; icacorrection.red; + cdist[1] = 0.0; + cdist[2] = params->cacorrection.blue; + + // 1. check upper and lower border + double d1r = rotmagn - a*h2/scale - params->cacorrection.red; + double d2r = rotmagn - a*w2/scale - params->cacorrection.red; + double d3r = rotmagn - a*sqrt(h2*h2+w2*w2) / scale - params->cacorrection.red; + double dr = MIN(d,MIN(d1r,MIN(d2r,d3r))); + double d1b = rotmagn - a*h2/scale - params->cacorrection.blue; + double d2b = rotmagn - a*w2/scale - params->cacorrection.blue; + double d3b = rotmagn - a*sqrt(h2*h2+w2*w2) / scale - params->cacorrection.blue; + double db = MIN(d,MIN(d1b,MIN(d2b,d3b))); + double d1g = rotmagn - a*h2/scale; + double d2g = rotmagn - a*w2/scale; + double d3g = rotmagn - a*sqrt(h2*h2+w2*w2) / scale; + double dg = MIN(d,MIN(d1g,MIN(d2g,d3g))); + + d = MIN(dg,MIN(dr,db)); + + for (int i=0; iresize.scale-1.0)>=1e-7) { + for (int i=0; iresize.scale; + red[i].y /= params->resize.scale; + green[i].x /= params->resize.scale; + green[i].y /= params->resize.scale; + blue[i].x /= params->resize.scale; + blue[i].y /= params->resize.scale; + } + } + for (int i=0; i corners (8); + corners[0].set (x1, y1); + corners[1].set (x1, y2); + corners[2].set (x2, y2); + corners[3].set (x2, y1); + corners[4].set ((x1+x2)/2, y1); + corners[5].set ((x1+x2)/2, y2); + corners[6].set (x1, (y1+y2)/2); + corners[7].set (x2, (y1+y2)/2); + + std::vector r, g, b; + + bool result = transCoord (params, W, H, corners, r, g, b); + + std::vector transCorners; + transCorners.insert (transCorners.end(), r.begin(), r.end()); + transCorners.insert (transCorners.end(), g.begin(), g.end()); + transCorners.insert (transCorners.end(), b.begin(), b.end()); + + double x1d = transCorners[0].x; + for (int i=1; ix2d) + x2d = transCorners[i].x; + int x2v = (int)ceil(x2d); + + double y2d = transCorners[0].y; + for (int i=1; iy2d) + y2d = transCorners[i].y; + int y2v = (int)ceil(y2d); + + xv = x1v; + yv = y1v; + wv = x2v - x1v + 1; + hv = y2v - y1v + 1; + + return result; +} + +void ImProcFunctions::transform (Image16* original, Image16* transformed, const ProcParams* params, int cx, int cy, int sx, int sy, int oW, int oH) { + + STemp sizes; + sizes.cx = 0;//cx; + sizes.cy = 0;//cy; + sizes.oW = oW; + sizes.oH = oH; + sizes.sx = 0;//sx; + sizes.sy = 0;//sy; + + if (params->cacorrection.red==0 && params->cacorrection.blue==0) { + if (settings->dualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::transform_), original, transformed, params, sizes, 0, transformed->height/2), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::transform_), original, transformed, params, sizes, transformed->height/2, transformed->height), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else + transform_ (original, transformed, params, sizes, 0, transformed->height); + } + else { + if (settings->dualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::transform_sep_), original, transformed, params, sizes, 0, transformed->height/2), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::transform_sep_), original, transformed, params, sizes, transformed->height/2, transformed->height), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else + transform_sep_ (original, transformed, params, sizes, 0, transformed->height); + } +} + +void ImProcFunctions::simpltransform (Image16* original, Image16* transformed, const ProcParams* params, int cx, int cy, int sx, int sy, int oW, int oH) { + + STemp sizes; + sizes.cx = 0;//cx; + sizes.cy = 0;//cy; + sizes.oW = oW; + sizes.oH = oH; + sizes.sx = 0;//sx; + sizes.sy = 0;//sy; + + if (settings->dualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::simpltransform_), original, transformed, params, sizes, 0, transformed->height/2), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::simpltransform_), original, transformed, params, sizes, transformed->height/2, transformed->height), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else + simpltransform_ (original, transformed, params, sizes, 0, transformed->height); +} +/*void ImProcFunctions::transform (Image16* original, Image16* transformed, const ProcParams* params, int ox, int oy) { + + if (!transformed) + return; + + int oW = W, oH = H, tW = W, tH = H; + + double w2 = (double) tW / 2.0 - 0.5; + double h2 = (double) tH / 2.0 - 0.5; + double sw2 = (double) oW / 2.0 - 0.5; + double sh2 = (double) oH / 2.0 - 0.5; + + double cost = cos(params->rotate_fine * 3.14/180.0); + double sint = sin(params->rotate_fine * 3.14/180.0); + + double max_x = (double) oW; + double max_y = (double) oH; + double min_x = 0.0; + double min_y = 0.0; + + const int n2 = 2; + const int n = 4; + + int mix = oW - 1; // maximum x-index src + int miy = oH - 1;// maximum y-index src + int mix2 = mix +1 - n; + int miy2 = miy +1 - n; + + double scale = (tW>tH) ? (double)tW / 2.0 : (double)tH / 2.0 ; + double radius = sqrt( (double)( tW*tW + tH*tH ) ); + radius /= (tWlens_distortion; + + for (int y=0; yheight; y++) { + double y_d = (double) y + oy - h2 ; + + for (int x=0; xwidth; x++) { + double x_d = (double) x + ox - w2 ; + + double r = (sqrt(x_d*x_d + y_d*y_d)) / scale; + double s = 10000.0; + if (r= max_x) || (Dy >= max_y) || (Dx < min_x) || (Dy < min_y)); + + // Convert only valid pixels + if (valid) { + // Extract integer and fractions of source screen coordinates + int xc = (int) floor (Dx) ; Dx -= (double)xc; + int yc = (int) floor (Dy) ; Dy -= (double)yc; + int ys = yc +1 - n2 ; // smallest y-index used for interpolation + int xs = xc +1 - n2 ; // smallest x-index used for interpolation + + unsigned short sr[2][2], sg[2][2], sb[2][2]; + + if (ys >= 0 && ys <= miy2 && xs >= 0 && xs <= mix2) // all interpolation pixels inside image + cubint (original, xs, ys, Dx, Dy, &(transformed->r[y][x]), &(transformed->g[y][x]), &(transformed->b[y][x])); + else { // edge pixels + transformed->r[y][x] = 0; + transformed->g[y][x] = 0; + transformed->b[y][x] = 0; + } + } + else { + // not valid (source pixel x,y not inside source image, etc.) + transformed->r[y][x] = 0; + transformed->g[y][x] = 0; + transformed->b[y][x] = 0; + } + } + } +}*/ + +void ImProcFunctions::lab2rgb (LabImage* lab, Image8* image) { + + if (settings->dualThreadEnabled) { + + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::lab2rgb_), lab, image, 0, lab->H/2), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::lab2rgb_), lab, image, lab->H/2, lab->H), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else + lab2rgb_ (lab, image, 0, lab->H); +} + +void ImProcFunctions::lab2rgb_ (LabImage* lab, Image8* image, int row_from, int row_to) { + + int X, Y, Z; + unsigned short** nL = lab->L; + short** na = lab->a; + short** nb = lab->b; + int tW = lab->W; + int ix = row_from*tW*3; + + if (monitorTransform) { + short* buffer = new short [3*tW]; + for (int i=row_from; idata + ix, tW); + ix += 3*tW; + } + delete [] buffer; + } + else { + for (int i=row_from; i> 13; + int G = (-8017*X+15697*Y+274*Z) >> 13; + int B = (590*X-1877*Y+11517*Z) >> 13; + + /* copy RGB */ + image->data[ix++] = gamma2curve[CLIP(R)] >> 8; + image->data[ix++] = gamma2curve[CLIP(G)] >> 8; + image->data[ix++] = gamma2curve[CLIP(B)] >> 8; + } + } + } +} + +Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile) { + + int tW = lab->W; + int tH = lab->H; + + if (cx<0) cx = 0; + if (cy<0) cy = 0; + if (cx+cw>tW) cw = tW-cx; + if (cy+ch>tH) ch = tH-cy; + + Image8* image = new Image8 (cw, ch); + + int X, Y, Z; + int ix = 0; + unsigned short** nL = lab->L; + short** na = lab->a; + short** nb = lab->b; + + cmsHPROFILE oprof = iccStore.getProfile (profile); + + if (oprof) { + cmsHPROFILE iprof = iccStore.getXYZProfile (); + lcmsMutex->lock (); + cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_8, settings->colorimetricIntent, 0); + lcmsMutex->unlock (); + short* buffer = new short [3*cw]; + for (int i=cy; idata + ix, cw); + ix += 3*cw; + } + delete [] buffer; + cmsDeleteTransform(hTransform); + } + else { + for (int i=cy; i> 13; + int G = (-8017*X+15697*Y+274*Z) >> 13; + int B = (590*X-1877*Y+11517*Z) >> 13; + + image->data[ix++] = gamma2curve[CLIP(R)] >> 8; + image->data[ix++] = gamma2curve[CLIP(G)] >> 8; + image->data[ix++] = gamma2curve[CLIP(B)] >> 8; + } + } + } + return image; +} + +Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile) { + + int tW = lab->W; + int tH = lab->H; + + if (cx<0) cx = 0; + if (cy<0) cy = 0; + if (cx+cw>tW) cw = tW-cx; + if (cy+ch>tH) ch = tH-cy; + + Image16* image = new Image16 (cw, ch); + + int X, Y, Z; + int ix = 0; + unsigned short** nL = lab->L; + short** na = lab->a; + short** nb = lab->b; + + cmsHPROFILE oprof = iccStore.getProfile (profile); + + if (oprof) { + for (int i=cy; ir[i-cy]; + short* ya = (short*)image->g[i-cy]; + short* za = (short*)image->b[i-cy]; + for (register int j=cx; jlock (); + cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16_PLANAR, oprof, TYPE_RGB_16_PLANAR, settings->colorimetricIntent, 0); + lcmsMutex->unlock (); + cmsDoTransform (hTransform, image->data, image->data, image->planestride/2); + cmsDeleteTransform(hTransform); + } + else { + for (int i=cy; i> 13; + int G = (-8017*X+15697*Y+274*Z) >> 13; + int B = (590*X-1877*Y+11517*Z) >> 13; + + image->r[i-cy][j-cx] = gamma2curve[CLIP(R)]; + image->g[i-cy][j-cx] = gamma2curve[CLIP(G)]; + image->b[i-cy][j-cx] = gamma2curve[CLIP(B)]; + } + } + } + return image; +} + +void ImProcFunctions::resize (Image16* src, Image16* dst, ResizeParams params) { + + if (settings->dualThreadEnabled) { + + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::resize_), src, dst, params, 0, dst->height/2), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ImProcFunctions::resize_), src, dst, params, dst->height/2, dst->height), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else + resize_ (src, dst, params, 0, dst->height); +} + +void ImProcFunctions::resize_ (Image16* src, Image16* dst, ResizeParams params, int row_from, int row_to) { + if(params.method == "Downscale (Better)") { + // small-scale algorithm by Ilia + // provides much better quality on small scales + // calculates mean value over source pixels which current destination pixel covers + // works only for scales < 1 + // for scales ~1 it is analogous to bilinear + // possibly, for even less scale factors (< 0.2 possibly) boundary pixels are not needed, omitting them can give a speedup + // this algorithm is much slower on small factors than others, because it uses all pixels of the SOURCE image + // Ilia Popov ilia_popov@rambler.ru 2010 + + double delta = 1.0 / params.scale; + double k = params.scale * params.scale; + + for(int i = row_from; i < row_to; i++) { + // top and bottom boundary coordinates + double y0 = i * delta; + double y1 = (i + 1) * delta; + + int m0 = y0; + m0 = CLIPTO(m0, 0, src->height-1); + + int m1 = y1; + m1 = CLIPTO(m1, 0, src->height-1); + + // weights of boundary pixels + double wy0 = 1.0 - (y0 - m0); + double wy1 = y1 - m1; + + for(int j = 0; j < dst->width; j++) { + // left and right boundary coordinates + double x0 = j * delta; + double x1 = (j + 1) * delta; + + int n0 = x0; + n0 = CLIPTO(n0, 0, src->width-1); + int n1 = x1; + n1 = CLIPTO(n1, 0, src->width-1); + + double wx0 = 1.0 - (x0 - n0); + double wx1 = x1 - n1; + + double r = 0; + double g = 0; + double b = 0; + + // integration + // corners + r += wy0 * wx0 * src->r[m0][n0] + wy0 * wx1 * src->r[m0][n1] + wy1 * wx0 * src->r[m1][n0] + wy1 * wx1 * src->r[m1][n1]; + g += wy0 * wx0 * src->g[m0][n0] + wy0 * wx1 * src->g[m0][n1] + wy1 * wx0 * src->g[m1][n0] + wy1 * wx1 * src->g[m1][n1]; + b += wy0 * wx0 * src->b[m0][n0] + wy0 * wx1 * src->b[m0][n1] + wy1 * wx0 * src->b[m1][n0] + wy1 * wx1 * src->b[m1][n1]; + + // top and bottom boundaries + for(int n = n0 + 1; n < n1; n++) { + r += wy0 * src->r[m0][n] + wy1 * src->r[m1][n]; + g += wy0 * src->g[m0][n] + wy1 * src->g[m1][n]; + b += wy0 * src->b[m0][n] + wy1 * src->b[m1][n]; + } + + // inner rows + for(int m = m0 + 1; m < m1; m++) { + // left and right boundaries + r += wx0 * src->r[m][n0] + wx1 * src->r[m][n1]; + g += wx0 * src->g[m][n0] + wx1 * src->g[m][n1]; + b += wx0 * src->b[m][n0] + wx1 * src->b[m][n1]; + // inner pixels + for(int n = n0 + 1; n < n1; n++) { + r += src->r[m][n]; + g += src->g[m][n]; + b += src->b[m][n]; + } + } + + // overall weight is equal to the DST pixel area in SRC coordinates + r *= k; + g *= k; + b *= k; + + dst->r[i][j] = CLIP((int)r); + dst->g[i][j] = CLIP((int)g); + dst->b[i][j] = CLIP((int)b); + } + } + + return; + } + + if(params.method == "Downscale (Faster)") + { + // faster version of algo above, does not take into account border pixels, + // which are summed with non-unity weights in slow algo. So, no need + // for weights at all + // Ilia Popov ilia_popov@rambler.ru 5.04.2010 + + double delta = 1.0 / params.scale; + + int p = (int) delta; + + // if actually we are doing upscaling, behave like Nearest + if(p == 0) + p = 1; + + int q = p/2; + + // may cause problems on 32-bit systems on extremely small factors. + // In that case change 1024 to smth less + const int divider = 1024; + + // scaling factor after summation + int k = divider / (p * p); + + for(int i = row_from; i < row_to; i++) { + // y coordinate of center of destination pixel + double y = (i + 0.5) * delta; + + int m0 = (int) (y) - q; + m0 = CLIPTO(m0, 0, src->height-1); + + int m1 = m0 + p; + if(m1 > src->height) { + m1 = src->height; + m0 = m1 - p; + } + m1 = CLIPTO(m1, 0, src->height); + + for(int j = 0; j < dst->width; j++) { + // x coordinate of center of destination pixel + double x = (j + 0.5) * delta; + + int n0 = (int) (x) - q; + n0 = CLIPTO(n0, 0, src->width-1); + + int n1 = n0 + p; + if(n1 > src->width) { + n1 = src->width; + n0 = n1 - p; + } + n1 = CLIPTO(n1, 0, src->width); + + int r = 0; + int g = 0; + int b = 0; + + // integration + for(int m = m0; m < m1; m++) { + for(int n = n0; n < n1; n++) { + r += src->r[m][n]; + g += src->g[m][n]; + b += src->b[m][n]; + } + } + + dst->r[i][j] = CLIP( r * k / divider); + dst->g[i][j] = CLIP( g * k / divider); + dst->b[i][j] = CLIP( b * k / divider); + } + } + return; + } + + + if (params.method.substr(0,7)=="Bicubic") { + double Av = -0.5; + if (params.method=="Bicubic (Sharper)") + Av = -0.75; + else if (params.method=="Bicubic (Softer)") + Av = -0.25; + double wx[4], wy[4]; + for (int i=row_from; iwidth; j++) { + double Dx = j / params.scale; + int xc = (int) Dx; Dx -= (double)xc; + int xs = xc - 1; // smallest x-index used for interpolation + if (ys >= 0 && ys height-3 && xs >= 0 && xs <= src->width-3) { + // compute horizontal weights + double t1 = -Av*(Dx-1.0)*Dx; + double t2 = (3.0-2.0*Dx)*Dx*Dx; + wx[3] = t1*Dx; + wx[2] = t1*(Dx-1.0) + t2; + wx[1] = -t1*Dx + 1.0 - t2; + wx[0] = -t1*(Dx-1.0); + // compute weighted sum + int r = 0; + int g = 0; + int b = 0; +/* r = wx[0]*wy[0]*src->r[ys+0][xs+0] + wx[0]*wy[1]*src->r[ys+1][xs+0] + wx[0]*wy[2]*src->r[ys+2][xs+0] + wx[0]*wy[3]*src->r[ys+3][xs+0] + + wx[1]*wy[0]*src->r[ys+0][xs+1] + wx[1]*wy[1]*src->r[ys+1][xs+1] + wx[1]*wy[2]*src->r[ys+2][xs+1] + wx[1]*wy[3]*src->r[ys+3][xs+1] + + wx[2]*wy[0]*src->r[ys+0][xs+2] + wx[2]*wy[1]*src->r[ys+1][xs+1] + wx[2]*wy[2]*src->r[ys+2][xs+2] + wx[2]*wy[3]*src->r[ys+3][xs+2] + + wx[3]*wy[0]*src->r[ys+0][xs+3] + wx[3]*wy[1]*src->r[ys+1][xs+1] + wx[3]*wy[2]*src->r[ys+2][xs+3] + wx[3]*wy[3]*src->r[ys+3][xs+3]; + g = wx[0]*wy[0]*src->g[ys+0][xs+0] + wx[0]*wy[1]*src->g[ys+1][xs+0] + wx[0]*wy[2]*src->g[ys+2][xs+0] + wx[0]*wy[3]*src->g[ys+3][xs+0] + + wx[1]*wy[0]*src->g[ys+0][xs+1] + wx[1]*wy[1]*src->g[ys+1][xs+1] + wx[1]*wy[2]*src->g[ys+2][xs+1] + wx[1]*wy[3]*src->g[ys+3][xs+1] + + wx[2]*wy[0]*src->g[ys+0][xs+2] + wx[2]*wy[1]*src->g[ys+1][xs+1] + wx[2]*wy[2]*src->g[ys+2][xs+2] + wx[2]*wy[3]*src->g[ys+3][xs+2] + + wx[3]*wy[0]*src->g[ys+0][xs+3] + wx[3]*wy[1]*src->g[ys+1][xs+1] + wx[3]*wy[2]*src->g[ys+2][xs+3] + wx[3]*wy[3]*src->g[ys+3][xs+3]; + b = wx[0]*wy[0]*src->b[ys+0][xs+0] + wx[0]*wy[1]*src->b[ys+1][xs+0] + wx[0]*wy[2]*src->b[ys+2][xs+0] + wx[0]*wy[3]*src->b[ys+3][xs+0] + + wx[1]*wy[0]*src->b[ys+0][xs+1] + wx[1]*wy[1]*src->b[ys+1][xs+1] + wx[1]*wy[2]*src->b[ys+2][xs+1] + wx[1]*wy[3]*src->b[ys+3][xs+1] + + wx[2]*wy[0]*src->b[ys+0][xs+2] + wx[2]*wy[1]*src->b[ys+1][xs+1] + wx[2]*wy[2]*src->b[ys+2][xs+2] + wx[2]*wy[3]*src->b[ys+3][xs+2] + + wx[3]*wy[0]*src->b[ys+0][xs+3] + wx[3]*wy[1]*src->b[ys+1][xs+1] + wx[3]*wy[2]*src->b[ys+2][xs+3] + wx[3]*wy[3]*src->b[ys+3][xs+3];*/ + for (int x=0; x<4; x++) + for (int y=0; y<4; y++) { + double w = wx[x]*wy[y]; + r += w*src->r[ys+y][xs+x]; + g += w*src->g[ys+y][xs+x]; + b += w*src->b[ys+y][xs+x]; + } + dst->r[i][j] = CLIP(r); + dst->g[i][j] = CLIP(g); + dst->b[i][j] = CLIP(b); + } + else { + xc = CLIPTO(xc, 0, src->width-1); + yc = CLIPTO(yc, 0, src->height-1); + int nx = xc + 1; + if (nx>=src->width) + nx = xc; + int ny = yc + 1; + if (ny>=src->height) + ny = yc; + dst->r[i][j] = (1-Dx)*(1-Dy)*src->r[yc][xc] + (1-Dx)*Dy*src->r[ny][xc] + Dx*(1-Dy)*src->r[yc][nx] + Dx*Dy*src->r[ny][nx]; + dst->g[i][j] = (1-Dx)*(1-Dy)*src->g[yc][xc] + (1-Dx)*Dy*src->g[ny][xc] + Dx*(1-Dy)*src->g[yc][nx] + Dx*Dy*src->g[ny][nx]; + dst->b[i][j] = (1-Dx)*(1-Dy)*src->b[yc][xc] + (1-Dx)*Dy*src->b[ny][xc] + Dx*(1-Dy)*src->b[yc][nx] + Dx*Dy*src->b[ny][nx]; + } + } + } + } + else if (params.method=="Bilinear") { + for (int i=row_from; iheight-1); + double dy = i/params.scale - sy; + int ny = sy+1; + if (ny>=src->height) + ny = sy; + for (int j=0; jwidth; j++) { + int sx = j/params.scale; + sx = CLIPTO(sx, 0, src->width-1); + double dx = j/params.scale - sx; + int nx = sx+1; + if (nx>=src->width) + nx = sx; + dst->r[i][j] = (1-dx)*(1-dy)*src->r[sy][sx] + (1-dx)*dy*src->r[ny][sx] + dx*(1-dy)*src->r[sy][nx] + dx*dy*src->r[ny][nx]; + dst->g[i][j] = (1-dx)*(1-dy)*src->g[sy][sx] + (1-dx)*dy*src->g[ny][sx] + dx*(1-dy)*src->g[sy][nx] + dx*dy*src->g[ny][nx]; + dst->b[i][j] = (1-dx)*(1-dy)*src->b[sy][sx] + (1-dx)*dy*src->b[ny][sx] + dx*(1-dy)*src->b[sy][nx] + dx*dy*src->b[ny][nx]; + } + } + } + else { + for (int i=row_from; iheight-1); + for (int j=0; jwidth; j++) { + int sx = j/params.scale; + sx = CLIPTO(sx, 0, src->width-1); + dst->r[i][j] = src->r[sy][sx]; + dst->g[i][j] = src->g[sy][sx]; + dst->b[i][j] = src->b[sy][sx]; + } + } + } +} + +void ImProcFunctions::getAutoExp (unsigned int* histogram, int histcompr, double expcomp, double clip, double& br, int& bl) { + + double sum = 0; + for (int i=0; i<65536>>histcompr; i++) + sum += histogram[i]; + + // compute clipping points based on the original histograms (linear, without exp comp.) + int clippable = (int)(sum * clip); + int clipped = 0; + int aw = (65536>>histcompr) - 1; + while (aw>1 && histogram[aw]+clipped <= clippable) { + clipped += histogram[aw]; + aw--; + } + + clipped = 0; + int shc = 0; + while (shc>histcompr; i++) + gavg += histogram[i] * CurveFactory::gamma2((int)(corr*(i< + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _IMPROCFUN_H_ +#define _IMPROCFUN_H_ + +#include +#include +#include +#include +#include + +namespace rtengine { + +using namespace procparams; + +class LabImage { + private: + bool fromImage; + + public: + int W, H; + unsigned short** L; + short** a; + short** b; + + LabImage (int w, int h); + LabImage (Image16* im); + ~LabImage (); +}; + +class ImProcFunctions { + + protected: + struct STemp { + int cx, cy, sx, sy, oW, oH; + }; + cmsHTRANSFORM monitorTransform; + + void transform_ (Image16* original, Image16* transformed, const ProcParams* params, STemp sizes, int row_from, int row_to); + void simpltransform_ (Image16* original, Image16* transformed, const ProcParams* params, STemp sizes, int row_from, int row_to); + void vignetting_ (Image16* original, Image16* transformed, const ProcParams* params, STemp sizes, int row_from, int row_to); + void transform_sep_ (Image16* original, Image16* transformed, const ProcParams* params, STemp sizes, int row_from, int row_to); + void rgbProc_ (Image16* working, LabImage* lab, const ProcParams* params, int* tonecurve, SHMap* shmap, int row_from, int row_to); + void lab2rgb_ (LabImage* lab, Image8* image, int row_from, int row_to); + void colorCurve_ (LabImage* lold, LabImage* lnew, const ProcParams* params, int row_from, int row_to, double* cmultiplier); + void sharpenHaloCtrl (LabImage* lab, const ProcParams* params, unsigned short** blurmap, unsigned short** base, int W, int row_from, int row_to); + void firstAnalysis_ (Image16* original, Glib::ustring wprofile, unsigned int* histogram, int* chroma_radius, int row_from, int row_to); + void resize_ (Image16* src, Image16* dst, ResizeParams params, int row_from, int row_to); + void damping_ (float** aI, unsigned short** aO, float damping, int W, int rowfrom, int rowto); + + public: + + static int* cacheL; + static int* cachea; + static int* cacheb; + static int* xcache; + static int* ycache; + static int* zcache; + + int chroma_scale; + int chroma_radius; + + double lumimul[3]; + static unsigned short gamma2curve[65536]; + + + static void initCache (); + + ImProcFunctions () : monitorTransform(NULL) {} + void release (); + + + void firstAnalysis (Image16* working, const ProcParams* params, unsigned int* vhist16, double gamma); + + void rgbProc (Image16* working, LabImage* lab, const ProcParams* params, int* tonecurve, SHMap* shmap); + void luminanceCurve (LabImage* lold, LabImage* lnew, int* curve, int row_from, int row_to); + void colorCurve (LabImage* lold, LabImage* lnew, const ProcParams* params); + void sharpening (LabImage* lab, const ProcParams* params, double scale, unsigned short** buffer); + void lumadenoise (LabImage* lab, const ProcParams* params, double scale, int** buffer); + void colordenoise (LabImage* lab, const ProcParams* params, double scale, int** buffer); + void transform (Image16* original, Image16* transformed, const ProcParams* params, int cx, int cy, int sx, int sy, int oW, int oH); + void simpltransform (Image16* original, Image16* transformed, const ProcParams* params, int cx, int cy, int sx, int sy, int oW, int oH); + void vignetting (Image16* original, Image16* transformed, const ProcParams* params, int cx, int cy, int oW, int oH); + void lab2rgb (LabImage* lab, Image8* image); + void resize (Image16* src, Image16* dst, ResizeParams params); + + bool transCoord (const ProcParams* params, int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv); + bool transCoord (const ProcParams* params, int W, int H, std::vector &src, std::vector &red, std::vector &green, std::vector &blue); + void deconvsharpening(LabImage* lab, const ProcParams* params, double scale, unsigned short** buffer); + + Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile); + Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile); + + static void getAutoExp (unsigned int* histogram, int histcompr, double expcomp, double clip, double& br, int& bl); +}; +}; +#endif diff --git a/rtengine/init.cc b/rtengine/init.cc new file mode 100644 index 000000000..c14056106 --- /dev/null +++ b/rtengine/init.cc @@ -0,0 +1,69 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include + +namespace rtengine { + +const Settings* settings; + +extern Glib::Mutex* dcrMutex; +Glib::Mutex* lcmsMutex = NULL; + +int init (const Settings* s) { + + settings = s; + iccStore.parseDir (s->iccDirectory); + CurveFactory::init (); + ImProcFunctions::initCache (); + delete dcrMutex; + dcrMutex = new Glib::Mutex; + delete lcmsMutex; + lcmsMutex = new Glib::Mutex; + return 0; +} + +StagedImageProcessor* StagedImageProcessor::create (InitialImage* initialImage) { + + ImProcCoordinator* ipc = new ImProcCoordinator (); + ipc->assign (initialImage->getImageSource ()); + return ipc; +} + +void StagedImageProcessor::destroy (StagedImageProcessor* sip) { + + delete sip; +} + +Settings* Settings::create () { + + return new Settings; +} + +void Settings::destroy (Settings* s) { + + delete s; +} + + +} + diff --git a/rtengine/iptcpairs.h b/rtengine/iptcpairs.h new file mode 100644 index 000000000..f4f0c0b07 --- /dev/null +++ b/rtengine/iptcpairs.h @@ -0,0 +1,47 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _IPTCPAIRS_ +#define _IPTCPAIRS_ + + +struct IptcPair { + IptcTag tag; + int size; + Glib::ustring field; +}; + +const IptcPair strTags[] = {IPTC_TAG_CAPTION, 2000, "Caption", + IPTC_TAG_WRITER_EDITOR, 32, "CaptionWriter", + IPTC_TAG_HEADLINE, 256, "Headline", + IPTC_TAG_SPECIAL_INSTRUCTIONS, 256, "Instructions", + IPTC_TAG_CATEGORY, 3, "Category", + IPTC_TAG_BYLINE, 32, "Author", + IPTC_TAG_BYLINE_TITLE, 32, "AuthorsPosition", + IPTC_TAG_CREDIT, 32, "Credit", + IPTC_TAG_SOURCE, 32, "Source", + IPTC_TAG_COPYRIGHT_NOTICE, 128, "Copyright", + IPTC_TAG_CITY, 32, "City", + IPTC_TAG_STATE, 32, "Province", + IPTC_TAG_COUNTRY_NAME, 64, "Country", + IPTC_TAG_OBJECT_NAME, 64, "Title", + IPTC_TAG_ORIG_TRANS_REF, 32, "TransReference", + IPTC_TAG_DATE_CREATED, 8, "DateCreated"}; + +#endif + diff --git a/rtengine/jdatasrc.c b/rtengine/jdatasrc.c new file mode 100644 index 000000000..0b77f26b1 --- /dev/null +++ b/rtengine/jdatasrc.c @@ -0,0 +1,413 @@ +#ifndef WIN32 +#define jboolean boolean +#endif +#include + +/* + * jdatasrc.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains decompression data source routines for the case of + * reading JPEG data from a file (or any stdio stream). While these routines + * are sufficient for most applications, some will want to use a different + * source manager. + * IMPORTANT: we assume that fread() will correctly transcribe an array of + * JOCTETs from 8-bit-wide elements on external storage. If char is wider + * than 8 bits on your machine, you may need to do some tweaking. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +//#include "jinclude.h" +#include +#include +#include + +#define JFREAD(file,buf,sizeofbuf) \ + ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) +#define JFWRITE(file,buf,sizeofbuf) \ + ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) + + + + +/* Expanded data source object for stdio input */ + +typedef struct { + struct jpeg_source_mgr pub; /* public fields */ + + FILE * infile; /* source stream */ + JOCTET * buffer; /* start of buffer */ + jboolean start_of_file; /* have we gotten any data yet? */ +} my_source_mgr; + +typedef my_source_mgr * my_src_ptr; + +#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ + + +/* + * Initialize source --- called by jpeg_read_header + * before any data is actually read. + */ + +METHODDEF(void) +my_init_source (j_decompress_ptr cinfo) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + /* We reset the empty-input-file flag for each image, + * but we don't clear the input buffer. + * This is correct behavior for reading a series of images from one source. + */ + src->start_of_file = TRUE; +} + + +/* + * Fill the input buffer --- called whenever buffer is emptied. + * + * In typical applications, this should read fresh data into the buffer + * (ignoring the current state of next_input_byte & bytes_in_buffer), + * reset the pointer & count to the start of the buffer, and return TRUE + * indicating that the buffer has been reloaded. It is not necessary to + * fill the buffer entirely, only to obtain at least one more byte. + * + * There is no such thing as an EOF return. If the end of the file has been + * reached, the routine has a choice of ERREXIT() or inserting fake data into + * the buffer. In most cases, generating a warning message and inserting a + * fake EOI marker is the best course of action --- this will allow the + * decompressor to output however much of the image is there. However, + * the resulting error message is misleading if the real problem is an empty + * input file, so we handle that case specially. + * + * In applications that need to be able to suspend compression due to input + * not being available yet, a FALSE return indicates that no more data can be + * obtained right now, but more may be forthcoming later. In this situation, + * the decompressor will return to its caller (with an indication of the + * number of scanlines it has read, if any). The application should resume + * decompression after it has loaded more data into the input buffer. Note + * that there are substantial restrictions on the use of suspension --- see + * the documentation. + * + * When suspending, the decompressor will back up to a convenient restart point + * (typically the start of the current MCU). next_input_byte & bytes_in_buffer + * indicate where the restart point will be if the current call returns FALSE. + * Data beyond this point must be rescanned after resumption, so move it to + * the front of the buffer rather than discarding it. + */ + +METHODDEF(jboolean) +my_fill_input_buffer (j_decompress_ptr cinfo) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + size_t nbytes; + + nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE); + + if (nbytes <= 0) { + if (src->start_of_file) /* Treat empty input file as fatal error */ + ERREXIT(cinfo, JERR_INPUT_EMPTY); + WARNMS(cinfo, JWRN_JPEG_EOF); + /* Insert a fake EOI marker */ + src->buffer[0] = (JOCTET) 0xFF; + src->buffer[1] = (JOCTET) JPEG_EOI; + nbytes = 2; + } + + if (src->start_of_file) + src->buffer[0] = (JOCTET) 0xFF; + + src->pub.next_input_byte = src->buffer; + src->pub.bytes_in_buffer = nbytes; + src->start_of_file = FALSE; + + return TRUE; +} + + +/* + * Skip data --- used to skip over a potentially large amount of + * uninteresting data (such as an APPn marker). + * + * Writers of suspendable-input applications must note that skip_input_data + * is not granted the right to give a suspension return. If the skip extends + * beyond the data currently in the buffer, the buffer can be marked empty so + * that the next read will cause a fill_input_buffer call that can suspend. + * Arranging for additional bytes to be discarded before reloading the input + * buffer is the application writer's problem. + */ + +METHODDEF(void) +my_skip_input_data (j_decompress_ptr cinfo, long num_bytes) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + /* Just a dumb implementation for now. Could use fseek() except + * it doesn't work on pipes. Not clear that being smart is worth + * any trouble anyway --- large skips are infrequent. + */ + if (num_bytes > 0) { + while (num_bytes > (long) src->pub.bytes_in_buffer) { + num_bytes -= (long) src->pub.bytes_in_buffer; + (void) my_fill_input_buffer(cinfo); + /* note we assume that fill_input_buffer will never return FALSE, + * so suspension need not be handled. + */ + } + src->pub.next_input_byte += (size_t) num_bytes; + src->pub.bytes_in_buffer -= (size_t) num_bytes; + } +} + + +/* + * An additional method that can be provided by data source modules is the + * resync_to_restart method for error recovery in the presence of RST markers. + * For the moment, this source module just uses the default resync method + * provided by the JPEG library. That method assumes that no backtracking + * is possible. + */ + + +/* + * Terminate source --- called by jpeg_finish_decompress + * after all data has been read. Often a no-op. + * + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + * application must deal with any cleanup that should happen even + * for error exit. + */ + +METHODDEF(void) +my_term_source (j_decompress_ptr cinfo) +{ + /* no work necessary here */ +} + + +/* + * Prepare for input from a stdio stream. + * The caller must have already opened the stream, and is responsible + * for closing it after finishing decompression. + */ + +GLOBAL(void) +my_jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile) +{ + my_src_ptr src; + + /* The source object and input buffer are made permanent so that a series + * of JPEG images can be read from the same file by calling jpeg_stdio_src + * only before the first one. (If we discarded the buffer at the end of + * one image, we'd likely lose the start of the next one.) + * This makes it unsafe to use this manager and a different source + * manager serially with the same JPEG object. Caveat programmer. + */ + if (cinfo->src == NULL) { /* first time for this JPEG object? */ + cinfo->src = (struct jpeg_source_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + sizeof(my_source_mgr)); + src = (my_src_ptr) cinfo->src; + src->buffer = (JOCTET *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + INPUT_BUF_SIZE * sizeof(JOCTET)); + } + + src = (my_src_ptr) cinfo->src; + src->pub.init_source = my_init_source; + src->pub.fill_input_buffer = my_fill_input_buffer; + src->pub.skip_input_data = my_skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ + src->pub.term_source = my_term_source; + src->infile = infile; + src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ + src->pub.next_input_byte = NULL; /* until buffer loaded */ +} + +jmp_buf jpeg_jmp_buf; + +METHODDEF(void) +my_error_exit (j_common_ptr cinfo) +{ + /* Always display the message */ + (*cinfo->err->output_message) (cinfo); + + /* Let the memory manager delete any temp files before we die */ + jpeg_destroy(cinfo); + + longjmp (jpeg_jmp_buf, 1); +} + + +//const char * const jpeg_std_message_table[] = { +//#include "jerror.h" +// NULL +//}; +extern const char * const jpeg_std_message_table[]; + + +/* + * Actual output of an error or trace message. + * Applications may override this method to send JPEG messages somewhere + * other than stderr. + * + * On Windows, printing to stderr is generally completely useless, + * so we provide optional code to produce an error-dialog popup. + * Most Windows applications will still prefer to override this routine, + * but if they don't, it'll do something at least marginally useful. + * + * NOTE: to use the library in an environment that doesn't support the + * C stdio library, you may have to delete the call to fprintf() entirely, + * not just not use this routine. + */ + +METHODDEF(void) +output_message (j_common_ptr cinfo) +{ + char buffer[JMSG_LENGTH_MAX]; + + /* Create the message */ + (*cinfo->err->format_message) (cinfo, buffer); + +#ifdef USE_WINDOWS_MESSAGEBOX + /* Display it in a message dialog box */ + MessageBox(GetActiveWindow(), buffer, "JPEG Library Error", + MB_OK | MB_ICONERROR); +#else + /* Send it to stderr, adding a newline */ + fprintf(stderr, "%s\n", buffer); +#endif +} + + +/* + * Decide whether to emit a trace or warning message. + * msg_level is one of: + * -1: recoverable corrupt-data warning, may want to abort. + * 0: important advisory messages (always display to user). + * 1: first level of tracing detail. + * 2,3,...: successively more detailed tracing messages. + * An application might override this method if it wanted to abort on warnings + * or change the policy about which messages to display. + */ + +METHODDEF(void) +emit_message (j_common_ptr cinfo, int msg_level) +{ + struct jpeg_error_mgr * err = cinfo->err; + + if (msg_level < 0) { + /* It's a warning message. Since corrupt files may generate many warnings, + * the policy implemented here is to show only the first warning, + * unless trace_level >= 3. + */ + if (err->num_warnings == 0 || err->trace_level >= 3) + (*err->output_message) (cinfo); + /* Always count warnings in num_warnings. */ + err->num_warnings++; + } else { + /* It's a trace message. Show it if trace_level >= msg_level. */ + if (err->trace_level >= msg_level) + (*err->output_message) (cinfo); + } +} + + +/* + * Format a message string for the most recent JPEG error or message. + * The message is stored into buffer, which should be at least JMSG_LENGTH_MAX + * characters. Note that no '\n' character is added to the string. + * Few applications should need to override this method. + */ + +METHODDEF(void) +format_message (j_common_ptr cinfo, char * buffer) +{ + struct jpeg_error_mgr * err = cinfo->err; + int msg_code = err->msg_code; + const char * msgtext = NULL; + const char * msgptr; + char ch; + jboolean isstring; + + /* Look up message string in proper table */ + if (msg_code > 0 && msg_code <= err->last_jpeg_message) { + msgtext = err->jpeg_message_table[msg_code]; + } else if (err->addon_message_table != NULL && + msg_code >= err->first_addon_message && + msg_code <= err->last_addon_message) { + msgtext = err->addon_message_table[msg_code - err->first_addon_message]; + } + + /* Defend against bogus message number */ + if (msgtext == NULL) { + err->msg_parm.i[0] = msg_code; + msgtext = err->jpeg_message_table[0]; + } + + /* Check for string parameter, as indicated by %s in the message text */ + isstring = FALSE; + msgptr = msgtext; + while ((ch = *msgptr++) != '\0') { + if (ch == '%') { + if (*msgptr == 's') isstring = TRUE; + break; + } + } + + /* Format the message into the passed buffer */ + if (isstring) + sprintf(buffer, msgtext, err->msg_parm.s); + else + sprintf(buffer, msgtext, + err->msg_parm.i[0], err->msg_parm.i[1], + err->msg_parm.i[2], err->msg_parm.i[3], + err->msg_parm.i[4], err->msg_parm.i[5], + err->msg_parm.i[6], err->msg_parm.i[7]); +} + + +/* + * Reset error state variables at start of a new image. + * This is called during compression startup to reset trace/error + * processing to default state, without losing any application-specific + * method pointers. An application might possibly want to override + * this method if it has additional error processing state. + */ + +METHODDEF(void) +reset_error_mgr (j_common_ptr cinfo) +{ + cinfo->err->num_warnings = 0; + /* trace_level is not reset since it is an application-supplied parameter */ + cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */ +} + + +GLOBAL(struct jpeg_error_mgr *) +my_jpeg_std_error (struct jpeg_error_mgr * err) +{ + + err->error_exit = my_error_exit; + err->emit_message = emit_message; + err->output_message = output_message; + err->format_message = format_message; + err->reset_error_mgr = reset_error_mgr; + + err->trace_level = 0; /* default = no tracing */ + err->num_warnings = 0; /* no warnings emitted yet */ + err->msg_code = 0; /* may be useful as a flag for "no error" */ + + /* Initialize message table pointers */ + err->jpeg_message_table = jpeg_std_message_table; + err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1; + + err->addon_message_table = NULL; + err->first_addon_message = 0; /* for safety */ + err->last_addon_message = 0; + + return err; +} diff --git a/rtengine/loadinitial.cc b/rtengine/loadinitial.cc new file mode 100644 index 000000000..515d703fd --- /dev/null +++ b/rtengine/loadinitial.cc @@ -0,0 +1,43 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +namespace rtengine { + +InitialImage* InitialImage::load (const Glib::ustring& fname, bool isRaw, int* errorCode, ProgressListener* pl) { + + ImageSource* isrc; + + if (!isRaw) + isrc = new StdImageSource (); + else + isrc = new RawImageSource (); + + isrc->setProgressListener (pl); + *errorCode = isrc->load (fname); + if (*errorCode) { + delete isrc; + return NULL; + } + return isrc; +} +} + diff --git a/rtengine/median.h b/rtengine/median.h new file mode 100644 index 000000000..e963d484b --- /dev/null +++ b/rtengine/median.h @@ -0,0 +1,222 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#define SORT3(a1,a2,a3,b1,b2,b3) \ + { \ + if ((a1)<(a2)) { \ + if ((a2)<(a3)) { \ + (b1) = (a1); (b2) = (a2); (b3) = (a3); \ + } \ + else if ((a1)<(a3)) { \ + (b1) = (a1); (b2) = (a3); (b3) = (a2); \ + } \ + else { \ + (b1) = (a3); (b2) = (a1); (b3) = (a2); \ + } \ + } \ + else { \ + if ((a3)<(a2)) { \ + (b1) = (a3); (b2) = (a2); (b3) = (a1); \ + } \ + else if ((a3)<(a1)) { \ + (b1) = (a2); (b2) = (a3); (b3) = (a1); \ + } \ + else { \ + (b1) = (a2); (b2) = (a1); (b3) = (a3); \ + } \ + } \ + } + +#define MERGESORT(a1,a2,a3,b1,b2,b3,c1,c2,c3,c4,c5,c6) \ + {\ + if (a1 + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#define MINMAX3(a,b,c,min,max) \ +{ \ +if ((a)<(b)) { \ + if ((b)<(c)) { \ + (min) = (a); \ + (max) = (c); \ + } \ + else { \ + (max) = (b); \ + if ((a)<(c)) \ + (min) = (a); \ + else \ + (min) = (c); \ + } \ +} else { \ + if ((b)>(c)) { \ + (min) = (c); \ + (max) = (a); \ + } \ + else { \ + (min) = (b); \ + if ((a)>(c)) \ + (max) = (a); \ + else \ + (max) = (c); \ + } \ +} \ +} + +#define MIN3(a,b,c,min) \ +{ \ +if ((a)<(b)) { \ + if ((a)<(c)) \ + (min) = (a); \ + else \ + (min) = (c); \ +} else { \ + if ((b)>(c)) \ + (min) = (c); \ + else \ + (min) = (b); \ +} \ +} + +#define MAX3(a,b,c,min) \ +{ \ +if ((a)>(b)) { \ + if ((a)>(c)) \ + (max) = (a); \ + else \ + (max) = (c); \ +} else { \ + if ((b)<(c)) \ + (max) = (c); \ + else \ + (max) = (b); \ +} \ +} diff --git a/rtengine/myfile.cc b/rtengine/myfile.cc new file mode 100644 index 000000000..aee82f5d8 --- /dev/null +++ b/rtengine/myfile.cc @@ -0,0 +1,135 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#ifdef RAWZOR_SUPPORT +#include +#endif + +IMFILE* fopen (const char* fname) { + + FILE* f = fopen (fname, "rb"); + if (!f) + return NULL; + IMFILE* mf = new IMFILE; + fseek (f, 0, SEEK_END); + mf->size = ftell (f); + mf->data = new char [mf->size]; + fseek (f, 0, SEEK_SET); + fread (mf->data, 1, mf->size, f); + fclose (f); + mf->pos = 0; + mf->eof = false; +#ifdef RAWZOR_SUPPORT + // RAWZOR support begin + bool rawzor = false; + Glib::ustring bname = Glib::path_get_basename(fname); + int lastdot = bname.find_last_of ('.'); + if (lastdot!=bname.npos) + rawzor = bname.substr (lastdot).casefold() == Glib::ustring(".rwz").casefold(); + + if (rawzor) { + int realSize = 0; + if (!m_rwz_check (mf->data, mf->size, &realSize)) { + char* realData = new char [realSize]; + m_rwz_decompress (mf->data, mf->size, realData, realSize); + delete [] mf->data; + mf->data = realData; + mf->size = realSize; + } + } + // RAWZOR support end +#endif + + return mf; +} + +IMFILE* gfopen (const char* fname) { + + FILE* f = g_fopen (fname, "rb"); + if (!f) + return NULL; + IMFILE* mf = new IMFILE; + fseek (f, 0, SEEK_END); + mf->size = ftell (f); + mf->data = new char [mf->size]; + fseek (f, 0, SEEK_SET); + fread (mf->data, 1, mf->size, f); + fclose (f); + mf->pos = 0; + mf->eof = false; + +#ifdef RAWZOR_SUPPORT + // RAWZOR support begin + bool rawzor = false; + Glib::ustring bname = Glib::path_get_basename(fname); + int lastdot = bname.find_last_of ('.'); + if (lastdot!=bname.npos) + rawzor = bname.substr (lastdot).casefold() == Glib::ustring(".rwz").casefold(); + + if (rawzor) { + int realSize = 0; + if (!m_rwz_check (mf->data, mf->size, &realSize)) { + char* realData = new char [realSize]; + m_rwz_decompress (mf->data, mf->size, realData, realSize); + delete [] mf->data; + mf->data = realData; + mf->size = realSize; + } + } + // RAWZOR support end +#endif + return mf; +} + +IMFILE* fopen (unsigned* buf, int size) { + + IMFILE* mf = new IMFILE; + mf->size = size; + mf->data = new char [mf->size]; + memcpy (mf->data, buf, size); + mf->pos = 0; + mf->eof = false; + return mf; +} + +void fclose (IMFILE* f) { + + delete [] f->data; + delete f; +} + +int fscanf (IMFILE* f, const char* s ...) { + + va_list ap; + return sscanf (f->data, s, ap); +} + +char* fgets (char* s, int n, IMFILE* f) { + + if (f->pos>=f->size) { + f->eof = true; + return NULL; + } + int i = 0; + do s[i++] = f->data[f->pos++]; + while (ipossize); + return s; +} diff --git a/rtengine/myfile.h b/rtengine/myfile.h new file mode 100644 index 000000000..c81d2eaac --- /dev/null +++ b/rtengine/myfile.h @@ -0,0 +1,92 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _MYFILE_ +#define _MYFILE_ + +#include +#include +#include +struct IMFILE { + + int pos; + int size; + char* data; + bool eof; +}; + +IMFILE* fopen (const char* fname); +IMFILE* gfopen (const char* fname);IMFILE* fopen (unsigned* buf, int size); +void fclose (IMFILE* f); +inline int ftell (IMFILE* f) { + + return f->pos; +} + +inline int feof (IMFILE* f) { + + return f->eof; +} + +inline void fseek (IMFILE* f, int p, int how) { + + if (how==SEEK_SET) + f->pos = p; + else if (how==SEEK_CUR) + f->pos += p; + else if (how==SEEK_END) + f->pos = f->size-p; +} + +inline int fgetc (IMFILE* f) { + + if (f->possize) + return (unsigned char)f->data[f->pos++]; + f->eof = true; + return EOF; +} + +inline int getc (IMFILE* f) { + + if (f->possize) + return (unsigned char)f->data[f->pos++]; + f->eof = true; + return EOF; +} + +inline int fread (void* dst, int es, int count, IMFILE* f) { + + int s = es*count; + int avail = f->size - f->pos; + if (s<=avail) { + memcpy (dst, f->data+f->pos, s); + f->pos += s; + return count; + } + else { + memcpy (dst, f->data+f->pos, avail); + f->pos += avail; + f->eof = true; + return avail/es; + } +} + +int fscanf (IMFILE* f, const char* s ...); +char* fgets (char* s, int n, IMFILE* f); +#endif + diff --git a/rtengine/mytime.h b/rtengine/mytime.h new file mode 100644 index 000000000..240076aa0 --- /dev/null +++ b/rtengine/mytime.h @@ -0,0 +1,62 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _MYTIME_ +#define _MYTIME_ + +#ifdef WIN32 +#include +#elif defined __APPLE__ +#include +#else +#include +#endif + +class MyTime { + + public: +#ifndef WIN32 + timespec t; +#else + DWORD t; +#endif + + void set () { +#ifdef WIN32 + t = GetTickCount (); +#elif defined __APPLE__ + struct timeval tv; + gettimeofday(&tv, NULL); + t.tv_sec = tv.tv_sec; + t.tv_nsec = tv.tv_usec*1000; +#else + clock_gettime (CLOCK_REALTIME, &t); +#endif +} + + int etime (MyTime a) { +#ifndef WIN32 + return (t.tv_sec-a.t.tv_sec)*1000000 + (t.tv_nsec-a.t.tv_nsec)/1000; +#else + return (t - a.t)*1000; +#endif + } +}; + + +#endif diff --git a/rtengine/processingjob.cc b/rtengine/processingjob.cc new file mode 100644 index 000000000..4c0b1ddcb --- /dev/null +++ b/rtengine/processingjob.cc @@ -0,0 +1,39 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include + +namespace rtengine { + +ProcessingJob* ProcessingJob::create (const Glib::ustring& fname, bool isRaw, const procparams::ProcParams& pparams) { + + return new ProcessingJobImpl (fname, isRaw, pparams); +} + +ProcessingJob* ProcessingJob::create (InitialImage* initialImage, const procparams::ProcParams& pparams) { + + return new ProcessingJobImpl (initialImage, pparams); +} + +void ProcessingJob::destroy (ProcessingJob* job) { + + delete (ProcessingJobImpl*) job; +} + +} + diff --git a/rtengine/processingjob.h b/rtengine/processingjob.h new file mode 100644 index 000000000..050bde66a --- /dev/null +++ b/rtengine/processingjob.h @@ -0,0 +1,45 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _PROCESSINGJOB_ +#define _PROCESSINGJOB_ + +#include + +namespace rtengine { + +class ProcessingJobImpl : public ProcessingJob { + + public: + Glib::ustring fname; + bool isRaw; + InitialImage* initialImage; + procparams::ProcParams pparams; + + ProcessingJobImpl (const Glib::ustring& fn, bool iR, const procparams::ProcParams& pp) + : fname(fn), isRaw(iR), initialImage(NULL) { pparams = pp; } + + ProcessingJobImpl (InitialImage* iImage, const procparams::ProcParams& pp) + : fname(""), initialImage(iImage) { pparams = pp; iImage->increaseRef(); } + + ~ProcessingJobImpl () { if (initialImage) initialImage->decreaseRef(); } +}; + +}; + +#endif diff --git a/rtengine/procevents.h b/rtengine/procevents.h new file mode 100644 index 000000000..9e0452b8d --- /dev/null +++ b/rtengine/procevents.h @@ -0,0 +1,114 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef __PROCEVENT__ +#define __PROCEVENT__ + +#include + +#define NUMOFEVENTS 83 + +namespace rtengine { + +enum ProcEvent { + EvPhotoLoaded=0, + EvProfileLoaded=1, + EvProfileChanged=2, + EvHistoryBrowsed=3, + EvBrightness=4, + EvContrast=5, + EvBlack=6, + EvExpComp=7, + EvHLCompr=8, + EvSHCompr=9, + EvToneCurve=10, + EvAutoExp=11, + EvClip=12, + EvLBrightness=13, + EvLContrast=14, + EvLBlack=15, + EvLHLCompr=16, + EvLSHCompr=17, + EvLCurve=18, + EvShrEnabled=19, + EvShrRadius=20, + EvShrAmount=21, + EvShrThresh=22, + EvShrEdgeOnly=23, + EvShrEdgeRadius=24, + EvShrEdgeTolerance=25, + EvShrHaloControl=26, + EvShrHaloAmount=27, + EvShrMethod=28, + EvShrDRadius=29, + EvShrDAmount=30, + EvShrDDamping=31, + EvShrDIterations=32, + EvCBAvoidClip=33, + EvCBSatLimiter=34, + EvCBSatLimit=35, + EvCBBoost=36, + EvWBMethod=37, + EvWBTemp=38, + EvWBGreen=39, + EvCShiftA=40, + EvCShiftB=41, + EvLDNEnabled=42, + EvLDNRadius=43, + EvLDNEdgeTolerance=44, + EvCDNEnabled=45, + EvCDNRadius=46, + EvCDNEdgeTolerance=47, + EvCDNEdgeSensitive=48, + EvSHEnabled=49, + EvSHHighlights=50, + EvSHShadows=51, + EvSHHLTonalW=52, + EvSHSHTonalW=53, + EvSHLContrast=54, + EvSHRadius=55, + EvCTRotate=56, + EvCTHFlip=57, + EvCTVFlip=58, + EvROTDegree=59, + EvROTFill=60, + EvDISTAmount=61, + EvBookmarkSelected=62, + EvCrop=63, + EvCACorr=64, + EvHREnabled=65, + EvHRAmount=66, + EvHRMethod=67, + EvWProfile=68, + EvOProfile=69, + EvIProfile=70, + EvVignetting=71, + EvChMixer=72, + EvResizeScale=73, + EvResizeMethod=74, + EvExif=75, + EvIPTC=76, + EvResizeSpec=77, + EvResizeWidth=78, + EvResizeHeight=79, + EvResizeEnabled=80, + EvProfileChangeNotification=81, + EvSHHighQuality=82 + }; +} +#endif diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc new file mode 100644 index 000000000..438a47c50 --- /dev/null +++ b/rtengine/procparams.cc @@ -0,0 +1,647 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include + +#include + +namespace rtengine { +namespace procparams { + +ProcParams::ProcParams () { + + setDefaults (); +} + +ProcParams* ProcParams::create () { + + return new ProcParams(); +} + +void ProcParams::destroy (ProcParams* pp) { + + delete pp; +} + +void ProcParams::setDefaults () { + + toneCurve.autoexp = false; + toneCurve.clip = 0.002; + toneCurve.expcomp = 0; + toneCurve.brightness = 0; + toneCurve.contrast = 0; + toneCurve.black = 0; + toneCurve.hlcompr = 85; + toneCurve.shcompr = 85; + toneCurve.curve.clear (); + + lumaCurve.brightness = 0; + lumaCurve.contrast = 0; + lumaCurve.curve.clear (); + + sharpening.enabled = true; + sharpening.radius = 1.0; + sharpening.amount = 90; + sharpening.threshold = 768; + sharpening.edgesonly = false; + sharpening.edges_radius = 3; + sharpening.edges_tolerance = 1000; + sharpening.halocontrol = false; + sharpening.halocontrol_amount = 85; + sharpening.method = "usm"; + sharpening.deconvradius = 0.75; + sharpening.deconviter = 30; + sharpening.deconvdamping = 20; + sharpening.deconvamount = 75; + + colorBoost.amount = 0; + colorBoost.avoidclip = false; + colorBoost.enable_saturationlimiter = false; + colorBoost.saturationlimit = 50; + + wb.method = "Camera"; + wb.temperature = 6504; + wb.green = 1.00102; + + colorShift.a = 0; + colorShift.b = 0; + + lumaDenoise.enabled = false; + lumaDenoise.radius = 1.9; + lumaDenoise.edgetolerance = 2000; + + colorDenoise.enabled = false; + colorDenoise.edgesensitive = false; + colorDenoise.radius = 1.9; + colorDenoise.edgetolerance = 2000; + + sh.enabled = false; + sh.hq = false; + sh.highlights = 10; + sh.htonalwidth = 80; + sh.shadows = 10; + sh.stonalwidth = 80; + sh.localcontrast = 15; + sh.radius = 40; + + crop.enabled = false; + crop.x = -1; + crop.y = -1; + crop.w = 15000; + crop.h = 15000; + crop.fixratio = false; + crop.ratio = "3:2"; + crop.orientation= "Landscape"; + crop.guide = "None"; + + coarse.rotate = 0; + coarse.hflip = false; + coarse.vflip = false; + + rotate.degree = 0; + rotate.fill = true; + distortion.amount = 0; + + cacorrection.red = 0; + cacorrection.blue = 0; + + hlrecovery.enabled = false; + hlrecovery.method = "Luminance"; + + vignetting.amount = 0; + vignetting.radius = 50; + + chmixer.red[0] = 100; + chmixer.red[1] = 0; + chmixer.red[2] = 0; + chmixer.green[0] = 0; + chmixer.green[1] = 100; + chmixer.green[2] = 0; + chmixer.blue[0] = 0; + chmixer.blue[1] = 0; + chmixer.blue[2] = 100; + + resize.enabled = false; + resize.scale = 1.0; + resize.method = "Bicubic"; + resize.dataspec = 0; + resize.width = 800; + resize.height = 600; + + icm.input = ""; + icm.gammaOnInput = false; + icm.working = "sRGB"; + icm.output = "sRGB"; + + exif.clear (); + iptc.clear (); + + version = 249; +} + +int ProcParams::save (Glib::ustring fname) const { + + SafeKeyFile keyFile; + + keyFile.set_integer ("Version", "Version", 231); + + // save tonecurve: + keyFile.set_boolean ("Exposure", "Auto", toneCurve.autoexp); + keyFile.set_double ("Exposure", "Clip", toneCurve.clip); + keyFile.set_double ("Exposure", "Compensation", toneCurve.expcomp); + keyFile.set_integer ("Exposure", "Brightness", toneCurve.brightness); + keyFile.set_integer ("Exposure", "Contrast", toneCurve.contrast); + keyFile.set_integer ("Exposure", "Black", toneCurve.black); + keyFile.set_integer ("Exposure", "HighlightCompr", toneCurve.hlcompr); + keyFile.set_integer ("Exposure", "ShadowCompr", toneCurve.shcompr); + Glib::ArrayHandle tcurve = toneCurve.curve; + keyFile.set_double_list("Exposure", "Curve", tcurve); + + // save channel mixer + Glib::ArrayHandle rmix (chmixer.red, 3, Glib::OWNERSHIP_NONE); + Glib::ArrayHandle gmix (chmixer.green, 3, Glib::OWNERSHIP_NONE); + Glib::ArrayHandle bmix (chmixer.blue, 3, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Channel Mixer", "Red", rmix); + keyFile.set_integer_list("Channel Mixer", "Green", gmix); + keyFile.set_integer_list("Channel Mixer", "Blue", bmix); + + // save luma curve + keyFile.set_integer ("Luminance Curve", "Brightness", lumaCurve.brightness); + keyFile.set_integer ("Luminance Curve", "Contrast", lumaCurve.contrast); + Glib::ArrayHandle lcurve = lumaCurve.curve; + keyFile.set_double_list("Luminance Curve", "Curve", lcurve); + + // save sharpening + keyFile.set_boolean ("Sharpening", "Enabled", sharpening.enabled); + keyFile.set_string ("Sharpening", "Method", sharpening.method); + keyFile.set_double ("Sharpening", "Radius", sharpening.radius); + keyFile.set_integer ("Sharpening", "Amount", sharpening.amount); + keyFile.set_integer ("Sharpening", "Threshold", sharpening.threshold); + keyFile.set_boolean ("Sharpening", "OnlyEdges", sharpening.edgesonly); + keyFile.set_double ("Sharpening", "EdgedetectionRadius", sharpening.edges_radius); + keyFile.set_integer ("Sharpening", "EdgeTolerance", sharpening.edges_tolerance); + keyFile.set_boolean ("Sharpening", "HalocontrolEnabled", sharpening.halocontrol); + keyFile.set_integer ("Sharpening", "HalocontrolAmount", sharpening.halocontrol_amount); + keyFile.set_double ("Sharpening", "DeconvRadius", sharpening.deconvradius); + keyFile.set_integer ("Sharpening", "DeconvAmount", sharpening.deconvamount); + keyFile.set_integer ("Sharpening", "DeconvDamping", sharpening.deconvdamping); + keyFile.set_integer ("Sharpening", "DeconvIterations", sharpening.deconviter); + + // save colorBoost + keyFile.set_integer ("Color Boost", "Amount", colorBoost.amount); + keyFile.set_boolean ("Color Boost", "AvoidColorClipping", colorBoost.avoidclip); + keyFile.set_boolean ("Color Boost", "SaturationLimiter", colorBoost.enable_saturationlimiter); + keyFile.set_double ("Color Boost", "SaturationLimit", colorBoost.saturationlimit); + + // save wb + if (wb.method=="Camera") + keyFile.set_string ("White Balance", "Setting", "Camera"); + else + keyFile.set_string ("White Balance", "Setting", "Custom"); + keyFile.set_integer ("White Balance", "Temperature", wb.temperature); + keyFile.set_double ("White Balance", "Green", wb.green); + + // save colorShift + keyFile.set_double ("Color Shift", "ChannelA", colorShift.a); + keyFile.set_double ("Color Shift", "ChannelB", colorShift.b); + + // save lumaDenoise + keyFile.set_boolean ("Luminance Denoising", "Enabled", lumaDenoise.enabled); + keyFile.set_double ("Luminance Denoising", "Radius", lumaDenoise.radius); + keyFile.set_integer ("Luminance Denoising", "EdgeTolerance", lumaDenoise.edgetolerance); + + // save colorDenoise + keyFile.set_boolean ("Chrominance Denoising", "Enabled", colorDenoise.enabled); + keyFile.set_integer ("Chrominance Denoising", "Amount", colorDenoise.amount); + + // save sh + keyFile.set_boolean ("Shadows & Highlights", "Enabled", sh.enabled); + keyFile.set_boolean ("Shadows & Highlights", "HighQuality", sh.hq); + keyFile.set_integer ("Shadows & Highlights", "Highlights", sh.highlights); + keyFile.set_integer ("Shadows & Highlights", "HighlightTonalWidth", sh.htonalwidth); + keyFile.set_integer ("Shadows & Highlights", "Shadows", sh.shadows); + keyFile.set_integer ("Shadows & Highlights", "ShadowTonalWidth", sh.stonalwidth); + keyFile.set_integer ("Shadows & Highlights", "LocalContrast", sh.localcontrast); + keyFile.set_integer ("Shadows & Highlights", "Radius", sh.radius); + + // save crop + keyFile.set_boolean ("Crop", "Enabled", crop.enabled); + keyFile.set_integer ("Crop", "X", crop.x); + keyFile.set_integer ("Crop", "Y", crop.y); + keyFile.set_integer ("Crop", "W", crop.w); + keyFile.set_integer ("Crop", "H", crop.h); + keyFile.set_boolean ("Crop", "FixedRatio", crop.fixratio); + keyFile.set_string ("Crop", "Ratio", crop.ratio); + keyFile.set_string ("Crop", "Orientation", crop.orientation); + keyFile.set_string ("Crop", "Guide", crop.guide); + + // save coarse + keyFile.set_integer ("Coarse Transformation", "Rotate", coarse.rotate); + keyFile.set_boolean ("Coarse Transformation", "HorizontalFlip", coarse.hflip); + keyFile.set_boolean ("Coarse Transformation", "VerticalFlip", coarse.vflip); + + // save rotate + keyFile.set_double ("Rotation", "Degree", rotate.degree); + keyFile.set_double ("Rotation", "Fill", rotate.fill); + + // save distortion + keyFile.set_double ("Distortion", "Amount", distortion.amount); + + // save C/A correction + keyFile.set_double ("CACorrection", "Red", cacorrection.red); + keyFile.set_double ("CACorrection", "Blue", cacorrection.blue); + + // save vignetting correction + keyFile.set_integer ("Vignetting Correction", "Amount", vignetting.amount); + keyFile.set_integer ("Vignetting Correction", "Radius", vignetting.radius); + + // save highlight recovery settings + keyFile.set_boolean ("HLRecovery", "Enabled", hlrecovery.enabled); + keyFile.set_string ("HLRecovery", "Method", hlrecovery.method); + + keyFile.set_boolean ("Resize", "Enabled",resize.enabled); + keyFile.set_double ("Resize", "Scale", resize.scale); + keyFile.set_string ("Resize", "Method", resize.method); + keyFile.set_integer ("Resize", "DataSpecified", resize.dataspec); + keyFile.set_integer ("Resize", "Width", resize.width); + keyFile.set_integer ("Resize", "Height", resize.height); + + // save color management settings + keyFile.set_string ("Color Management", "InputProfile", icm.input); + keyFile.set_boolean ("Color Management", "ApplyGammaBeforeInputProfile", icm.gammaOnInput); + keyFile.set_string ("Color Management", "WorkingProfile", icm.working); + keyFile.set_string ("Color Management", "OutputProfile", icm.output); + + // save exif change list + for (int i=0; i values = iptc[i].values; + keyFile.set_string_list ("IPTC", iptc[i].field, values); + } + + FILE *f = g_fopen (fname.c_str(), "wt"); + + if (f==NULL) + return 1; + else { + fprintf (f, "%s", keyFile.to_data().c_str()); + fclose (f); + return 0; + } +} + +int ProcParams::load (Glib::ustring fname) { + + SafeKeyFile keyFile; + try { + setDefaults (); + + FILE* f = g_fopen (fname.c_str(), "rt"); + if (!f) + return 1; + char* buffer = new char[1024]; + std::ostringstream ostr; + while (fgets (buffer, 1024, f)) + ostr << buffer << "\n"; + delete [] buffer; + if (!keyFile.load_from_data (ostr.str())) + return 1; + fclose (f); + + // load tonecurve: + +version = 200; +if (keyFile.has_group ("Version")) { + if (keyFile.has_key ("Version", "Version")) version = keyFile.get_integer ("Version", "Version"); +} + +if (keyFile.has_group ("Exposure")) { + if (keyFile.has_key ("Exposure", "Auto")) toneCurve.autoexp = keyFile.get_boolean ("Exposure", "Auto"); + if (keyFile.has_key ("Exposure", "Clip")) toneCurve.clip = keyFile.get_double ("Exposure", "Clip"); + if (keyFile.has_key ("Exposure", "Compensation")) toneCurve.expcomp = keyFile.get_double ("Exposure", "Compensation"); + if (keyFile.has_key ("Exposure", "Brightness")) toneCurve.brightness = keyFile.get_integer ("Exposure", "Brightness"); + if (keyFile.has_key ("Exposure", "Contrast")) toneCurve.contrast = keyFile.get_integer ("Exposure", "Contrast"); + if (keyFile.has_key ("Exposure", "Black")) toneCurve.black = keyFile.get_integer ("Exposure", "Black"); + if (keyFile.has_key ("Exposure", "HighlightCompr")) toneCurve.hlcompr = keyFile.get_integer ("Exposure", "HighlightCompr"); + if (keyFile.has_key ("Exposure", "ShadowCompr")) toneCurve.shcompr = keyFile.get_integer ("Exposure", "ShadowCompr"); + if (version>200) + if (keyFile.has_key ("Exposure", "Curve")) toneCurve.curve = keyFile.get_double_list ("Exposure", "Curve"); +} + + // load channel mixer curve +if (keyFile.has_group ("Channel Mixer")) { + if (keyFile.has_key ("Channel Mixer", "Red") && keyFile.has_key ("Channel Mixer", "Green") && keyFile.has_key ("Channel Mixer", "Blue")) { + Glib::ArrayHandle rmix = keyFile.get_integer_list ("Channel Mixer", "Red"); + Glib::ArrayHandle gmix = keyFile.get_integer_list ("Channel Mixer", "Green"); + Glib::ArrayHandle bmix = keyFile.get_integer_list ("Channel Mixer", "Blue"); + memcpy (chmixer.red, rmix.data(), 3*sizeof(int)); + memcpy (chmixer.green, gmix.data(), 3*sizeof(int)); + memcpy (chmixer.blue, bmix.data(), 3*sizeof(int)); + } +} + + // load luma curve +if (keyFile.has_group ("Luminance Curve")) { + if (keyFile.has_key ("Luminance Curve", "Brightness")) lumaCurve.brightness = keyFile.get_integer ("Luminance Curve", "Brightness"); + if (keyFile.has_key ("Luminance Curve", "Contrast")) lumaCurve.contrast = keyFile.get_integer ("Luminance Curve", "Contrast"); + if (version>200) + if (keyFile.has_key ("Luminance Curve", "Curve")) lumaCurve.curve = keyFile.get_double_list ("Luminance Curve", "Curve"); +} + + // load sharpening +if (keyFile.has_group ("Sharpening")) { + if (keyFile.has_key ("Sharpening", "Enabled")) sharpening.enabled = keyFile.get_boolean ("Sharpening", "Enabled"); + if (keyFile.has_key ("Sharpening", "Radius")) sharpening.radius = keyFile.get_double ("Sharpening", "Radius"); + if (keyFile.has_key ("Sharpening", "Amount")) sharpening.amount = keyFile.get_integer ("Sharpening", "Amount"); + if (keyFile.has_key ("Sharpening", "Threshold")) sharpening.threshold = keyFile.get_integer ("Sharpening", "Threshold"); + if (keyFile.has_key ("Sharpening", "OnlyEdges")) sharpening.edgesonly = keyFile.get_boolean ("Sharpening", "OnlyEdges"); + if (keyFile.has_key ("Sharpening", "EdgedetectionRadius")) sharpening.edges_radius = keyFile.get_double ("Sharpening", "EdgedetectionRadius"); + if (keyFile.has_key ("Sharpening", "EdgeTolerance")) sharpening.edges_tolerance = keyFile.get_integer ("Sharpening", "EdgeTolerance"); + if (keyFile.has_key ("Sharpening", "HalocontrolEnabled")) sharpening.halocontrol = keyFile.get_boolean ("Sharpening", "HalocontrolEnabled"); + if (keyFile.has_key ("Sharpening", "HalocontrolAmount")) sharpening.halocontrol_amount = keyFile.get_integer ("Sharpening", "HalocontrolAmount"); + if (keyFile.has_key ("Sharpening", "Method")) sharpening.method = keyFile.get_string ("Sharpening", "Method"); + if (keyFile.has_key ("Sharpening", "DeconvRadius")) sharpening.deconvradius = keyFile.get_double ("Sharpening", "DeconvRadius"); + if (keyFile.has_key ("Sharpening", "DeconvAmount")) sharpening.deconvamount = keyFile.get_integer ("Sharpening", "DeconvAmount"); + if (keyFile.has_key ("Sharpening", "DeconvDamping")) sharpening.deconvdamping = keyFile.get_integer ("Sharpening", "DeconvDamping"); + if (keyFile.has_key ("Sharpening", "DeconvIterations")) sharpening.deconviter = keyFile.get_integer ("Sharpening", "DeconvIterations"); +} + + // load colorBoost +if (keyFile.has_group ("Color Boost")) { + if (keyFile.has_key ("Color Boost", "Amount")) colorBoost.amount = keyFile.get_integer ("Color Boost", "Amount"); + else { + int a=0, b=0; + if (keyFile.has_key ("Color Boost", "ChannelA")) a = keyFile.get_integer ("Color Boost", "ChannelA"); + if (keyFile.has_key ("Color Boost", "ChannelB")) b = keyFile.get_integer ("Color Boost", "ChannelB"); + colorBoost.amount = (a+b) / 2; + } + if (keyFile.has_key ("Color Boost", "AvoidColorClipping")) colorBoost.avoidclip = keyFile.get_boolean ("Color Boost", "AvoidColorClipping"); + if (keyFile.has_key ("Color Boost", "SaturationLimiter")) colorBoost.enable_saturationlimiter= keyFile.get_boolean ("Color Boost", "SaturationLimiter"); + if (keyFile.has_key ("Color Boost", "SaturationLimit")) colorBoost.saturationlimit = keyFile.get_double ("Color Boost", "SaturationLimit"); +} + + // load wb +if (keyFile.has_group ("White Balance")) { + if (keyFile.has_key ("White Balance", "Setting")) wb.method = keyFile.get_string ("White Balance", "Setting"); + if (keyFile.has_key ("White Balance", "Temperature")) wb.temperature = keyFile.get_integer ("White Balance", "Temperature"); + if (keyFile.has_key ("White Balance", "Green")) wb.green = keyFile.get_double ("White Balance", "Green"); +} + + // load colorShift +if (keyFile.has_group ("Color Shift")) { + if (keyFile.has_key ("Color Shift", "ChannelA")) colorShift.a = keyFile.get_double ("Color Shift", "ChannelA"); + if (keyFile.has_key ("Color Shift", "ChannelB")) colorShift.b = keyFile.get_double ("Color Shift", "ChannelB"); +} + + // load lumaDenoise +if (keyFile.has_group ("Luminance Denoising")) { + if (keyFile.has_key ("Luminance Denoising", "Enabled")) lumaDenoise.enabled = keyFile.get_boolean ("Luminance Denoising", "Enabled"); + if (keyFile.has_key ("Luminance Denoising", "Radius")) lumaDenoise.radius = keyFile.get_double ("Luminance Denoising", "Radius"); + if (keyFile.has_key ("Luminance Denoising", "EdgeTolerance")) lumaDenoise.edgetolerance = keyFile.get_integer ("Luminance Denoising", "EdgeTolerance"); +} + + // load colorDenoise +if (keyFile.has_group ("Chrominance Denoising")) { + if (keyFile.has_key ("Chrominance Denoising", "Enabled")) colorDenoise.enabled = keyFile.get_boolean ("Chrominance Denoising", "Enabled"); + if (keyFile.has_key ("Chrominance Denoising", "Radius")) colorDenoise.amount = 10*keyFile.get_double ("Chrominance Denoising", "Radius"); + else if (keyFile.has_key ("Chrominance Denoising", "Amount")) colorDenoise.amount = keyFile.get_integer ("Chrominance Denoising", "Amount"); +} + + // load sh +if (keyFile.has_group ("Shadows & Highlights")) { + if (keyFile.has_key ("Shadows & Highlights", "Enabled")) sh.enabled = keyFile.get_boolean ("Shadows & Highlights", "Enabled"); + if (keyFile.has_key ("Shadows & Highlights", "HighQuality")) sh.hq = keyFile.get_boolean ("Shadows & Highlights", "HighQuality"); + if (keyFile.has_key ("Shadows & Highlights", "Highlights")) sh.highlights = keyFile.get_integer ("Shadows & Highlights", "Highlights"); + if (keyFile.has_key ("Shadows & Highlights", "HighlightTonalWidth")) sh.htonalwidth = keyFile.get_integer ("Shadows & Highlights", "HighlightTonalWidth"); + if (keyFile.has_key ("Shadows & Highlights", "Shadows")) sh.shadows = keyFile.get_integer ("Shadows & Highlights", "Shadows"); + if (keyFile.has_key ("Shadows & Highlights", "ShadowTonalWidth")) sh.stonalwidth = keyFile.get_integer ("Shadows & Highlights", "ShadowTonalWidth"); + if (keyFile.has_key ("Shadows & Highlights", "LocalContrast")) sh.localcontrast = keyFile.get_integer ("Shadows & Highlights", "LocalContrast"); + if (keyFile.has_key ("Shadows & Highlights", "Radius")) sh.radius = keyFile.get_integer ("Shadows & Highlights", "Radius"); +} + + // load crop +if (keyFile.has_group ("Crop")) { + if (keyFile.has_key ("Crop", "Enabled")) crop.enabled = keyFile.get_boolean ("Crop", "Enabled"); + if (keyFile.has_key ("Crop", "X")) crop.x = keyFile.get_integer ("Crop", "X"); + if (keyFile.has_key ("Crop", "Y")) crop.y = keyFile.get_integer ("Crop", "Y"); + if (keyFile.has_key ("Crop", "W")) crop.w = keyFile.get_integer ("Crop", "W"); + if (keyFile.has_key ("Crop", "H")) crop.h = keyFile.get_integer ("Crop", "H"); + if (keyFile.has_key ("Crop", "FixedRatio")) crop.fixratio = keyFile.get_boolean ("Crop", "FixedRatio"); + if (keyFile.has_key ("Crop", "Ratio")) crop.ratio = keyFile.get_string ("Crop", "Ratio"); + if (keyFile.has_key ("Crop", "Orientation"))crop.orientation= keyFile.get_string ("Crop", "Orientation"); + if (keyFile.has_key ("Crop", "Guide")) crop.guide = keyFile.get_string ("Crop", "Guide"); +} + + // load coarse +if (keyFile.has_group ("Coarse Transformation")) { + if (keyFile.has_key ("Coarse Transformation", "Rotate")) coarse.rotate = keyFile.get_integer ("Coarse Transformation", "Rotate"); + if (keyFile.has_key ("Coarse Transformation", "HorizontalFlip")) coarse.hflip = keyFile.get_boolean ("Coarse Transformation", "HorizontalFlip"); + if (keyFile.has_key ("Coarse Transformation", "VerticalFlip")) coarse.vflip = keyFile.get_boolean ("Coarse Transformation", "VerticalFlip"); +} + + // load rotate +if (keyFile.has_group ("Rotation")) { + if (keyFile.has_key ("Rotation", "Degree")) rotate.degree = keyFile.get_double ("Rotation", "Degree"); + if (keyFile.has_key ("Rotation", "Fill")) rotate.fill = keyFile.get_double ("Rotation", "Fill"); +} + + // load distortion +if (keyFile.has_group ("Distortion")) { + if (keyFile.has_key ("Distortion", "Amount")) distortion.amount = keyFile.get_double ("Distortion", "Amount"); +} + + // load c/a correction +if (keyFile.has_group ("CACorrection")) { + if (keyFile.has_key ("CACorrection", "Red")) cacorrection.red = keyFile.get_double ("CACorrection", "Red"); + if (keyFile.has_key ("CACorrection", "Blue")) cacorrection.blue = keyFile.get_double ("CACorrection", "Blue"); +} + + // load vignetting correction +if (keyFile.has_group ("Vignetting Correction")) { + if (keyFile.has_key ("Vignetting Correction", "Amount")) vignetting.amount = keyFile.get_integer ("Vignetting Correction", "Amount"); + if (keyFile.has_key ("Vignetting Correction", "Radius")) vignetting.radius = keyFile.get_integer ("Vignetting Correction", "Radius"); +} + + // load highlight recovery settings +if (keyFile.has_group ("HLRecovery")) { + if (keyFile.has_key ("HLRecovery", "Enabled")) hlrecovery.enabled = keyFile.get_boolean ("HLRecovery", "Enabled"); + if (keyFile.has_key ("HLRecovery", "Method")) hlrecovery.method = keyFile.get_string ("HLRecovery", "Method"); +} + // load resize settings +if (keyFile.has_group ("Resize")) { + if (keyFile.has_key ("Resize", "Enabled")) resize.enabled = keyFile.get_boolean ("Resize", "Enabled"); + if (keyFile.has_key ("Resize", "Scale")) resize.scale = keyFile.get_double ("Resize", "Scale"); + if (keyFile.has_key ("Resize", "Method")) resize.method = keyFile.get_string ("Resize", "Method"); + if (keyFile.has_key ("Resize", "DataSpecified")) resize.dataspec = keyFile.get_integer ("Resize", "DataSpecified"); + if (keyFile.has_key ("Resize", "Width")) resize.width = keyFile.get_integer ("Resize", "Width"); + if (keyFile.has_key ("Resize", "Height")) resize.height = keyFile.get_integer ("Resize", "Height"); +} + + // load color management settings +if (keyFile.has_group ("Color Management")) { + if (keyFile.has_key ("Color Management", "InputProfile")) icm.input = keyFile.get_string ("Color Management", "InputProfile"); + if (keyFile.has_key ("Color Management", "ApplyGammaBeforeInputProfile")) icm.gammaOnInput = keyFile.get_boolean ("Color Management", "ApplyGammaBeforeInputProfile"); + if (keyFile.has_key ("Color Management", "WorkingProfile")) icm.working = keyFile.get_string ("Color Management", "WorkingProfile"); + if (keyFile.has_key ("Color Management", "OutputProfile")) icm.output = keyFile.get_string ("Color Management", "OutputProfile"); +} + + // load exif change settings +if (keyFile.has_group ("Exif")) { + std::vector keys = keyFile.get_keys ("Exif"); + exif.resize (keys.size()); + for (int i=0; i keys = keyFile.get_keys ("IPTC"); + iptc.resize (keys.size()); + for (int i=0; i%s\n", e.what().c_str()); + } + catch (...) { + printf ("-->ismeretlen exception!\n"); + return 1; + } +} + +bool operator==(const ExifPair& a, const ExifPair& b) { + + return a.field == b.field && a.value == b.value; +} + +bool operator==(const IPTCPair& a, const IPTCPair& b) { + + return a.field == b.field && a.values == b.values; +} +bool ProcParams::operator== (const ProcParams& other) { + + return + toneCurve.curve == other.toneCurve.curve + && toneCurve.brightness == other.toneCurve.brightness + && toneCurve.black == other.toneCurve.black + && toneCurve.contrast == other.toneCurve.contrast + && toneCurve.shcompr == other.toneCurve.shcompr + && toneCurve.hlcompr == other.toneCurve.hlcompr + && toneCurve.autoexp == other.toneCurve.autoexp + && toneCurve.clip == other.toneCurve.clip + && toneCurve.expcomp == other.toneCurve.expcomp + && lumaCurve.curve == other.lumaCurve.curve + && lumaCurve.brightness == other.lumaCurve.brightness + && lumaCurve.contrast == other.lumaCurve.contrast + && sharpening.enabled == other.sharpening.enabled + && sharpening.radius == other.sharpening.radius + && sharpening.amount == other.sharpening.amount + && sharpening.threshold == other.sharpening.threshold + && sharpening.edgesonly == other.sharpening.edgesonly + && sharpening.edges_radius == other.sharpening.edges_radius + && sharpening.edges_tolerance == other.sharpening.edges_tolerance + && sharpening.halocontrol == other.sharpening.halocontrol + && sharpening.halocontrol_amount== other.sharpening.halocontrol_amount + && sharpening.method == other.sharpening.method + && sharpening.deconvamount == other.sharpening.deconvamount + && sharpening.deconvradius == other.sharpening.deconvradius + && sharpening.deconviter == other.sharpening.deconviter + && sharpening.deconvdamping == other.sharpening.deconvdamping + && colorBoost.amount == other.colorBoost.amount + && colorBoost.avoidclip == other.colorBoost.avoidclip + && colorBoost.enable_saturationlimiter == other.colorBoost.enable_saturationlimiter + && colorBoost.saturationlimit == other.colorBoost.saturationlimit + && wb.method == other.wb.method + && wb.green == other.wb.green + && wb.temperature == other.wb.temperature + && colorShift.a == other.colorShift.a + && colorShift.b == other.colorShift.b + && lumaDenoise.enabled == other.lumaDenoise.enabled + && lumaDenoise.radius == other.lumaDenoise.radius + && lumaDenoise.edgetolerance == other.lumaDenoise.edgetolerance + && colorDenoise.enabled == other.colorDenoise.enabled + && colorDenoise.radius == other.colorDenoise.radius + && colorDenoise.edgetolerance == other.colorDenoise.edgetolerance + && colorDenoise.edgesensitive == other.colorDenoise.edgesensitive + && sh.enabled == other.sh.enabled + && sh.hq == other.sh.hq + && sh.highlights == other.sh.highlights + && sh.htonalwidth == other.sh.htonalwidth + && sh.shadows == other.sh.shadows + && sh.stonalwidth == other.sh.stonalwidth + && sh.localcontrast == other.sh.localcontrast + && sh.radius == other.sh.radius + && crop.enabled == other.crop.enabled + && crop.x == other.crop.x + && crop.y == other.crop.y + && crop.w == other.crop.w + && crop.h == other.crop.h + && crop.fixratio == other.crop.fixratio + && crop.ratio == other.crop.ratio + && crop.orientation == other.crop.orientation + && crop.guide == other.crop.guide + && coarse.rotate == other.coarse.rotate + && coarse.hflip == other.coarse.hflip + && coarse.vflip == other.coarse.vflip + && rotate.degree == other.rotate.degree + && rotate.fill == other.rotate.fill + && distortion.amount == other.distortion.amount + && cacorrection.red == other.cacorrection.red + && cacorrection.blue == other.cacorrection.blue + && vignetting.amount == other.vignetting.amount + && vignetting.radius == other.vignetting.radius + && !memcmp (&chmixer.red, &other.chmixer.red, 3*sizeof(int)) + && !memcmp (&chmixer.green, &other.chmixer.green, 3*sizeof(int)) + && !memcmp (&chmixer.blue, &other.chmixer.blue, 3*sizeof(int)) + && hlrecovery.enabled == other.hlrecovery.enabled + && hlrecovery.method == other.hlrecovery.method + && resize.scale == other.resize.scale + && resize.method == other.resize.method + && resize.dataspec == other.resize.dataspec + && resize.width == other.resize.width + && resize.height == other.resize.height + && icm.input == other.icm.input + && icm.gammaOnInput == other.icm.gammaOnInput + && icm.working == other.icm.working + && icm.output == other.icm.output + && exif==other.exif + && iptc==other.iptc; +} + +bool ProcParams::operator!= (const ProcParams& other) { + + return !(*this==other); +} +} +} + diff --git a/rtengine/procparams.h b/rtengine/procparams.h new file mode 100644 index 000000000..31449afbf --- /dev/null +++ b/rtengine/procparams.h @@ -0,0 +1,349 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _PROCPARAMS_H_ +#define _PROCPARAMS_H_ + +#include +#include + +namespace rtengine { +namespace procparams { + +/** + * Parameters of the tone curve + */ +class ToneCurveParams { + + public: + bool autoexp; + double clip; + double expcomp; + std::vector curve; + int brightness; + int black; + int contrast; + int shcompr; + int hlcompr; +}; + +/** + * Parameters of the luminance curve + */ +class LCurveParams { + + public: + std::vector curve; + int brightness; + int contrast; +}; + +/** + * Parameters of the sharpening + */ +class SharpeningParams { + + public: + bool enabled; + double radius; + int amount; + int threshold; + bool edgesonly; + double edges_radius; + int edges_tolerance; + bool halocontrol; + int halocontrol_amount; + + Glib::ustring method; + int deconvamount; + double deconvradius; + int deconviter; + int deconvdamping; +}; + +/** + * Parameters of the color boost + */ +class ColorBoostParams { + + public: + int amount; + bool avoidclip; + bool enable_saturationlimiter; + double saturationlimit; +}; + +/** + * Parameters of the white balance adjustments + */ +class WBParams { + + public: + Glib::ustring method; + int temperature; + double green; +}; + +/** + * Parameters of the color shift + */ +class ColorShiftParams { + + public: + double a; + double b; +}; + +/** + * Parameters of the luminance denoising + */ +class LumaDenoiseParams { + + public: + bool enabled; + double radius; + int edgetolerance; +}; + +/** + * Parameters of the color denoising + */ +class ColorDenoiseParams { + + public: + bool enabled; + double radius; + int edgetolerance; + bool edgesensitive; + int amount; +}; + +/** + * Parameters of the shadow/highlight enhancement + */ +class SHParams { + + public: + bool enabled; + bool hq; + int highlights; + int htonalwidth; + int shadows; + int stonalwidth; + int localcontrast; + int radius; +}; + +/** + * Parameters of the cropping + */ +class CropParams { + + public: + bool enabled; + int x; + int y; + int w; + int h; + bool fixratio; + Glib::ustring ratio; + Glib::ustring orientation; + Glib::ustring guide; +}; + +/** + * Parameters of the coarse transformations like 90 deg rotations and h/v flipping + */ +class CoarseTransformParams { + + public: + int rotate; + bool hflip; + bool vflip; +}; + +/** + * Parameters of the rotation + */ +class RotateParams { + + public: + double degree; + bool fill; +}; + +/** + * Parameters of the distortion correction + */ +class DistortionParams { + + public: + double amount; +}; + +/** + * Parameters of the vignetting correction + */ +class VignettingParams { + + public: + int amount; + int radius; +}; + +/** + * Parameters of the color mixer + */ +class ChannelMixerParams { + + public: + int red[3]; + int green[3]; + int blue[3]; +}; + +/** + * Parameters of the c/a correction + */ +class CACorrParams { + + public: + double red; + double blue; +}; + +/** + * Parameters of the highlight recovery + */ +class HRecParams { + + public: + bool enabled; + Glib::ustring method; +}; + +/** + * Parameters of the resizing + */ +class ResizeParams { + + public: + bool enabled; + double scale; + Glib::ustring method; + int dataspec; + int width; + int height; +}; + +/** + * Parameters of the color spaces used during the processing + */ +class ColorManagementParams { + + public: + Glib::ustring input; + bool gammaOnInput; + Glib::ustring working; + Glib::ustring output; +}; + +/** + * A class representing a key/value for the exif metadata information + */ +class ExifPair { + + public: + Glib::ustring field; + Glib::ustring value; +}; + +/** + * The IPTC key/value pairs + */ +class IPTCPair { + + public: + Glib::ustring field; + std::vector values; +}; + +/** + * This class holds all the processing parameters applied on the images + */ +class ProcParams { + + public: + ToneCurveParams toneCurve; ///< Tone curve parameters + LCurveParams lumaCurve; ///< CIELAB luminance curve parameters + SharpeningParams sharpening; ///< Sharpening parameters + ColorBoostParams colorBoost; ///< Color boost parameters + WBParams wb; ///< White balance parameters + ColorShiftParams colorShift; ///< Color shift parameters + LumaDenoiseParams lumaDenoise; ///< Luminance denoising parameters + ColorDenoiseParams colorDenoise; ///< Color denoising parameters + SHParams sh; ///< Shadow/highlight enhancement parameters + CropParams crop; ///< Crop parameters + CoarseTransformParams coarse; ///< Coarse transformation (90, 180, 270 deg rotation, h/v flipping) parameters + RotateParams rotate; ///< Rotation parameters + DistortionParams distortion; ///< Lens distortion correction parameters + CACorrParams cacorrection; ///< Lens c/a correction parameters + VignettingParams vignetting; ///< Lens vignetting correction parameters + ChannelMixerParams chmixer; ///< Channel mixer parameters + HRecParams hlrecovery; ///< Highlight recovery parameters + ResizeParams resize; ///< Resize parameters + ColorManagementParams icm; ///< profiles/color spaces used during the image processing + std::vector exif; ///< List of modifications appplied on the exif tags of the input image + std::vector iptc; ///< The IPTC tags and values to be saved to the output image + int version; ///< Version of the file from which the parameters have been read + + /** + * The constructor only sets the hand-wired defaults. + */ + ProcParams (); + /** + * Sets the hand-wired defaults parameters. + */ + void setDefaults (); + /** + * Saves the parameters to a file. + * @param fname the name of the file + * @return Error code (=0 if no error) + */ + int save (Glib::ustring fname) const; + /** + * Loads the parameters from a file. + * @param fname the name of the file + * @return Error code (=0 if no error) + */ + int load (Glib::ustring fname); + + /** Creates a new instance of ProcParams. + * @return a pointer to the new ProcParams instance. */ + static ProcParams* create (); + + /** Destroys an instance of ProcParams. + * @param pp a pointer to the ProcParams instance to destroy. */ + static void destroy (ProcParams* pp); + + bool operator== (const ProcParams& other); + bool operator!= (const ProcParams& other); +}; +} +} +#endif diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc new file mode 100644 index 000000000..4fb9dd12a --- /dev/null +++ b/rtengine/rawimagesource.cc @@ -0,0 +1,3126 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rtengine { + +int loadRaw (const char* fname, struct RawImage* ri); + +extern const Settings* settings; + +#undef ABS +#undef MAX +#undef MIN +#undef DIST +#undef MAXVAL +#undef CLIP +#undef THREAD_PRIORITY_NORMAL + +#define ABS(a) ((a)<0?-(a):(a)) +#define MAX(a,b) ((a)<(b)?(b):(a)) +#define MIN(a,b) ((a)>(b)?(b):(a)) +#define DIST(a,b) (ABS(a-b)) +#define MAXVAL 0xffff +#define CLIP(a) ((a)>0?((a)allocation) + free (ri->allocation); + if (ri->data) + free (ri->data); + if (ri->profile_data) + free (ri->profile_data); + delete ri; + } + if (green) + freeArray(green, H); + if (red) + freeArray(red, H); + if (blue) + freeArray(blue, H); + + delete [] cache; + if (hrmap[0]!=NULL) { + int dh = H/HR_SCALE; + freeArray(hrmap[0], dh); + freeArray(hrmap[1], dh); + freeArray(hrmap[2], dh); + } + if (needhr) + freeArray(needhr, H); + if (hpmap) + freeArray(hpmap, H); + if (camProfile) + cmsCloseProfile (camProfile); + if (embProfile) + cmsCloseProfile (embProfile); +} + +void RawImageSource::transformRect (PreviewProps pp, int tran, int &ssx1, int &ssy1, int &width, int &height, int &fw) { + + pp.x += border; + pp.y += border; + + if (d1x) { + if ((tran & TR_ROT) == TR_R90 || (tran & TR_ROT) == TR_R270) { + pp.x /= 2; + pp.w = pp.w/2+1; + } + else { + pp.y /= 2; + pp.h = pp.h/2+1; + } + } + + int w = W, h = H; + if (fuji) { + w = ri->fuji_width * 2 + 1; + h = (H - ri->fuji_width)*2 + 1; + } + + int sw = w, sh = h; + if ((tran & TR_ROT) == TR_R90 || (tran & TR_ROT) == TR_R270) { + sw = h; + sh = w; + } + int ppx = pp.x, ppy = pp.y; + if (tran & TR_HFLIP) + ppx = sw - pp.x - pp.w; + if (tran & TR_VFLIP) + ppy = sh - pp.y - pp.h; + + int sx1 = ppx; + int sy1 = ppy; + int sx2 = ppx + pp.w; + int sy2 = ppy + pp.h; + + if ((tran & TR_ROT) == TR_R180) { + sx1 = w - ppx - pp.w; + sy1 = h - ppy - pp.h; + sx2 = sx1 + pp.w; + sy2 = sy1 + pp.h; + } + else if ((tran & TR_ROT) == TR_R90) { + sx1 = ppy; + sy1 = h - ppx - pp.w; + sx2 = sx1 + pp.h; + sy2 = sy1 + pp.w; + } + else if ((tran & TR_ROT) == TR_R270) { + sx1 = w - ppy - pp.h; + sy1 = ppx; + sx2 = sx1 + pp.h; + sy2 = sy1 + pp.w; + } + + if (fuji) { + // atszamoljuk a koordinatakat fuji-ra: + ssx1 = (sx1+sy1) / 2; + ssy1 = (sy1 - sx2 ) / 2 + ri->fuji_width; + int ssx2 = (sx2+sy2) / 2 + 1; + int ssy2 = (sy2 - sx1) / 2 + ri->fuji_width; + fw = (sx2 - sx1) / 2 / pp.skip; + width = (ssx2 - ssx1) / pp.skip + ((ssx2 - ssx1) % pp.skip > 0); + height = (ssy2 - ssy1) / pp.skip + ((ssy2 - ssy1) % pp.skip > 0); + } + else { + ssx1 = sx1; + ssy1 = sy1; + width = (sx2 - sx1) / pp.skip + ((sx2 - sx1) % pp.skip > 0); + height = (sy2 - sy1) / pp.skip + ((sy2 - sy1) % pp.skip > 0); + } +} + +void RawImageSource::getImage (ColorTemp ctemp, int tran, Image16* image, PreviewProps pp, HRecParams hrp, ColorManagementParams cmp) { + + isrcMutex.lock (); + + tran = defTransform (tran); + + // compute channel multipliers + double r, g, b, rm, gm, bm; + ctemp.getMultipliers (r, g, b); + rm = icoeff[0][0]*r + icoeff[0][1]*g + icoeff[0][2]*b; + gm = icoeff[1][0]*r + icoeff[1][1]*g + icoeff[1][2]*b; + bm = icoeff[2][0]*r + icoeff[2][1]*g + icoeff[2][2]*b; + rm = ri->camwb_red / rm; + gm = ri->camwb_green / gm; + bm = ri->camwb_blue / bm; + double mul_lum = 0.299*rm + 0.587*gm + 0.114*bm; + rm /= mul_lum; + gm /= mul_lum; + bm /= mul_lum; + + if (hrp.enabled) + defGain = log(ri->defgain) / log(2.0); + else { + defGain = 0.0; + rm *= ri->defgain; + gm *= ri->defgain; + bm *= ri->defgain; + } + + if (hrp.enabled==true && hrp.method=="Color" && hrmap[0]==NULL) + updateHLRecoveryMap_ColorPropagation (); + + // compute image area to render in order to provide the requested part of the image + int sx1, sy1, imwidth, imheight, fw; + transformRect (pp, tran, sx1, sy1, imwidth, imheight, fw); + + // check possible overflows + int maximwidth, maximheight; + if ((tran & TR_ROT) == TR_R90 || (tran & TR_ROT) == TR_R270) { + maximwidth = image->height; + maximheight = image->width; + } + else { + maximwidth = image->width; + maximheight = image->height; + } + if (d1x) + maximheight /= 2; + + // correct if overflow (very rare), but not fuji because it is corrected in transline + if (!fuji && imwidth>maximwidth) + imwidth = maximwidth; + if (!fuji && imheight>maximheight) + imheight = maximheight; + + // render the requested image part + unsigned short* red = new unsigned short[imwidth]; + unsigned short* grn = new unsigned short[imwidth]; + unsigned short* blue = new unsigned short[imwidth]; + + for (int i=sy1,ix=0; ixfilters && this->red && this->blue) { + for (int j=0,jx=sx1; jred[i][jx]); + grn[j] = CLIP(gm*green[i][jx]); + blue[j] = CLIP(bm*this->blue[i][jx]); + } + } else if(ri->filters) { + if (i==0) + interpolate_row_rb_mul_pp (red, blue, NULL, green[i], green[i+1], i, rm, gm, bm, sx1, imwidth, pp.skip); + else if (i==H-1) + interpolate_row_rb_mul_pp (red, blue, green[i-1], green[i], NULL, i, rm, gm, bm, sx1, imwidth, pp.skip); + else + interpolate_row_rb_mul_pp (red, blue, green[i-1], green[i], green[i+1], i, rm, gm, bm, sx1, imwidth, pp.skip); + + for (int j=0,jx=sx1; jdata[i][jx*3+0]); + grn[j] = CLIP(gm*ri->data[i][jx*3+1]); + blue[j] = CLIP(bm*ri->data[i][jx*3+2]); + } + } + + if (hrp.enabled) + hlRecovery (hrp.method, red, grn, blue, i, sx1, imwidth, pp.skip); + + transLine (red, grn, blue, ix, image, tran, imwidth, imheight, fw); + } + + delete [] red; + delete [] grn; + delete [] blue; + + if (fuji) { + int a = ((tran & TR_ROT) == TR_R90 && image->width%2==0) || ((tran & TR_ROT) == TR_R180 && image->height%2+image->width%2==1) || ((tran & TR_ROT) == TR_R270 && image->height%2==0); + // first row + for (int j=1+a; jwidth-1; j+=2) { + image->r[0][j] = (image->r[1][j] + image->r[0][j+1] + image->r[0][j-1]) / 3; + image->g[0][j] = (image->g[1][j] + image->g[0][j+1] + image->g[0][j-1]) / 3; + image->b[0][j] = (image->b[1][j] + image->b[0][j+1] + image->b[0][j-1]) / 3; + } + // other rows + for (int i=1; iheight-1; i++) { + for (int j=2-(a+i+1)%2; jwidth-1; j+=2) { + // edge-adaptive interpolation + double dh = (ABS(image->r[i][j+1] - image->r[i][j-1]) + ABS(image->g[i][j+1] - image->g[i][j-1]) + ABS(image->b[i][j+1] - image->b[i][j-1])) / 1.0; + double dv = (ABS(image->r[i+1][j] - image->r[i-1][j]) + ABS(image->g[i+1][j] - image->g[i-1][j]) + ABS(image->b[i+1][j] - image->b[i-1][j])) / 1.0; + double eh = 1.0 / (1.0 + dh); + double ev = 1.0 / (1.0 + dv); + image->r[i][j] = (eh * (image->r[i][j+1] + image->r[i][j-1]) + ev * (image->r[i+1][j] + image->r[i-1][j])) / (2.0 * (eh + ev)); + image->g[i][j] = (eh * (image->g[i][j+1] + image->g[i][j-1]) + ev * (image->g[i+1][j] + image->g[i-1][j])) / (2.0 * (eh + ev)); + image->b[i][j] = (eh * (image->b[i][j+1] + image->b[i][j-1]) + ev * (image->b[i+1][j] + image->b[i-1][j])) / (2.0 * (eh + ev)); + } + // first pixel + if (2-(a+i+1)%2==2) { + image->r[i][0] = (image->r[i+1][0] + image->r[i-1][0] + image->r[i][1]) / 3; + image->g[i][0] = (image->g[i+1][0] + image->g[i-1][0] + image->g[i][1]) / 3; + image->b[i][0] = (image->b[i+1][0] + image->b[i-1][0] + image->b[i][1]) / 3; + } + // last pixel + if (2-(a+i+image->width)%2==2) { + image->r[i][image->width-1] = (image->r[i+1][image->width-1] + image->r[i-1][image->width-1] + image->r[i][image->width-2]) / 3; + image->g[i][image->width-1] = (image->g[i+1][image->width-1] + image->g[i-1][image->width-1] + image->g[i][image->width-2]) / 3; + image->b[i][image->width-1] = (image->b[i+1][image->width-1] + image->b[i-1][image->width-1] + image->b[i][image->width-2]) / 3; + } + } + // last row + int b = (a==1 && image->height%2) || (a==0 && image->height%2==0); + for (int j=1+b; jwidth-1; j+=2) { + image->r[image->height-1][j] = (image->r[image->height-2][j] + image->r[image->height-1][j+1] + image->r[image->height-1][j-1]) / 3; + image->g[image->height-1][j] = (image->g[image->height-2][j] + image->g[image->height-1][j+1] + image->g[image->height-1][j-1]) / 3; + image->b[image->height-1][j] = (image->b[image->height-2][j] + image->b[image->height-1][j+1] + image->b[image->height-1][j-1]) / 3; + } + } + + // Flip if needed + if (tran & TR_HFLIP) + hflip (image); + if (tran & TR_VFLIP) + vflip (image); + + // Color correction + if (ri->filters && pp.skip==1) + correction_YIQ_LQ (image, settings->colorCorrectionSteps); + + // Applying postmul + colorSpaceConversion (image, cmp, embProfile, camProfile, cam, defGain); + + isrcMutex.unlock (); +} + +void RawImageSource::rotateLine (unsigned short* line, unsigned short** channel, int tran, int i, int w, int h) { + + if ((tran & TR_ROT) == TR_R180) + for (int j=0; j=0 && yheight && y>=0 && xwidth) { + image->r[image->height-1-y][image->width-1-x] = red[j]; + image->g[image->height-1-y][image->width-1-x] = green[j]; + image->b[image->height-1-y][image->width-1-x] = blue[j]; + } + } + } + else if ((tran & TR_ROT) == TR_R270) { + int end = MIN(h+fw-i, w-fw+i); + for (int j=start; j=0 && xheight && y>=0 && ywidth) { + image->r[image->height-1-x][y] = red[j]; + image->g[image->height-1-x][y] = green[j]; + image->b[image->height-1-x][y] = blue[j]; + } + } + } + else if ((tran & TR_ROT) == TR_R90) { + int end = MIN(h+fw-i, w-fw+i); + for (int j=start; j=0 && ywidth && y>=0 && xheight) { + image->r[x][image->width-1-y] = red[j]; + image->g[x][image->width-1-y] = green[j]; + image->b[x][image->width-1-y] = blue[j]; + } + } + } + else { + int end = MIN(h+fw-i, w-fw+i); + for (int j=start; j=0 && yheight && y>=0 && xwidth) { + image->r[y][x] = red[j]; + image->g[y][x] = green[j]; + image->b[y][x] = blue[j]; + } + } + } + } + // Nikon D1X vertical interpolation + coarse rotation + else if (d1x) { + // copy new pixels + if ((tran & TR_ROT) == TR_R180) { + for (int j=0; jr[2*imheight-2-2*i][imwidth-1-j] = red[j]; + image->g[2*imheight-2-2*i][imwidth-1-j] = green[j]; + image->b[2*imheight-2-2*i][imwidth-1-j] = blue[j]; + } + + if (i==1 || i==2) { // linear interpolation + int row = 2*imheight-1-2*i; + for (int j=0; jr[row][col] = (red[j] + image->r[row+1][col]) >> 1; + image->g[row][col] = (green[j] + image->g[row+1][col]) >> 1; + image->b[row][col] = (blue[j] + image->b[row+1][col]) >> 1; + } + } + else if (i==imheight-1) { + int row = 2*imheight-1-2*i; + for (int j=0; jr[row][col] = (red[j] + image->r[row+1][col]) >> 1; + image->g[row][col] = (green[j] + image->g[row+1][col]) >> 1; + image->b[row][col] = (blue[j] + image->b[row+1][col]) >> 1; + } + row = 2*imheight-1-2*i+2; + for (int j=0; jr[row][col] = (red[j] + image->r[row+1][col]) >> 1; + image->g[row][col] = (green[j] + image->g[row+1][col]) >> 1; + image->b[row][col] = (blue[j] + image->b[row+1][col]) >> 1; + } + } + else if (i>2 && ir[row][col] = CLIP((int)(-0.0625*red[j] + 0.5625*image->r[row-1][col] + 0.5625*image->r[row+1][col] - 0.0625*image->r[row+3][col])); + image->g[row][col] = CLIP((int)(-0.0625*green[j] + 0.5625*image->g[row-1][col] + 0.5625*image->g[row+1][col] - 0.0625*image->g[row+3][col])); + image->b[row][col] = CLIP((int)(-0.0625*blue[j] + 0.5625*image->b[row-1][col] + 0.5625*image->b[row+1][col] - 0.0625*image->b[row+3][col])); + } + } + } + else if ((tran & TR_ROT) == TR_R90) { + for (int j=0; jr[j][2*imheight-2-2*i] = red[j]; + image->g[j][2*imheight-2-2*i] = green[j]; + image->b[j][2*imheight-2-2*i] = blue[j]; + } + if (i==1 || i==2) { // linear interpolation + int col = 2*imheight-1-2*i; + for (int j=0; jr[j][col] = (red[j] + image->r[j][col+1]) >> 1; + image->g[j][col] = (green[j] + image->g[j][col+1]) >> 1; + image->b[j][col] = (blue[j] + image->b[j][col+1]) >> 1; + } + } + else if (i==imheight-1) { + int col = 2*imheight-1-2*i; + for (int j=0; jr[j][col] = (red[j] + image->r[j][col+1]) >> 1; + image->g[j][col] = (green[j] + image->g[j][col+1]) >> 1; + image->b[j][col] = (blue[j] + image->b[j][col+1]) >> 1; + } + col = 2*imheight-1-2*i+2; + for (int j=0; jr[j][col] = (red[j] + image->r[j][col+1]) >> 1; + image->g[j][col] = (green[j] + image->g[j][col+1]) >> 1; + image->b[j][col] = (blue[j] + image->b[j][col+1]) >> 1; + } + } + else if (i>2 && ir[j][col] = CLIP((int)(-0.0625*red[j] + 0.5625*image->r[j][col-1] + 0.5625*image->r[j][col+1] - 0.0625*image->r[j][col+3])); + image->g[j][col] = CLIP((int)(-0.0625*green[j] + 0.5625*image->g[j][col-1] + 0.5625*image->g[j][col+1] - 0.0625*image->g[j][col+3])); + image->b[j][col] = CLIP((int)(-0.0625*blue[j] + 0.5625*image->b[j][col-1] + 0.5625*image->b[j][col+1] - 0.0625*image->b[j][col+3])); + } + } + } + else if ((tran & TR_ROT) == TR_R270) { + for (int j=0; jr[imwidth-1-j][2*i] = red[j]; + image->g[imwidth-1-j][2*i] = green[j]; + image->b[imwidth-1-j][2*i] = blue[j]; + } + if (i==1 || i==2) { // linear interpolation + for (int j=0; jr[row][2*i-1] = (red[j] + image->r[row][2*i-2]) >> 1; + image->g[row][2*i-1] = (green[j] + image->g[row][2*i-2]) >> 1; + image->b[row][2*i-1] = (blue[j] + image->b[row][2*i-2]) >> 1; + } + } + else if (i==imheight-1) { + for (int j=0; jr[row][2*i-1] = (red[j] + image->r[row][2*i-2]) >> 1; + image->g[row][2*i-1] = (green[j] + image->g[row][2*i-2]) >> 1; + image->b[row][2*i-1] = (blue[j] + image->b[row][2*i-2]) >> 1; + image->r[row][2*i-3] = (image->r[row][2*i-2] + image->r[row][2*i-4]) >> 1; + image->g[row][2*i-3] = (image->g[row][2*i-2] + image->g[row][2*i-4]) >> 1; + image->b[row][2*i-3] = (image->b[row][2*i-2] + image->b[row][2*i-4]) >> 1; + } + } + else if (i>0 && ir[row][2*i-3] = CLIP((int)(-0.0625*red[j] + 0.5625*image->r[row][2*i-2] + 0.5625*image->r[row][2*i-4] - 0.0625*image->r[row][2*i-6])); + image->g[row][2*i-3] = CLIP((int)(-0.0625*green[j] + 0.5625*image->g[row][2*i-2] + 0.5625*image->g[row][2*i-4] - 0.0625*image->g[row][2*i-6])); + image->b[row][2*i-3] = CLIP((int)(-0.0625*blue[j] + 0.5625*image->b[row][2*i-2] + 0.5625*image->b[row][2*i-4] - 0.0625*image->b[row][2*i-6])); + } + } + } + else { + rotateLine (red, image->r, tran, 2*i, imwidth, imheight); + rotateLine (green, image->g, tran, 2*i, imwidth, imheight); + rotateLine (blue, image->b, tran, 2*i, imwidth, imheight); + + if (i==1 || i==2) { // linear interpolation + for (int j=0; jr[2*i-1][j] = (red[j] + image->r[2*i-2][j]) >> 1; + image->g[2*i-1][j] = (green[j] + image->g[2*i-2][j]) >> 1; + image->b[2*i-1][j] = (blue[j] + image->b[2*i-2][j]) >> 1; + } + } + else if (i==imheight-1) { + for (int j=0; jr[2*i-3][j] = (image->r[2*i-4][j] + image->r[2*i-2][j]) >> 1; + image->g[2*i-3][j] = (image->g[2*i-4][j] + image->g[2*i-2][j]) >> 1; + image->b[2*i-3][j] = (image->b[2*i-4][j] + image->b[2*i-2][j]) >> 1; + image->r[2*i-1][j] = (red[j] + image->r[2*i-2][j]) >> 1; + image->g[2*i-1][j] = (green[j] + image->g[2*i-2][j]) >> 1; + image->b[2*i-1][j] = (blue[j] + image->b[2*i-2][j]) >> 1; + } + } + else if (i>2 && ir[2*i-3][j] = CLIP((int)(-0.0625*red[j] + 0.5625*image->r[2*i-2][j] + 0.5625*image->r[2*i-4][j] - 0.0625*image->r[2*i-6][j])); + image->g[2*i-3][j] = CLIP((int)(-0.0625*green[j] + 0.5625*image->g[2*i-2][j] + 0.5625*image->g[2*i-4][j] - 0.0625*image->g[2*i-6][j])); + image->b[2*i-3][j] = CLIP((int)(-0.0625*blue[j] + 0.5625*image->b[2*i-2][j] + 0.5625*image->b[2*i-4][j] - 0.0625*image->b[2*i-6][j])); + } + } + } + } + // other (conventional) CCD coarse rotation + else { + rotateLine (red, image->r, tran, i, imwidth, imheight); + rotateLine (green, image->g, tran, i, imwidth, imheight); + rotateLine (blue, image->b, tran, i, imwidth, imheight); + } +} + +void RawImageSource::getFullSize (int& w, int& h, int tr) { + + tr = defTransform (tr); + + if (fuji) { + w = ri->fuji_width * 2 + 1; + h = (H - ri->fuji_width)*2 + 1; + } + else if (d1x) { + w = W; + h = 2*H-1; + } + else { + w = W; + h = H; + } + + if ((tr & TR_ROT) == TR_R90 || (tr & TR_ROT) == TR_R270) { + int tmp = w; + w = h; + h = tmp; + } + w -= 2 * border; + h -= 2 * border; +} + +void RawImageSource::getSize (int tran, PreviewProps pp, int& w, int& h) { + + tran = defTransform (tran); + +// if (fuji) { +// return; +// } +// else if (d1x) { +// return; +// } +// else { + w = pp.w / pp.skip + (pp.w % pp.skip > 0); + h = pp.h / pp.skip + (pp.h % pp.skip > 0); +// } +} + +void RawImageSource::hflip (Image16* image) { + int width = image->width; + int height = image->height; + + unsigned short* rowr = new unsigned short[width]; + unsigned short* rowg = new unsigned short[width]; + unsigned short* rowb = new unsigned short[width]; + for (int i=0; ir[i][width-1-j]; + rowg[j] = image->g[i][width-1-j]; + rowb[j] = image->b[i][width-1-j]; + } + memcpy (image->r[i], rowr, width*sizeof(unsigned short)); + memcpy (image->g[i], rowg, width*sizeof(unsigned short)); + memcpy (image->b[i], rowb, width*sizeof(unsigned short)); + } + delete [] rowr; + delete [] rowg; + delete [] rowb; +} + +void RawImageSource::vflip (Image16* image) { + int width = image->width; + int height = image->height; + + register unsigned short tmp; + for (int i=0; ir[i][j]; + image->r[i][j] = image->r[height-1-i][j]; + image->r[height-1-i][j] = tmp; + tmp = image->g[i][j]; + image->g[i][j] = image->g[height-1-i][j]; + image->g[height-1-i][j] = tmp; + tmp = image->b[i][j]; + image->b[i][j] = image->b[height-1-i][j]; + image->b[height-1-i][j] = tmp; + } +} + +void RawImageSource::inverse33 (double (*coeff)[3], double (*icoeff)[3]) { + double nom = coeff[0][2]*coeff[1][1]*coeff[2][0] - coeff[0][1]*coeff[1][2]*coeff[2][0] - coeff[0][2]*coeff[1][0]*coeff[2][1] + coeff[0][0]*coeff[1][2]*coeff[2][1] + coeff[0][1]*coeff[1][0]*coeff[2][2] - coeff[0][0]*coeff[1][1]*coeff[2][2]; + icoeff[0][0] = (coeff[1][2]*coeff[2][1]-coeff[1][1]*coeff[2][2]) / nom; + icoeff[0][1] = -(coeff[0][2]*coeff[2][1]-coeff[0][1]*coeff[2][2]) / nom; + icoeff[0][2] = (coeff[0][2]*coeff[1][1]-coeff[0][1]*coeff[1][2]) / nom; + icoeff[1][0] = -(coeff[1][2]*coeff[2][0]-coeff[1][0]*coeff[2][2]) / nom; + icoeff[1][1] = (coeff[0][2]*coeff[2][0]-coeff[0][0]*coeff[2][2]) / nom; + icoeff[1][2] = -(coeff[0][2]*coeff[1][0]-coeff[0][0]*coeff[1][2]) / nom; + icoeff[2][0] = (coeff[1][1]*coeff[2][0]-coeff[1][0]*coeff[2][1]) / nom; + icoeff[2][1] = -(coeff[0][1]*coeff[2][0]-coeff[0][0]*coeff[2][1]) / nom; + icoeff[2][2] = (coeff[0][1]*coeff[1][0]-coeff[0][0]*coeff[1][1]) / nom; +} + +int RawImageSource::load (Glib::ustring fname) { + + fileName = fname; + + if (plistener) { + plistener->setProgressStr ("Decoding..."); + plistener->setProgress (0.0); + } + + ri = new RawImage; + int res = loadRaw (fname.c_str(), ri); + if (res) + return res; + + if(red) { + delete red; + red = 0; + } + if(green) { + delete green; + green = 0; + } + if(blue) { + delete blue; + blue = 0; + } + + W = ri->width; + H = ri->height; + + d1x = !strcmp(ri->model, "D1X"); + fuji = ri->fuji_width; + if (d1x) + border = 8; + + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + coeff[i][j] = ri->coeff[i][j]; + + // compute inverse of the color transformation matrix + inverse33 (coeff, icoeff); + + double cam_r = coeff[0][0]*ri->camwb_red + coeff[0][1]*ri->camwb_green + coeff[0][2]*ri->camwb_blue; + double cam_g = coeff[1][0]*ri->camwb_red + coeff[1][1]*ri->camwb_green + coeff[1][2]*ri->camwb_blue; + double cam_b = coeff[2][0]*ri->camwb_red + coeff[2][1]*ri->camwb_green + coeff[2][2]*ri->camwb_blue; + + wb = ColorTemp (cam_r, cam_g, cam_b); + + double tr = icoeff[0][0] * cam_r + icoeff[0][1] * cam_g + icoeff[0][2] * cam_b; + double tg = icoeff[1][0] * cam_r + icoeff[1][1] * cam_g + icoeff[1][2] * cam_b; + double tb = icoeff[2][0] * cam_r + icoeff[2][1] * cam_g + icoeff[2][2] * cam_b; + + // create profile + memset (cam, 0, sizeof(cam)); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + cam[i][j] += coeff[k][i] * sRGB_d50[k][j]; + camProfile = iccStore.createFromMatrix (cam, false, "Camera"); + inverse33 (cam, icam); + + if (ri->profile_data) + embProfile = cmsOpenProfileFromMem (ri->profile_data, ri->profile_len); + + defGain = log(ri->defgain) / log(2.0); + + RawMetaDataLocation rml; + rml.exifBase = ri->exifbase; + rml.ciffBase = ri->ciff_base; + rml.ciffLength = ri->ciff_len; + + idata = new ImageData (fname, &rml); + + // check if it is an olympus E camera, if yes, compute G channel pre-compensation factors + if (((idata->getMake().size()>=7 && idata->getMake().substr(0,7)=="OLYMPUS" && idata->getModel()[0]=='E') || (idata->getMake().size()>=9 && idata->getMake().substr(0,7)=="Panasonic")) && settings->demosaicMethod!="vng4" && ri->filters) { + // global correction + int ng1=0, ng2=0; + double avgg1=0, avgg2=0; + for (int i=border; idata[i][j]; + ng1++; + } + else { + avgg2 += ri->data[i][j]; + ng2++; + } + } + double corrg1 = ((double)avgg1/ng1 + (double)avgg2/ng2) / 2.0 / ((double)avgg1/ng1); + double corrg2 = ((double)avgg1/ng1 + (double)avgg2/ng2) / 2.0 / ((double)avgg2/ng2); + for (int i=border; idata[i][j] = CLIP(ri->data[i][j] * (i%2 ? corrg2 : corrg1)); + + // local correction in a 9x9 box +/* unsigned short* corr_alloc = new unsigned short[W*H]; + unsigned short** corr_data = new unsigned short* [H]; + for (int i=0; iallocation, W*H*sizeof(unsigned short)); + for (int i=border; idata[i-4][j-4] + ri->data[i-4][j-2] + ri->data[i-4][j] + ri->data[i-4][j+2] + + ri->data[i-2][j-4] + ri->data[i-2][j-2] + ri->data[i-2][j] + ri->data[i-2][j+2] + + ri->data[i][j-4] + ri->data[i][j-2] + ri->data[i][j] + ri->data[i][j+2] + + ri->data[i+2][j-4] + ri->data[i+2][j-2] + ri->data[i+2][j] + ri->data[i+2][j+2]; + unsigned int ag2 = ri->data[i-3][j-3] + ri->data[i-3][j-1] + ri->data[i-3][j+1] + ri->data[i-3][j+1] + + ri->data[i-1][j-3] + ri->data[i-1][j-1] + ri->data[i-1][j+1] + ri->data[i-1][j+1] + + ri->data[i+1][j-3] + ri->data[i+1][j-1] + ri->data[i+1][j+1] + ri->data[i+1][j+1] + + ri->data[i+3][j-3] + ri->data[i+3][j-1] + ri->data[i+3][j+1] + ri->data[i+3][j+1]; + unsigned int val = (ri->data[i][j] + ri->data[i][j] * ag2 / ag1) / 2; + corr_data[i][j] = CLIP (val); + } + memcpy (ri->allocation, corr_alloc, W*H*sizeof(unsigned short)); + delete corr_alloc; + delete corr_data; +*/ + } + + if (ri->filters) { + // demosaic + if (settings->demosaicMethod=="hphd") + hphd_demosaic (); + else if (settings->demosaicMethod=="vng4") + vng4_demosaic (); + else if (settings->demosaicMethod=="ahd") + ahd_demosaic (); + else if (settings->demosaicMethod=="ppg") + ppg_demosaic (); + else if (settings->demosaicMethod=="dcb") + dcb_demosaic(settings->dcb_iterations, settings->dcb_enhance? 1:0); + else + eahd_demosaic (); + } + + + if (plistener) { + plistener->setProgressStr ("Ready."); + plistener->setProgress (1.0); + } + + return 0; +} + +int RawImageSource::defTransform (int tran) { + + int deg = ri->rotate_deg; + if ((tran & TR_ROT) == TR_R180) + deg += 180; + else if ((tran & TR_ROT) == TR_R90) + deg += 90; + else if ((tran & TR_ROT) == TR_R270) + deg += 270; + deg %= 360; + + int ret = 0; + if (deg==90) + ret |= TR_R90; + else if (deg==180) + ret |= TR_R180; + else if (deg==270) + ret |= TR_R270; + if (tran & TR_HFLIP) + ret |= TR_HFLIP; + if (tran & TR_VFLIP) + ret |= TR_VFLIP; + return ret; +} + +void RawImageSource::correction_YIQ_LQ_ (Image16* im, int row_from, int row_to) { + + int W = im->width; + + int** rbconv_Y = new int*[3]; + int** rbconv_I = new int*[3]; + int** rbconv_Q = new int*[3]; + int** rbout_I = new int*[3]; + int** rbout_Q = new int*[3]; + for (int i=0; i<3; i++) { + rbconv_Y[i] = new int[W]; + rbconv_I[i] = new int[W]; + rbconv_Q[i] = new int[W]; + rbout_I[i] = new int[W]; + rbout_Q[i] = new int[W]; + } + + int* row_I = new int[W]; + int* row_Q = new int[W]; + + int* pre1_I = new int[3]; + int* pre2_I = new int[3]; + int* post1_I = new int[3]; + int* post2_I = new int[3]; + int middle_I[6]; + int* pre1_Q = new int[3]; + int* pre2_Q = new int[3]; + int* post1_Q = new int[3]; + int* post2_Q = new int[3]; + int middle_Q[6]; + int* tmp; + + int ppx=0, px=(row_from-1)%3, cx=row_from%3, nx=0; + + convert_row_to_YIQ (im->r[row_from-1], im->g[row_from-1], im->b[row_from-1], rbconv_Y[px], rbconv_I[px], rbconv_Q[px], W); + convert_row_to_YIQ (im->r[row_from], im->g[row_from], im->b[row_from], rbconv_Y[cx], rbconv_I[cx], rbconv_Q[cx], W); + + for (int j=0; jr[i+1], im->g[i+1], im->b[i+1], rbconv_Y[nx], rbconv_I[nx], rbconv_Q[nx], W); + + SORT3(rbconv_I[px][0],rbconv_I[cx][0],rbconv_I[nx][0],pre1_I[0],pre1_I[1],pre1_I[2]); + SORT3(rbconv_I[px][1],rbconv_I[cx][1],rbconv_I[nx][1],pre2_I[0],pre2_I[1],pre2_I[2]); + SORT3(rbconv_Q[px][0],rbconv_Q[cx][0],rbconv_Q[nx][0],pre1_Q[0],pre1_Q[1],pre1_Q[2]); + SORT3(rbconv_Q[px][1],rbconv_Q[cx][1],rbconv_Q[nx][1],pre2_Q[0],pre2_Q[1],pre2_Q[2]); + + // median I channel + for (int j=1; jrow_from) { + for (int j=1; jr[i-1], im->g[i-1], im->b[i-1], rbconv_Y[px], row_I, row_Q, W); + } + } + // blur last 3 row and finalize H-1th row + for (int j=1; jr[row_to-1], im->g[row_to-1], im->b[row_to-1], rbconv_Y[cx], row_I, row_Q, W); + + freeArray(rbconv_Y, 3); + freeArray(rbconv_I, 3); + freeArray(rbconv_Q, 3); + freeArray(rbout_I, 3); + freeArray(rbout_Q, 3); + delete [] row_I; + delete [] row_Q; + delete [] pre1_I; + delete [] pre2_I; + delete [] post1_I; + delete [] post2_I; + delete [] pre1_Q; + delete [] pre2_Q; + delete [] post1_Q; + delete [] post2_Q; +} + + +void RawImageSource::correction_YIQ_LQ (Image16* im, int times) { + + if (im->height<4) + return; + + MyTime t1, t2; + + t1.set (); + for (int t=0; tdualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &RawImageSource::correction_YIQ_LQ_), im, 1, im->height/2), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &RawImageSource::correction_YIQ_LQ_), im, im->height/2, im->height-1), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else + correction_YIQ_LQ_ (im, 1, im->height-1); + } + t2.set (); +// printf ("Corrected. (%d)\n", t2.etime(t1)); +} + + + +void RawImageSource::convert_row_to_YIQ (unsigned short* r, unsigned short* g, unsigned short* b, int* Y, int* I, int* Q, int W) { + for (int j=0; j +void RawImageSource::convert_to_cielab_row (unsigned short* ar, unsigned short* ag, unsigned short* ab, short* oL, short* oa, short* ob) { + + for (int j=0; jthreshold) + oL[j] = 300.0*cache[(int)y]; + else + oL[j] = 300.0 * 903.3 * y / CMAXVAL; + + oa[j] = 32.0 * 500.0 * ((x>threshold ? cache[(int)x] : 7.787*x/CMAXVAL+16.0/116.0) - (y>threshold ? cache[(int)y] : 7.787*y/CMAXVAL+16.0/116.0)); + ob[j] = 32.0 * 200.0 * ((y>threshold ? cache[(int)y] : 7.787*y/CMAXVAL+16.0/116.0) - (z>threshold ? cache[(int)z] : 7.787*z/CMAXVAL+16.0/116.0)); + } +} + +void RawImageSource::interpolate_row_g (unsigned short* agh, unsigned short* agv, int i) { + + for (int j=0; jdata[i][j]; + agv[j] = ri->data[i][j]; + } + else { + int gh=0; + int gv=0; + if (j>1 && jdata[i][j-2] + 2*ri->data[i][j-1] + 2*ri->data[i][j] + 2*ri->data[i][j+1] -ri->data[i][j+2]) / 4; + int maxgh = MAX(ri->data[i][j-1], ri->data[i][j+1]); + int mingh = MIN(ri->data[i][j-1], ri->data[i][j+1]); + if (gh>maxgh) + gh = maxgh; + else if (ghdata[i][1]; + else if (j==1) + gh = (ri->data[i][0] + ri->data[i][2]) / 2; + else if (j==W-1) + gh = ri->data[i][W-2]; + else if (j==W-2) + gh = (ri->data[i][W-1] + ri->data[i][W-3]) / 2; + + if (i>1 && idata[i-2][j] + 2*ri->data[i-1][j] + 2*ri->data[i][j] + 2*ri->data[i+1][j] - ri->data[i+2][j]) / 4; + int maxgv = MAX(ri->data[i-1][j], ri->data[i+1][j]); + int mingv = MIN(ri->data[i-1][j], ri->data[i+1][j]); + if (gv>maxgv) + gv = maxgv; + else if (gvdata[1][j]; + else if (i==1) + gv = (ri->data[0][j] + ri->data[2][j]) / 2; + else if (i==H-1) + gv = ri->data[H-2][j]; + else if (i==H-2) + gv = (ri->data[H-1][j] + ri->data[H-3][j]) / 2; + + agh[j] = CLIP(gh); + agv[j] = CLIP(gv); + } + } +} + +void RawImageSource::interpolate_row_rb (unsigned short* ar, unsigned short* ab, unsigned short* pg, unsigned short* cg, unsigned short* ng, int i) { + if (ISRED(ri,i,0) || ISRED(ri,i,1)) { + // RGRGR or GRGRGR line + for (int j=0; jdata[i][j]; + // blue: cross interpolation + int b = 0; + int n = 0; + if (i>0 && j>0) { + b += ri->data[i-1][j-1] - pg[j-1]; + n++; + } + if (i>0 && jdata[i-1][j+1] - pg[j+1]; + n++; + } + if (i0) { + b += ri->data[i+1][j-1] - ng[j-1]; + n++; + } + if (idata[i+1][j+1] - ng[j+1]; + n++; + } + b = cg[j] + b / n; + ab[j] = CLIP(b); + } + else { + // linear R-G interp. horizontally + int r; + if (j==0) + r = cg[0] + ri->data[i][1] - cg[1]; + else if (j==W-1) + r = cg[W-1] + ri->data[i][W-2] - cg[W-2]; + else + r = cg[j] + (ri->data[i][j-1] - cg[j-1] + ri->data[i][j+1] - cg[j+1]) / 2; + ar[j] = CLIP(r); + // linear B-G interp. vertically + int b; + if (i==0) + b = ng[j] + ri->data[1][j] - cg[j]; + else if (i==H-1) + b = pg[j] + ri->data[H-2][j] - cg[j]; + else + b = cg[j] + (ri->data[i-1][j] - pg[j] + ri->data[i+1][j] - ng[j]) / 2; + ab[j] = CLIP(b); + } + } + } + else { + // BGBGB or GBGBGB line + for (int j=0; jdata[i][j]; + // blue: cross interpolation + int r = 0; + int n = 0; + if (i>0 && j>0) { + r += ri->data[i-1][j-1] - pg[j-1]; + n++; + } + if (i>0 && jdata[i-1][j+1] - pg[j+1]; + n++; + } + if (i0) { + r += ri->data[i+1][j-1] - ng[j-1]; + n++; + } + if (idata[i+1][j+1] - ng[j+1]; + n++; + } + r = cg[j] + r / n; + + ar[j] = CLIP(r); + } + else { + // linear B-G interp. horizontally + int b; + if (j==0) + b = cg[0] + ri->data[i][1] - cg[1]; + else if (j==W-1) + b = cg[W-1] + ri->data[i][W-2] - cg[W-2]; + else + b = cg[j] + (ri->data[i][j-1] - cg[j-1] + ri->data[i][j+1] - cg[j+1]) / 2; + ab[j] = CLIP(b); + // linear R-G interp. vertically + int r; + if (i==0) + r = ng[j] + ri->data[1][j] - cg[j]; + else if (i==H-1) + r = pg[j] + ri->data[H-2][j] - cg[j]; + else + r = cg[j] + (ri->data[i-1][j] - pg[j] + ri->data[i+1][j] - ng[j]) / 2; + ar[j] = CLIP(r); + } + } + } +} + +void RawImageSource::interpolate_row_rb_mul_pp (unsigned short* ar, unsigned short* ab, unsigned short* pg, unsigned short* cg, unsigned short* ng, int i, double r_mul, double g_mul, double b_mul, int x1, int width, int skip) { + + if (ISRED(ri,i,0) || ISRED(ri,i,1)) { + // RGRGR or GRGRGR line + for (int j=x1, jx=0; jxdata[i][j]); + // blue: cross interpolation + int b = 0; + int n = 0; + if (i>0 && j>0) { + b += b_mul*ri->data[i-1][j-1] - g_mul*pg[j-1]; + n++; + } + if (i>0 && jdata[i-1][j+1] - g_mul*pg[j+1]; + n++; + } + if (i0) { + b += b_mul*ri->data[i+1][j-1] - g_mul*ng[j-1]; + n++; + } + if (idata[i+1][j+1] - g_mul*ng[j+1]; + n++; + } + b = g_mul*cg[j] + b / n; + ab[jx] = CLIP(b); + } + else { + // linear R-G interp. horizontally + int r; + if (j==0) + r = g_mul*cg[0] + r_mul*ri->data[i][1] - g_mul*cg[1]; + else if (j==W-1) + r = g_mul*cg[W-1] + r_mul*ri->data[i][W-2] - g_mul*cg[W-2]; + else + r = g_mul*cg[j] + (r_mul*ri->data[i][j-1] - g_mul*cg[j-1] + r_mul*ri->data[i][j+1] - g_mul*cg[j+1]) / 2; + ar[jx] = CLIP(r); + // linear B-G interp. vertically + int b; + if (i==0) + b = g_mul*ng[j] + b_mul*ri->data[1][j] - g_mul*cg[j]; + else if (i==H-1) + b = g_mul*pg[j] + b_mul*ri->data[H-2][j] - g_mul*cg[j]; + else + b = g_mul*cg[j] + (b_mul*ri->data[i-1][j] - g_mul*pg[j] + b_mul*ri->data[i+1][j] - g_mul*ng[j]) / 2; + ab[jx] = CLIP(b); + } + } + } + else { + // BGBGB or GBGBGB line + for (int j=x1, jx=0; jxdata[i][j]); + // blue: cross interpolation + int r = 0; + int n = 0; + if (i>0 && j>0) { + r += r_mul*ri->data[i-1][j-1] - g_mul*pg[j-1]; + n++; + } + if (i>0 && jdata[i-1][j+1] - g_mul*pg[j+1]; + n++; + } + if (i0) { + r += r_mul*ri->data[i+1][j-1] - g_mul*ng[j-1]; + n++; + } + if (idata[i+1][j+1] - g_mul*ng[j+1]; + n++; + } + r = g_mul*cg[j] + r / n; + + ar[jx] = CLIP(r); + } + else { + // linear B-G interp. horizontally + int b; + if (j==0) + b = g_mul*cg[0] + b_mul*ri->data[i][1] - g_mul*cg[1]; + else if (j==W-1) + b = g_mul*cg[W-1] + b_mul*ri->data[i][W-2] - g_mul*cg[W-2]; + else + b = g_mul*cg[j] + (b_mul*ri->data[i][j-1] - g_mul*cg[j-1] + b_mul*ri->data[i][j+1] - g_mul*cg[j+1]) / 2; + ab[jx] = CLIP(b); + // linear R-G interp. vertically + int r; + if (i==0) + r = g_mul*ng[j] + r_mul*ri->data[1][j] - g_mul*cg[j]; + else if (i==H-1) + r = g_mul*pg[j] + r_mul*ri->data[H-2][j] - g_mul*cg[j]; + else + r = g_mul*cg[j] + (r_mul*ri->data[i-1][j] - g_mul*pg[j] + r_mul*ri->data[i+1][j] - g_mul*ng[j]) / 2; + ar[jx] = CLIP(r); + } + } + } +} + + +void RawImageSource::colorSpaceConversion (Image16* im, ColorManagementParams cmp, cmsHPROFILE embedded, cmsHPROFILE camprofile, double camMatrix[3][3], double& defgain) { + + if (cmp.input == "(none)") + return; + + MyTime t1, t2, t3; + + t1.set (); + + cmsHPROFILE in; + cmsHPROFILE out; + + Glib::ustring inProfile = cmp.input; + + if (inProfile=="(embedded)") { + if (embedded) + in = embedded; + else + in = camprofile; + } + else if (inProfile=="(camera)" || inProfile=="") + in = camprofile; + else { + in = iccStore.getProfile (inProfile); + if (in==NULL) + inProfile = "(camera)"; + } + + + if (inProfile=="(camera)" || inProfile=="" || (inProfile=="(embedded)" && !embedded)) { + // in this case we avoid using the slllllooooooowwww lcms + +// out = iccStore.workingSpace (wProfile); +// hTransform = cmsCreateTransform (in, TYPE_RGB_16_PLANAR, out, TYPE_RGB_16_PLANAR, settings->colorimetricIntent, cmsFLAGS_MATRIXINPUT | cmsFLAGS_MATRIXOUTPUT);//cmsFLAGS_MATRIXINPUT | cmsFLAGS_MATRIXOUTPUT); +// cmsDoTransform (hTransform, im->data, im->data, im->planestride/2); +// cmsDeleteTransform(hTransform); + TMatrix work = iccStore.workingSpaceInverseMatrix (cmp.working); + double mat[3][3] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + mat[i][j] += camMatrix[i][k] * work[k][j]; + + for (int i=0; iheight; i++) + for (int j=0; jwidth; j++) { + + int newr = mat[0][0]*im->r[i][j] + mat[1][0]*im->g[i][j] + mat[2][0]*im->b[i][j]; + int newg = mat[0][1]*im->r[i][j] + mat[1][1]*im->g[i][j] + mat[2][1]*im->b[i][j]; + int newb = mat[0][2]*im->r[i][j] + mat[1][2]*im->g[i][j] + mat[2][2]*im->b[i][j]; + + im->r[i][j] = CLIP(newr); + im->g[i][j] = CLIP(newg); + im->b[i][j] = CLIP(newb); + } + } + else { + out = iccStore.workingSpace (cmp.working); +// out = iccStore.workingSpaceGamma (wProfile); + lcmsMutex->lock (); + cmsHTRANSFORM hTransform = cmsCreateTransform (in, TYPE_RGB_16_PLANAR, out, TYPE_RGB_16_PLANAR, settings->colorimetricIntent, 0); + lcmsMutex->unlock (); + if (hTransform) { + if (cmp.gammaOnInput) { + double gd = pow (2.0, defgain); + defgain = 0.0; + for (int i=0; iheight; i++) + for (int j=0; jwidth; j++) { + im->r[i][j] = CurveFactory::gamma (CLIP(defgain*im->r[i][j])); + im->g[i][j] = CurveFactory::gamma (CLIP(defgain*im->g[i][j])); + im->b[i][j] = CurveFactory::gamma (CLIP(defgain*im->b[i][j])); + } + } + cmsDoTransform (hTransform, im->data, im->data, im->planestride/2); + } + else { + lcmsMutex->lock (); + hTransform = cmsCreateTransform (camprofile, TYPE_RGB_16_PLANAR, out, TYPE_RGB_16_PLANAR, settings->colorimetricIntent, 0); + lcmsMutex->unlock (); + cmsDoTransform (hTransform, im->data, im->data, im->planestride/2); + } + cmsDeleteTransform(hTransform); + } + t3.set (); +// printf ("ICM TIME: %d\n", t3.etime(t1)); +} + +void RawImageSource::eahd_demosaic () { + + if (plistener) { + plistener->setProgressStr ("Demosaicing..."); + plistener->setProgress (0.0); + } + + // prepare chache and constants for cielab conversion + lc00 = (0.412453 * coeff[0][0] + 0.357580 * coeff[1][0] + 0.180423 * coeff[2][0]) / 0.950456; + lc01 = (0.412453 * coeff[0][1] + 0.357580 * coeff[1][1] + 0.180423 * coeff[2][1]) / 0.950456; + lc02 = (0.412453 * coeff[0][2] + 0.357580 * coeff[1][2] + 0.180423 * coeff[2][2]) / 0.950456; + + lc10 = 0.212671 * coeff[0][0] + 0.715160 * coeff[1][0] + 0.072169 * coeff[2][0]; + lc11 = 0.212671 * coeff[0][1] + 0.715160 * coeff[1][1] + 0.072169 * coeff[2][1]; + lc12 = 0.212671 * coeff[0][2] + 0.715160 * coeff[1][2] + 0.072169 * coeff[2][2]; + + lc20 = (0.019334 * coeff[0][0] + 0.119193 * coeff[1][0] + 0.950227 * coeff[2][0]) / 1.088754; + lc21 = (0.019334 * coeff[0][1] + 0.119193 * coeff[1][1] + 0.950227 * coeff[2][1]) / 1.088754; + lc22 = (0.019334 * coeff[0][2] + 0.119193 * coeff[1][2] + 0.950227 * coeff[2][2]) / 1.088754; + + int maxindex = 2*65536; + cache = new double[maxindex]; + threshold = (int)(0.008856*CMAXVAL); + for (int i=0; isv) { // fixate horizontal pixel + dLmaph[dmi] = DIST(lLh[ix][j], lLh[idx][j+y]); + dCamaph[dmi] = DIST(lah[ix][j], lah[idx][j+y]); + dCbmaph[dmi] = DIST(lbh[ix][j], lbh[idx][j+y]); + dLmapv[dmi] = DIST(lLv[ix][j], lLh[idx][j+y]); + dCamapv[dmi] = DIST(lav[ix][j], lah[idx][j+y]); + dCbmapv[dmi] = DIST(lbv[ix][j], lbh[idx][j+y]); + } + else if (shdata[i-1][j]; + else { + hc = homh[imx][j]; + vc = homv[imx][j]; + if (hc > vc) + green[i-1][j] = gh[(i-1)%4][j]; + else if (hc < vc) + green[i-1][j] = gv[(i-1)%4][j]; + else + green[i-1][j] = (gh[(i-1)%4][j] + gv[(i-1)%4][j]) / 2; + } + } + + if (!(i%20) && plistener) + plistener->setProgress ((double)i / (H-2)); + } + // finish H-2th and H-1th row, homogenity value is still valailable + int hc, vc; + for (int i=H-1; i vc) + green[i-1][j] = gh[(i-1)%4][j]; + else if (hc < vc) + green[i-1][j] = gv[(i-1)%4][j]; + else + green[i-1][j] = (gh[(i-1)%4][j] + gv[(i-1)%4][j]) / 2; + } + + freeArray2(rh, 3); + freeArray2(gh, 4); + freeArray2(bh, 3); + freeArray2(rv, 3); + freeArray2(gv, 4); + freeArray2(bv, 3); + freeArray2(lLh, 3); + freeArray2(lah, 3); + freeArray2(lbh, 3); + freeArray2(homh, 3); + freeArray2(lLv, 3); + freeArray2(lav, 3); + freeArray2(lbv, 3); + freeArray2(homv, 3); +} + +void RawImageSource::hphd_vertical (float** hpmap, int col_from, int col_to) { + + float* temp = new float[MAX(W,H)]; + float* avg = new float[MAX(W,H)]; + float* dev = new float[MAX(W,H)]; + + memset (temp, 0, MAX(W,H)*sizeof(float)); + memset (avg, 0, MAX(W,H)*sizeof(float)); + memset (dev, 0, MAX(W,H)*sizeof(float)); + + for (int k=col_from; kdata[i-5][k] - 8*ri->data[i-4][k] + 27*ri->data[i-3][k] - 48*ri->data[i-2][k] + 42*ri->data[i-1][k] - + (ri->data[i+5][k] - 8*ri->data[i+4][k] + 27*ri->data[i+3][k] - 48*ri->data[i+2][k] + 42*ri->data[i+1][k])) / 100.0; + temp[i] = ABS(temp[i]); + } + for (int j=4; jdata[i][j-5] - 8*ri->data[i][j-4] + 27*ri->data[i][j-3] - 48*ri->data[i][j-2] + 42*ri->data[i][j-1] - + (ri->data[i][j+5] - 8*ri->data[i][j+4] + 27*ri->data[i][j+3] - 48*ri->data[i][j+2] + 42*ri->data[i][j+1])) / 100; + temp[j] = ABS(temp[j]); + } + for (int j=4; jhpmap[i][j] = 2; + else if (hpv < 0.8*hpmap[i][j]) + this->hpmap[i][j] = 1; + else + this->hpmap[i][j] = 0; + } + } + delete [] temp; + delete [] avg; + delete [] dev; +} + +void RawImageSource::hphd_green (int row_from, int row_to) { + + for (int i=row_from; idata[i][j]; + else { + if (this->hpmap[i][j]==1) { + int g2 = ri->data[i][j+1] + ((ri->data[i][j] - ri->data[i][j+2]) >> 1); + int g4 = ri->data[i][j-1] + ((ri->data[i][j] - ri->data[i][j-2]) >> 1); + + int dx = ri->data[i][j+1] - ri->data[i][j-1]; + int d1 = ri->data[i][j+3] - ri->data[i][j+1]; + int d2 = ri->data[i][j+2] - ri->data[i][j]; + int d3 = (ri->data[i-1][j+2] - ri->data[i-1][j]) >> 1; + int d4 = (ri->data[i+1][j+2] - ri->data[i+1][j]) >> 1; + + double e2 = 1.0 / (1.0 + ABS(dx) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); + + d1 = ri->data[i][j-3] - ri->data[i][j-1]; + d2 = ri->data[i][j-2] - ri->data[i][j]; + d3 = (ri->data[i-1][j-2] - ri->data[i-1][j]) >> 1; + d4 = (ri->data[i+1][j-2] - ri->data[i+1][j]) >> 1; + + double e4 = 1.0 / (1.0 + ABS(dx) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); + + green[i][j] = CLIP((e2 * g2 + e4 * g4) / (e2 + e4)); + } + else if (this->hpmap[i][j]==2) { + int g1 = ri->data[i-1][j] + ((ri->data[i][j] - ri->data[i-2][j]) >> 1); + int g3 = ri->data[i+1][j] + ((ri->data[i][j] - ri->data[i+2][j]) >> 1); + + int dy = ri->data[i+1][j] - ri->data[i-1][j]; + int d1 = ri->data[i-1][j] - ri->data[i-3][j]; + int d2 = ri->data[i][j] - ri->data[i-2][j]; + int d3 = (ri->data[i][j-1] - ri->data[i-2][j-1]) >> 1; + int d4 = (ri->data[i][j+1] - ri->data[i-2][j+1]) >> 1; + + double e1 = 1.0 / (1.0 + ABS(dy) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); + + d1 = ri->data[i+1][j] - ri->data[i+3][j]; + d2 = ri->data[i][j] - ri->data[i+2][j]; + d3 = (ri->data[i][j-1] - ri->data[i+2][j-1]) >> 1; + d4 = (ri->data[i][j+1] - ri->data[i+2][j+1]) >> 1; + + double e3 = 1.0 / (1.0 + ABS(dy) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); + + green[i][j] = CLIP((e1 * g1 + e3 * g3) / (e1 + e3)); + } + else { + int g1 = ri->data[i-1][j] + ((ri->data[i][j] - ri->data[i-2][j]) >> 1); + int g2 = ri->data[i][j+1] + ((ri->data[i][j] - ri->data[i][j+2]) >> 1); + int g3 = ri->data[i+1][j] + ((ri->data[i][j] - ri->data[i+2][j]) >> 1); + int g4 = ri->data[i][j-1] + ((ri->data[i][j] - ri->data[i][j-2]) >> 1); + + int dx = ri->data[i][j+1] - ri->data[i][j-1]; + int dy = ri->data[i+1][j] - ri->data[i-1][j]; + + int d1 = ri->data[i-1][j] - ri->data[i-3][j]; + int d2 = ri->data[i][j] - ri->data[i-2][j]; + int d3 = (ri->data[i][j-1] - ri->data[i-2][j-1]) >> 1; + int d4 = (ri->data[i][j+1] - ri->data[i-2][j+1]) >> 1; + + double e1 = 1.0 / (1.0 + ABS(dy) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); + + d1 = ri->data[i][j+3] - ri->data[i][j+1]; + d2 = ri->data[i][j+2] - ri->data[i][j]; + d3 = (ri->data[i-1][j+2] - ri->data[i-1][j]) >> 1; + d4 = (ri->data[i+1][j+2] - ri->data[i+1][j]) >> 1; + + double e2 = 1.0 / (1.0 + ABS(dx) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); + + d1 = ri->data[i+1][j] - ri->data[i+3][j]; + d2 = ri->data[i][j] - ri->data[i+2][j]; + d3 = (ri->data[i][j-1] - ri->data[i+2][j-1]) >> 1; + d4 = (ri->data[i][j+1] - ri->data[i+2][j+1]) >> 1; + + double e3 = 1.0 / (1.0 + ABS(dy) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); + + d1 = ri->data[i][j-3] - ri->data[i][j-1]; + d2 = ri->data[i][j-2] - ri->data[i][j]; + d3 = (ri->data[i-1][j-2] - ri->data[i-1][j]) >> 1; + d4 = (ri->data[i+1][j-2] - ri->data[i+1][j]) >> 1; + + double e4 = 1.0 / (1.0 + ABS(dx) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); + + green[i][j] = CLIP((e1*g1 + e2*g2 + e3*g3 + e4*g4) / (e1 + e2 + e3 + e4)); + } + } + } + } +} + +void RawImageSource::hphd_demosaic () { + + if (plistener) { + plistener->setProgressStr ("Demosaicing..."); + plistener->setProgress (0.0); + } + + float** hpmap = new float*[H]; + for (int i=0; idualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &RawImageSource::hphd_vertical), hpmap, 0, W/2), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &RawImageSource::hphd_vertical), hpmap, W/2, W), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else + hphd_vertical (hpmap, 0, W); + + if (plistener) + plistener->setProgress (0.33); + + // horizontal + this->hpmap = allocArray(W, H); + for (int i=0; ihpmap[i], 0, W*sizeof(char)); + + if (settings->dualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &RawImageSource::hphd_horizontal), hpmap, 0, H/2), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &RawImageSource::hphd_horizontal), hpmap, H/2, H), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else + hphd_horizontal (hpmap, 0, H); + + freeArray(hpmap, H); + + if (plistener) + plistener->setProgress (0.66); + +// reconstruct G + green = new unsigned short*[H]; + for (int i=0; idualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &RawImageSource::hphd_green), 3, H/2), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &RawImageSource::hphd_green), H/2, H-3), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else + hphd_green (3, H-3); + + if (plistener) + plistener->setProgress (1.0); +} + +void RawImageSource::HLRecovery_Luminance (unsigned short* rin, unsigned short* gin, unsigned short* bin, unsigned short* rout, unsigned short* gout, unsigned short* bout, int width, int maxval) { + + for (int i=0; imaxval || g>maxval || b>maxval) { + int ro = MIN (r, maxval); + int go = MIN (g, maxval); + int bo = MIN (b, maxval); + double L = r + g + b; + double C = 1.732050808 * (r - g); + double H = 2 * b - r - g; + double Co = 1.732050808 * (ro - go); + double Ho = 2 * bo - ro - go; + if (r!=g && g!=b) { + double ratio = sqrt ((Co*Co+Ho*Ho) / (C*C+H*H)); + C *= ratio; + H *= ratio; + } + int rr = L / 3.0 - H / 6.0 + C / 3.464101615; + int gr = L / 3.0 - H / 6.0 - C / 3.464101615; + int br = L / 3.0 + H / 3.0; + rout[i] = CLIP(rr); + gout[i] = CLIP(gr); + bout[i] = CLIP(br); + } + else { + rout[i] = rin[i]; + gout[i] = gin[i]; + bout[i] = bin[i]; + } + } +} + +void RawImageSource::HLRecovery_CIELab (unsigned short* rin, unsigned short* gin, unsigned short* bin, unsigned short* rout, unsigned short* gout, unsigned short* bout, int width, int maxval, double cam[3][3], double icam[3][3]) { + + static bool crTableReady = false; + static double fv[0x10000]; + if (!crTableReady) { + for (int ix=0; ix < 0x10000; ix++) { + double rx = ix / 65535.0; + fv[ix] = rx > 0.008856 ? exp(1.0/3 * log(rx)) : 7.787*rx + 16/116.0; + } + crTableReady = true; + } + + for (int i=0; imaxval || g>maxval || b>maxval) { + int ro = MIN (r, maxval); + int go = MIN (g, maxval); + int bo = MIN (b, maxval); + double yy = cam[0][1]*r + cam[1][1]*g + cam[2][1]*b; + double fy = fv[CLIP((int)yy)]; + // compute LCH decompostion of the clipped pixel (only color information, thus C and H will be used) + double x = cam[0][0]*ro + cam[1][0]*go + cam[2][0]*bo; + double y = cam[0][1]*ro + cam[1][1]*go + cam[2][1]*bo; + double z = cam[0][2]*ro + cam[1][2]*go + cam[2][2]*bo; + x = fv[CLIP((int)x)]; + y = fv[CLIP((int)y)]; + z = fv[CLIP((int)z)]; + // convert back to rgb + double fz = fy - y + z; + double fx = fy + x - y; + double zr = (fz<=0.206893) ? ((116.0*fz-16.0)/903.3) : (fz * fz * fz); + double xr = (fx<=0.206893) ? ((116.0*fx-16.0)/903.3) : (fx * fx * fx); + x = xr*65535.0 - 0.5; + y = yy; + z = zr*65535.0 - 0.5; + int rr = icam[0][0]*x + icam[1][0]*y + icam[2][0]*z; + int gr = icam[0][1]*x + icam[1][1]*y + icam[2][1]*z; + int br = icam[0][2]*x + icam[1][2]*y + icam[2][2]*z; + rout[i] = CLIP(rr); + gout[i] = CLIP(gr); + bout[i] = CLIP(br); + } + else { + rout[i] = rin[i]; + gout[i] = gin[i]; + bout[i] = bin[i]; + } + } +} + +void RawImageSource::hlRecovery (std::string method, unsigned short* red, unsigned short* green, unsigned short* blue, int i, int sx1, int width, int skip) { + + if (method=="Luminance") + HLRecovery_Luminance (red, green, blue, red, green, blue, width, 65535 / ri->defgain); + else if (method=="CIELab blending") + HLRecovery_CIELab (red, green, blue, red, green, blue, width, 65535 / ri->defgain, cam, icam); + else if (method=="Color") + HLRecovery_ColorPropagation (red, green, blue, i, sx1, width, skip); +} + +int RawImageSource::getAEHistogram (unsigned int* histogram, int& histcompr) { + + histcompr = 3; + + memset (histogram, 0, (65536>>histcompr)*sizeof(int)); + + for (int i=border; iheight-border; i++) { + int start, end; + if (fuji) { + int fw = ri->fuji_width; + start = ABS(fw-i) + border; + end = MIN( ri->height+ ri->width-fw-i, fw+i) - border; + } + else { + start = border; + end = ri->width-border; + } + if (ri->filters) + for (int j=start; jdata[i][j]>>histcompr]+=2; + else + histogram[ri->data[i][j]>>histcompr]+=4; + else + for (int j=start; j<3*end; j++) { + histogram[ri->data[i][j+0]>>histcompr]++; + histogram[ri->data[i][j+1]>>histcompr]++; + histogram[ri->data[i][j+2]>>histcompr]++; + } + } + return 1; +} + +ColorTemp RawImageSource::getAutoWB () { + + double avg_r = 0; + double avg_g = 0; + double avg_b = 0; + int rn = 0, gn = 0, bn = 0; + + if (fuji) { + for (int i=32; iheight-32; i++) { + int fw = ri->fuji_width; + int start = ABS(fw-i) + 32; + int end = MIN(ri->height+ri->width-fw-i, fw+i) - 32; + for (int j=start; jfilters) { + double d = CLIP(ri->defgain*ri->data[i][3*j]); + if (d>64000) + continue; + avg_r += d*d*d*d*d*d; rn++; + d = CLIP(ri->defgain*ri->data[i][3*j+1]); + if (d>64000) + continue; + avg_g += d*d*d*d*d*d; gn++; + d = CLIP(ri->defgain*ri->data[i][3*j+2]); + if (d>64000) + continue; + avg_b += d*d*d*d*d*d; bn++; + } + else { + double d = CLIP(ri->defgain*ri->data[i][j]); + if (d>64000) + continue; + double dp = d*d*d*d*d*d; + if (ISRED(ri,i,j)) { + avg_r += dp; + rn++; + } + else if (ISGREEN(ri,i,j)) { + avg_g += dp; + gn++; + } + else if (ISBLUE(ri,i,j)) { + avg_b += dp; + bn++; + } + } + } + } + } + else { + for (int i=32; iheight-32; i++) + for (int j=32; jwidth-32; j++) { + if (!ri->filters) { + double d = CLIP(ri->defgain*ri->data[i][3*j]); + if (d>64000) + continue; + avg_r += d*d*d*d*d*d; rn++; + d = CLIP(ri->defgain*ri->data[i][3*j+1]); + if (d>64000) + continue; + avg_g += d*d*d*d*d*d; gn++; + d = CLIP(ri->defgain*ri->data[i][3*j+2]); + if (d>64000) + continue; + avg_b += d*d*d*d*d*d; bn++; + } + else { + double d = CLIP(ri->defgain*ri->data[i][j]); + if (d>64000) + continue; + double dp = d*d*d*d*d*d; + if (ISRED(ri,i,j)) { + avg_r += dp; + rn++; + } + else if (ISGREEN(ri,i,j)) { + avg_g += dp; + gn++; + } + else if (ISBLUE(ri,i,j)) { + avg_b += dp; + bn++; + } + } + } + } + + printf ("AVG: %g %g %g\n", avg_r/rn, avg_g/gn, avg_b/bn); + +// double img_r, img_g, img_b; +// wb.getMultipliers (img_r, img_g, img_b); + +// return ColorTemp (pow(avg_r/rn, 1.0/6.0)*img_r, pow(avg_g/gn, 1.0/6.0)*img_g, pow(avg_b/bn, 1.0/6.0)*img_b); + + double reds = pow (avg_r/rn, 1.0/6.0) * ri->camwb_red; + double greens = pow (avg_g/gn, 1.0/6.0) * ri->camwb_green; + double blues = pow (avg_b/bn, 1.0/6.0) * ri->camwb_blue; + + double rm = coeff[0][0]*reds + coeff[0][1]*greens + coeff[0][2]*blues; + double gm = coeff[1][0]*reds + coeff[1][1]*greens + coeff[1][2]*blues; + double bm = coeff[2][0]*reds + coeff[2][1]*greens + coeff[2][2]*blues; + + return ColorTemp (rm, gm, bm); +} + +void RawImageSource::transformPosition (int x, int y, int tran, int& ttx, int& tty) { + + tran = defTransform (tran); + + x += border; + y += border; + + if (d1x) { + if ((tran & TR_ROT) == TR_R90 || (tran & TR_ROT) == TR_R270) + x /= 2; + else + y /= 2; + } + + int w = W, h = H; + if (fuji) { + w = ri->fuji_width * 2 + 1; + h = (H - ri->fuji_width)*2 + 1; + } + int sw = w, sh = h; + if ((tran & TR_ROT) == TR_R90 || (tran & TR_ROT) == TR_R270) { + sw = h; + sh = w; + } + + int ppx = x, ppy = y; + if (tran & TR_HFLIP) + ppx = sw - 1 - x ; + if (tran & TR_VFLIP) + ppy = sh - 1 - y; + + int tx = ppx; + int ty = ppy; + + if ((tran & TR_ROT) == TR_R180) { + tx = w - 1 - ppx; + ty = h - 1 - ppy; + } + else if ((tran & TR_ROT) == TR_R90) { + tx = ppy; + ty = h - 1 - ppx; + } + else if ((tran & TR_ROT) == TR_R270) { + tx = w - 1 - ppy; + ty = ppx; + } + + if (fuji) { + ttx = (tx+ty) / 2; + tty = (ty-tx) / 2 + ri->fuji_width; + } + else { + ttx = tx; + tty = ty; + } +} + +ColorTemp RawImageSource::getSpotWB (std::vector red, std::vector green, std::vector& blue, int tran) { + + int x; int y; + int d[9][2] = {0,0, -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1}; + double reds = 0, greens = 0, blues = 0; + int rn = 0, gn = 0, bn = 0; + + if (!ri->filters) { + for (int i=0; i=0 && y>=0 && xdata[y][3*x]; + rn++; + } + transformPosition (green[i].x, green[i].y, tran, x, y); + if (x>=0 && y>=0 && xdata[y][3*x+1]; + gn++; + } + transformPosition (blue[i].x, blue[i].y, tran, x, y); + if (x>=0 && y>=0 && xdata[y][3*x+2]; + bn++; + } + } + } + else { + for (int i=0; i=0 && yv>=0 && xvdata[yv][xv]; + rn++; + break; + } + } + transformPosition (green[i].x, green[i].y, tran, x, y); + for (int k=0; k<9; k++) { + int xv = x + d[k][0]; + int yv = y + d[k][1]; + if (ISGREEN(ri,yv,xv) && xv>=0 && yv>=0 && xvdata[yv][xv]; + gn++; + break; + } + } + transformPosition (blue[i].x, blue[i].y, tran, x, y); + for (int k=0; k<9; k++) { + int xv = x + d[k][0]; + int yv = y + d[k][1]; + if (ISBLUE(ri,yv,xv) && xv>=0 && yv>=0 && xvdata[yv][xv]; + bn++; + break; + } + } + } + } + + reds = reds/rn * ri->camwb_red; + greens = greens/gn * ri->camwb_green; + blues = blues/bn * ri->camwb_blue; + + double rm = coeff[0][0]*reds + coeff[0][1]*greens + coeff[0][2]*blues; + double gm = coeff[1][0]*reds + coeff[1][1]*greens + coeff[1][2]*blues; + double bm = coeff[2][0]*reds + coeff[2][1]*greens + coeff[2][2]*blues; + + return ColorTemp (rm, gm, bm); +} + +#define FORCC for (c=0; c < colors; c++) +#define fc(row,col) \ + (ri->prefilters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) +typedef unsigned short ushort; +void RawImageSource::vng4_demosaic () { + + static const signed char *cp, terms[] = { + -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01, + -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01, + -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03, + -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06, + -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04, + -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01, + -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40, + -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11, + -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11, + -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22, + -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44, + -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10, + -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04, + +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40, + +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20, + +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08, + +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20, + +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44, + +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60, + +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80, + +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40, + +1,+0,+2,+1,0,0x10 + }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 }; + + if (plistener) { + plistener->setProgressStr ("Demosaicing..."); + plistener->setProgress (0.0); + } + + ushort (*brow[5])[4], *pix; + int prow=7, pcol=1, *ip, *code[16][16], gval[8], gmin, gmax, sum[4]; + int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag; + int g, diff, thold, num, c, width=W, height=H, colors=4; + ushort (*image)[4]; + int lcode[16][16][32], shift, i, j; + + image = (ushort (*)[4]) calloc (H*W, sizeof *image); + for (int ii=0; iidata[ii][jj]; + +// first linear interpolation + for (row=0; row < 16; row++) + for (col=0; col < 16; col++) { + ip = lcode[row][col]; + memset (sum, 0, sizeof sum); + for (y=-1; y <= 1; y++) + for (x=-1; x <= 1; x++) { + shift = (y==0) + (x==0); + if (shift == 2) continue; + color = fc(row+y,col+x); + *ip++ = (width*y + x)*4 + color; + *ip++ = shift; + *ip++ = color; + sum[color] += 1 << shift; + } + FORCC + if (c != fc(row,col)) { + *ip++ = c; + *ip++ = 256 / sum[c]; + } + } + + for (row=1; row < height-1; row++) + for (col=1; col < width-1; col++) { + pix = image[row*width+col]; + ip = lcode[row & 15][col & 15]; + memset (sum, 0, sizeof sum); + for (i=8; i--; ip+=3) + sum[ip[2]] += pix[ip[0]] << ip[1]; + for (i=colors; --i; ip+=2) + pix[ip[0]] = sum[ip[0]] * ip[1] >> 8; + } + +// lin_interpolate(); + + + ip = (int *) calloc ((prow+1)*(pcol+1), 1280); + for (row=0; row <= prow; row++) /* Precalculate for VNG */ + for (col=0; col <= pcol; col++) { + code[row][col] = ip; + for (cp=terms, t=0; t < 64; t++) { + y1 = *cp++; x1 = *cp++; + y2 = *cp++; x2 = *cp++; + weight = *cp++; + grads = *cp++; + color = fc(row+y1,col+x1); + if (fc(row+y2,col+x2) != color) continue; + diag = (fc(row,col+1) == color && fc(row+1,col) == color) ? 2:1; + if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue; + *ip++ = (y1*width + x1)*4 + color; + *ip++ = (y2*width + x2)*4 + color; + *ip++ = weight; + for (g=0; g < 8; g++) + if (grads & 1< gval[g]) gmin = gval[g]; + if (gmax < gval[g]) gmax = gval[g]; + } + if (gmax == 0) { + memcpy (brow[2][col], pix, sizeof *image); + continue; + } + thold = gmin + (gmax >> 1); + memset (sum, 0, sizeof sum); + for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */ + if (gval[g] <= thold) { + FORCC + if (c == color && ip[1]) + sum[c] += (pix[c] + pix[ip[1]]) >> 1; + else + sum[c] += pix[ip[0] + c]; + num++; + } + } + FORCC { /* Save to buffer */ + t = pix[color]; + if (c != color) + t += (sum[c] - sum[color]) / num; + brow[2][col][c] = CLIP(t); + } + } + if (row > 3) /* Write buffer to image */ + memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image); + for (g=0; g < 4; g++) + brow[(g-1) & 3] = brow[g]; + if (!(row%20) && plistener) + plistener->setProgress ((double)row / (H-2)); + } + memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image); + memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image); + free (brow[4]); + free (code[0][0]); + + green = new unsigned short*[H]; + for (int i=0; i> 1; + } + free (image); +} + +//#define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31)) +//#define MIN(a,b) ((a) < (b) ? (a) : (b)) +//#define MAX(a,b) ((a) > (b) ? (a) : (b)) +//#define LIM(x,min,max) MAX(min,MIN(x,max)) +//#define CLIP(x) LIM(x,0,65535) +#undef fc +#define fc(row,col) \ + (ri->filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) +#define FC(x,y) fc(x,y) +#define LIM(x,min,max) MAX(min,MIN(x,max)) +#define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y)) + +/* + Patterned Pixel Grouping Interpolation by Alain Desbiolles +*/ +void RawImageSource::ppg_demosaic() +{ + int width=W, height=H; + int dir[5] = { 1, width, -1, -width, 1 }; + int row, col, diff[2], guess[2], c, d, i; + ushort (*pix)[4]; + + ushort (*image)[4]; + int colors = 3; + + if (plistener) { + plistener->setProgressStr ("Demosaicing..."); + plistener->setProgress (0.0); + } + + image = (ushort (*)[4]) calloc (H*W, sizeof *image); + for (int ii=0; iidata[ii][jj]; + + border_interpolate(3, image); + +/* Fill in the green layer with gradients and pattern recognition: */ + for (row=3; row < height-3; row++) { + for (col=3+(FC(row,3) & 1), c=FC(row,col); col < width-3; col+=2) { + pix = image + row*width+col; + for (i=0; (d=dir[i]) > 0; i++) { + guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2 + - pix[-2*d][c] - pix[2*d][c]; + diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) + + ABS(pix[ 2*d][c] - pix[ 0][c]) + + ABS(pix[ -d][1] - pix[ d][1]) ) * 3 + + ( ABS(pix[ 3*d][1] - pix[ d][1]) + + ABS(pix[-3*d][1] - pix[-d][1]) ) * 2; + } + d = dir[i = diff[0] > diff[1]]; + pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]); + } + if(plistener) plistener->setProgress(0.33*row/(height-3)); + } +/* Calculate red and blue for each green pixel: */ + for (row=1; row < height-1; row++) { + for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < width-1; col+=2) { + pix = image + row*width+col; + for (i=0; (d=dir[i]) > 0; c=2-c, i++) + pix[0][c] = CLIP((pix[-d][c] + pix[d][c] + 2*pix[0][1] + - pix[-d][1] - pix[d][1]) >> 1); + } + if(plistener) plistener->setProgress(0.33 + 0.33*row/(height-1)); + } +/* Calculate blue for red pixels and vice versa: */ + for (row=1; row < height-1; row++) { + for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < width-1; col+=2) { + pix = image + row*width+col; + for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) { + diff[i] = ABS(pix[-d][c] - pix[d][c]) + + ABS(pix[-d][1] - pix[0][1]) + + ABS(pix[ d][1] - pix[0][1]); + guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1] + - pix[-d][1] - pix[d][1]; + } + if (diff[0] != diff[1]) + pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1); + else + pix[0][c] = CLIP((guess[0]+guess[1]) >> 2); + } + if(plistener) plistener->setProgress(0.67 + 0.33*row/(height-1)); + } + + red = new unsigned short*[H]; + for (int i=0; i= border && row < height-border) + col = width-border; + memset (sum, 0, sizeof sum); + for (y=row-1; y != row+2; y++) + for (x=col-1; x != col+2; x++) + if (y < height && x < width) { + f = fc(y,x); + sum[f] += image[y*width+x][f]; + sum[f+4]++; + } + f = fc(row,col); + FORCC if (c != f && sum[c+4]) + image[row*width+col][c] = sum[c] / sum[c+4]; + } +} + +/* + Adaptive Homogeneity-Directed interpolation is based on + the work of Keigo Hirakawa, Thomas Parks, and Paul Lee. + */ +#define TS 256 /* Tile Size */ +#define FORC(cnt) for (c=0; c < cnt; c++) +#define FORC3 FORC(3) +#define SQR(x) ((x)*(x)) + +void RawImageSource::ahd_demosaic() +{ + int i, j, k, top, left, row, col, tr, tc, c, d, val, hm[2]; + ushort (*pix)[4], (*rix)[3]; + static const int dir[4] = { -1, 1, -TS, TS }; + unsigned ldiff[2][4], abdiff[2][4], leps, abeps; + float r, cbrt[0x10000], xyz[3], xyz_cam[3][4]; + ushort (*rgb)[TS][TS][3]; + short (*lab)[TS][TS][3], (*lix)[3]; + char (*homo)[TS][TS], *buffer; + + int width=W, height=H; + ushort (*image)[4]; + int colors = 3; + + const double xyz_rgb[3][3] = { /* XYZ from RGB */ + { 0.412453, 0.357580, 0.180423 }, + { 0.212671, 0.715160, 0.072169 }, + { 0.019334, 0.119193, 0.950227 } }; + const float d65_white[3] = { 0.950456, 1, 1.088754 }; + + if (plistener) { + plistener->setProgressStr ("Demosaicing..."); + plistener->setProgress (0.0); + } + + image = (ushort (*)[4]) calloc (H*W, sizeof *image); + for (int ii=0; iidata[ii][jj]; + + for (i=0; i < 0x10000; i++) { + r = i / 65535.0; + cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0; + } + for (i=0; i < 3; i++) + for (j=0; j < colors; j++) + for (xyz_cam[i][j] = k=0; k < 3; k++) + xyz_cam[i][j] += xyz_rgb[i][k] * coeff[k][j] / d65_white[i]; + + border_interpolate(5, image); + buffer = (char *) malloc (26*TS*TS); /* 1664 kB */ + //merror (buffer, "ahd_interpolate()"); + rgb = (ushort(*)[TS][TS][3]) buffer; + lab = (short (*)[TS][TS][3])(buffer + 12*TS*TS); + homo = (char (*)[TS][TS]) (buffer + 24*TS*TS); + + for (top=2; top < height-5; top += TS-6) + for (left=2; left < width-5; left += TS-6) { + +/* Interpolate green horizontally and vertically: */ + for (row = top; row < top+TS && row < height-2; row++) { + col = left + (FC(row,left) & 1); + for (c = FC(row,col); col < left+TS && col < width-2; col+=2) { + pix = image + row*width+col; + val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2 + - pix[-2][c] - pix[2][c]) >> 2; + rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]); + val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2 + - pix[-2*width][c] - pix[2*width][c]) >> 2; + rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]); + } + } + + if(plistener) plistener->setProgress (0.33); +/* Interpolate red and blue, and convert to CIELab: */ + for (d=0; d < 2; d++) + for (row=top+1; row < top+TS-1 && row < height-3; row++) + for (col=left+1; col < left+TS-1 && col < width-3; col++) { + pix = image + row*width+col; + rix = &rgb[d][row-top][col-left]; + lix = &lab[d][row-top][col-left]; + if ((c = 2 - FC(row,col)) == 1) { + c = FC(row+1,col); + val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c] + - rix[-1][1] - rix[1][1] ) >> 1); + rix[0][2-c] = CLIP(val); + val = pix[0][1] + (( pix[-width][c] + pix[width][c] + - rix[-TS][1] - rix[TS][1] ) >> 1); + } else + val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c] + + pix[+width-1][c] + pix[+width+1][c] + - rix[-TS-1][1] - rix[-TS+1][1] + - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2); + rix[0][c] = CLIP(val); + c = FC(row,col); + rix[0][c] = pix[0][c]; + xyz[0] = xyz[1] = xyz[2] = 0.5; + FORCC { + xyz[0] += xyz_cam[0][c] * rix[0][c]; + xyz[1] += xyz_cam[1][c] * rix[0][c]; + xyz[2] += xyz_cam[2][c] * rix[0][c]; + } + xyz[0] = cbrt[CLIP((int) xyz[0])]; + xyz[1] = cbrt[CLIP((int) xyz[1])]; + xyz[2] = cbrt[CLIP((int) xyz[2])]; + lix[0][0] = 64 * (116 * xyz[1] - 16); + lix[0][1] = 64 * 500 * (xyz[0] - xyz[1]); + lix[0][2] = 64 * 200 * (xyz[1] - xyz[2]); + } + + if(plistener) plistener->setProgress (0.5); +/* Build homogeneity maps from the CIELab images: */ + memset (homo, 0, 2*TS*TS); + for (row=top+2; row < top+TS-2 && row < height-4; row++) { + tr = row-top; + for (col=left+2; col < left+TS-2 && col < width-4; col++) { + tc = col-left; + for (d=0; d < 2; d++) { + lix = &lab[d][tr][tc]; + for (i=0; i < 4; i++) { + ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]); + abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1]) + + SQR(lix[0][2]-lix[dir[i]][2]); + } + } + leps = MIN(MAX(ldiff[0][0],ldiff[0][1]), + MAX(ldiff[1][2],ldiff[1][3])); + abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]), + MAX(abdiff[1][2],abdiff[1][3])); + for (d=0; d < 2; d++) + for (i=0; i < 4; i++) + if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps) + homo[d][tr][tc]++; + } + } + if(plistener) plistener->setProgress (0.8); +/* Combine the most homogenous pixels for the final result: */ + for (row=top+3; row < top+TS-3 && row < height-5; row++) { + tr = row-top; + for (col=left+3; col < left+TS-3 && col < width-5; col++) { + tc = col-left; + for (d=0; d < 2; d++) + for (hm[d]=0, i=tr-1; i <= tr+1; i++) + for (j=tc-1; j <= tc+1; j++) + hm[d] += homo[d][i][j]; + if (hm[0] != hm[1]) + FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c]; + else + FORC3 image[row*width+col][c] = + (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1; + } + } + } + if(plistener) plistener->setProgress (1.0); + free (buffer); + red = new unsigned short*[H]; + for (int i=0; i ( image[indx-1][1] + image[indx+1][1] + image[indx-u][1] + image[indx+u][1])/4.0) + image[indx][3] = ((MIN( image[indx-1][1], image[indx+1][1]) + image[indx-1][1] + image[indx+1][1] ) < (MIN( image[indx-u][1], image[indx+u][1]) + image[indx-u][1] + image[indx+u][1])); + else + image[indx][3] = ((MAX( image[indx-1][1], image[indx+1][1]) + image[indx-1][1] + image[indx+1][1] ) > (MAX( image[indx-u][1], image[indx+u][1]) + image[indx-u][1] + image[indx+u][1])) ; + } + } +} + + + + + +// interpolated green pixels are corrected using the map +void RawImageSource::dcb_correction(ushort (*image)[4]) +{ + int width=W, height=H; + int current, row, col, c, u=width, v=2*u, indx; + + for (row=4; row < height-4; row++) { + for (col=4, indx=row*width+col; col < width-4; col++, indx++) { + + c = FC(row,col); + + if (c != 1) + { + current = 4*image[indx][3] + + 2*(image[indx+u][3] + image[indx-u][3] + image[indx+1][3] + image[indx-1][3]) + + image[indx+v][3] + image[indx-v][3] + image[indx+2][3] + image[indx-2][3]; + + image[indx][1] = ((16-current)*(image[indx-1][1] + image[indx+1][1])/2.0 + current*(image[indx-u][1] + image[indx+u][1])/2.0)/16.0; + } + + } + } + +} + +// R and B smoothing using green contrast, all pixels except 2 pixel wide border +void RawImageSource::dcb_pp(ushort (*image)[4]) +{ + int width=W, height=H; + int g1, r1, b1, u=width, indx, row, col; + + + for (row=2; row < height-2; row++) + for (col=2, indx=row*u+col; col < width-2; col++, indx++) { + + r1 = ( image[indx-1][0] + image[indx+1][0] + image[indx-u][0] + image[indx+u][0] + image[indx-u-1][0] + image[indx+u+1][0] + image[indx-u+1][0] + image[indx+u-1][0])/8.0; + g1 = ( image[indx-1][1] + image[indx+1][1] + image[indx-u][1] + image[indx+u][1] + image[indx-u-1][1] + image[indx+u+1][1] + image[indx-u+1][1] + image[indx+u-1][1])/8.0; + b1 = ( image[indx-1][2] + image[indx+1][2] + image[indx-u][2] + image[indx+u][2] + image[indx-u-1][2] + image[indx+u+1][2] + image[indx-u+1][2] + image[indx+u-1][2])/8.0; + + image[indx][0] = CLIP(r1 + ( image[indx][1] - g1 )); + image[indx][2] = CLIP(b1 + ( image[indx][1] - g1 )); + + } +} + +// interpolated green pixels are corrected using the map +// with correction +void RawImageSource::dcb_correction2(ushort (*image)[4]) +{ + int width=W, height=H; + int current, row, col, c, u=width, v=2*u, indx; + ushort (*pix)[4]; + + for (row=4; row < height-4; row++) { + for (col=4, indx=row*width+col; col < width-4; col++, indx++) { + + c = FC(row,col); + + if (c != 1) + { + current = 4*image[indx][3] + + 2*(image[indx+u][3] + image[indx-u][3] + image[indx+1][3] + image[indx-1][3]) + + image[indx+v][3] + image[indx-v][3] + image[indx+2][3] + image[indx-2][3]; + + image[indx][1] = CLIP(((16-current)*((image[indx-1][1] + image[indx+1][1])/2.0 + image[indx][c] - (image[indx+2][c] + image[indx-2][c])/2.0) + current*((image[indx-u][1] + image[indx+u][1])/2.0 + image[indx][c] - (image[indx+v][c] + image[indx-v][c])/2.0))/16.0); + } + + } + } + +} + +// restores red and blue +void RawImageSource::restore_from_buffer(ushort (*image)[4], float (*image2)[3]) +{ + int width=W, height=H; + int indx; + + for (indx=0; indx < height*width; indx++) { + image[indx][0]=image2[indx][0]; //R + image[indx][2]=image2[indx][2]; //B + } +} + +// image refinement +void RawImageSource::dcb_refinement(ushort (*image)[4]) +{ + int width=W, height=H; + int row, col, c, u=width, v=2*u, w=3*u, x=4*u, y=5*u, indx, max, min; + float f[4], g[4]; + + for (row=5; row < height-5; row++) + for (col=5+(FC(row,1)&1),indx=row*width+col,c=FC(row,col); col < u-5; col+=2,indx+=2) { + +// Cubic Spline Interpolation by Li and Randhawa, modified by Jacek Gozdz and Luis Sanz Rodríguez + f[0]=1.0/(1.0+abs(image[indx-u][c]-image[indx][c])+abs(image[indx-u][1]-image[indx][1])); + f[1]=1.0/(1.0+abs(image[indx+1][c]-image[indx][c])+abs(image[indx+1][1]-image[indx][1])); + f[2]=1.0/(1.0+abs(image[indx-1][c]-image[indx][c])+abs(image[indx-1][1]-image[indx][1])); + f[3]=1.0/(1.0+abs(image[indx+u][c]-image[indx][c])+abs(image[indx+u][1]-image[indx][1])); + +g[0]=CLIP(image[indx-u][1]+0.5*(image[indx][c]-image[indx-u][c]) + 0.25*(image[indx][c]-image[indx-v][c])); +g[1]=CLIP(image[indx+1][1]+0.5*(image[indx][c]-image[indx+1][c]) + 0.25*(image[indx][c]-image[indx+2][c])); +g[2]=CLIP(image[indx-1][1]+0.5*(image[indx][c]-image[indx-1][c]) + 0.25*(image[indx][c]-image[indx-2][c])); +g[3]=CLIP(image[indx+u][1]+0.5*(image[indx][c]-image[indx+u][c]) + 0.25*(image[indx][c]-image[indx+v][c])); + + + + image[indx][1]=CLIP(((f[0]*g[0]+f[1]*g[1]+f[2]*g[2]+f[3]*g[3])/(f[0]+f[1]+f[2]+f[3]) )); + +// get rid of the overshooted pixels + min = MIN(image[indx+1+u][1], MIN(image[indx+1-u][1], MIN(image[indx-1+u][1], MIN(image[indx-1-u][1], MIN(image[indx-1][1], MIN(image[indx+1][1], MIN(image[indx-u][1], image[indx+u][1]))))))); + + max = MAX(image[indx+1+u][1], MAX(image[indx+1-u][1], MAX(image[indx-1+u][1], MAX(image[indx-1-u][1], MAX(image[indx-1][1], MAX(image[indx+1][1], MAX(image[indx-u][1], image[indx+u][1]))))))); + + image[indx][1] = ULIM(image[indx][1], max, min); + + + } +} + +// missing colors are interpolated using high quality algorithm by Luis Sanz Rodríguez +void RawImageSource::dcb_color_full(ushort (*image)[4]) +{ + int width=W, height=H; + int row,col,c,d,i,j,u=width,v=2*u,w=3*u,indx; + float f[4],g[4],(*chroma)[2]; + + chroma = (float (*)[2]) calloc(width*height,sizeof *chroma); + //merror (chroma, "dcb_color_full()"); + + for (row=1; row < height-1; row++) + for (col=1+(FC(row,1)&1),indx=row*width+col,c=FC(row,col),d=c/2; col < u-1; col+=2,indx+=2) + chroma[indx][d]=image[indx][c]-image[indx][1]; + + for (row=3; rowsetProgressStr ("Demosaicing..."); + plistener->setProgress (0.0); + } + + image = (ushort (*)[4]) calloc (H*W, sizeof *image); + for (int ii=0; iidata[ii][jj]; + + border_interpolate(2, image); + copy_to_buffer(image2, image); + + hid(image); + dcb_color(image); + + while (i<=iterations) { + //if (verbose) fprintf (stderr,_("DCB correction pass %d...\n"), i); + hid2(image); + hid2(image); + hid2(image); + dcb_map(image); + dcb_correction(image); + if(plistener) plistener->setProgress (0.33*i/iterations); + i++; + } + if(plistener) plistener->setProgress (0.33); + + dcb_color(image); + dcb_pp(image); + hid2(image); + hid2(image); + hid2(image); + + //if (verbose) fprintf (stderr,_("finishing DCB...\n")); + if(plistener) plistener->setProgress (0.5); + + dcb_map(image); + dcb_correction2(image); + + restore_from_buffer(image, image2); + + dcb_map(image); + dcb_correction(image); + + dcb_color(image); + dcb_pp(image); + dcb_map(image); + dcb_correction(image); + + dcb_map(image); + dcb_correction(image); + + restore_from_buffer(image, image2); + dcb_color(image); + + if(plistener) plistener->setProgress (0.7); + if (dcb_enhance) { + //if (verbose) fprintf (stderr,_("optional DCB refinement...\n")); + dcb_refinement(image); + dcb_color_full(image); + } + + if(plistener) plistener->setProgress (1.0); + + free(image2); + + red = new unsigned short*[H]; + for (int i=0; i + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _RAWIMAGESOURCE_ +#define _RAWIMAGESOURCE_ + +#include +#include +#define HR_SCALE 2 + +namespace rtengine { + +template void freeArray (T** a, int H) { + for (int i=0; i T** allocArray (int W, int H) { + + T** t = new T*[H]; + for (int i=0; i void freeArray2 (T** a, int H) { + for (int i=0; i red, std::vector green, std::vector& blue, int tran); + + double getDefGain () { return defGain; } + double getGamma () { return 2.2; } + + void getFullSize (int& w, int& h, int tr = TR_NONE); + void getSize (int tran, PreviewProps pp, int& w, int& h); + + ImageData* getImageData () { return idata; } + void setProgressListener (ProgressListener* pl) { plistener = pl; } + int getAEHistogram (unsigned int* histogram, int& histcompr); + + static void colorSpaceConversion (Image16* im, ColorManagementParams cmp, cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], double& defgain); + static void inverse33 (double (*coeff)[3], double (*icoeff)[3]); + + static void HLRecovery_Luminance (unsigned short* rin, unsigned short* gin, unsigned short* bin, unsigned short* rout, unsigned short* gout, unsigned short* bout, int width, int maxval); + static void HLRecovery_CIELab (unsigned short* rin, unsigned short* gin, unsigned short* bin, unsigned short* rout, unsigned short* gout, unsigned short* bout, int width, int maxval, double cam[3][3], double icam[3][3]); + + protected: + typedef unsigned short ushort; + void correction_YIQ_LQ (Image16* i, int times); + inline void convert_row_to_YIQ (unsigned short* r, unsigned short* g, unsigned short* b, int* Y, int* I, int* Q, int W); + inline void convert_row_to_RGB (unsigned short* r, unsigned short* g, unsigned short* b, int* Y, int* I, int* Q, int W); + + inline void convert_to_cielab_row (unsigned short* ar, unsigned short* ag, unsigned short* ab, short* oL, short* oa, short* ob); + inline void interpolate_row_g (unsigned short* agh, unsigned short* agv, int i); + inline void interpolate_row_rb (unsigned short* ar, unsigned short* ab, unsigned short* pg, unsigned short* cg, unsigned short* ng, int i); + inline void interpolate_row_rb_mul_pp (unsigned short* ar, unsigned short* ab, unsigned short* pg, unsigned short* cg, unsigned short* ng, int i, double r_mul, double g_mul, double b_mul, int x1, int width, int skip); + + void eahd_demosaic (); + void hphd_demosaic (); + void vng4_demosaic (); + void ppg_demosaic(); + void dcb_demosaic(int iterations, int dcb_enhance); + void ahd_demosaic(); + void border_interpolate(int border, ushort (*image)[4]); + void copy_to_buffer(float (*image2)[3], ushort (*image)[4]); + void hid(ushort (*image)[4]); + void dcb_color(ushort (*image)[4]); + void hid2(ushort (*image)[4]); + void dcb_map(ushort (*image)[4]); + void dcb_correction(ushort (*image)[4]); + void dcb_pp(ushort (*image)[4]); + void dcb_correction2(ushort (*image)[4]); + void restore_from_buffer(ushort (*image)[4], float (*image2)[3]); + void dcb_refinement(ushort (*image)[4]); + void dcb_color_full(ushort (*image)[4]); + + void transLine (unsigned short* red, unsigned short* green, unsigned short* blue, int i, Image16* image, int tran, int imw, int imh, int fw); + void hflip (Image16* im); + void vflip (Image16* im); + +}; +}; +#endif diff --git a/rtengine/rawmetadatalocation.h b/rtengine/rawmetadatalocation.h new file mode 100644 index 000000000..0e74b9446 --- /dev/null +++ b/rtengine/rawmetadatalocation.h @@ -0,0 +1,32 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _RAWMETADATALOCATION_ +#define _RAWMETADATALOCATION_ + +namespace rtengine { + + struct RawMetaDataLocation { + int exifBase; + int ciffBase; + int ciffLength; + }; +} + +#endif + diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc new file mode 100644 index 000000000..2e561aa7f --- /dev/null +++ b/rtengine/refreshmap.cc @@ -0,0 +1,106 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include + +int refreshmap[] = { +ALL, // EvPhotoLoaded, +ALL, // EvProfileLoaded, +ALL, // EvProfileChanged, +ALL, // EvHistoryBrowsed, +RGBCURVE, // EvBrightness, +RGBCURVE, // EvContrast, +RGBCURVE, // EvBlack, +RGBCURVE, // EvExpComp, +RGBCURVE, // EvHLCompr, +RGBCURVE, // EvSHCompr, +RGBCURVE, // EvToneCurve, +AUTOEXP, // EvAutoExp, +AUTOEXP, // EvClip, +LUMINANCECURVE, // EvLBrightness, +LUMINANCECURVE, // EvLContrast, +LUMINANCECURVE, // EvLBlack, +LUMINANCECURVE, // EvLHLCompr, +LUMINANCECURVE, // EvLSHCompr, +LUMINANCECURVE, // EvLCurve, +SHARPENING, // EvShrEnabled, +SHARPENING, // EvShrRadius, +SHARPENING, // EvShrAmount, +SHARPENING, // EvShrThresh, +SHARPENING, // EvShrEdgeOnly, +SHARPENING, // EvShrEdgeRadius, +SHARPENING, // EvShrEdgeTolerance, +SHARPENING, // EvShrHaloControl, +SHARPENING, // EvShrHaloAmount, +SHARPENING, // EvShrMethod, +SHARPENING, // EvShrDRadius, +SHARPENING, // EvShrDAmount, +SHARPENING, // EvShrDDamping, +SHARPENING, // EvShrDIterations, +COLORBOOST, // EvCBAvoidClip, +COLORBOOST, // EvCBSatLimiter, +COLORBOOST, // EvCBSatLimit, +COLORBOOST, // EvCBBoost, +WHITEBALANCE, // EvWBMethod, +WHITEBALANCE, // EvWBTemp, +WHITEBALANCE, // EvWBGreen, +COLORBOOST, // EvCShiftA, +COLORBOOST, // EvCShiftB, +LUMADENOISE, // EvLDNEnabled, +LUMADENOISE, // EvLDNRadius, +LUMADENOISE, // EvLDNEdgeTolerance, +COLORDENOISE, // EvCDNEnabled, +COLORDENOISE, // EvCDNRadius, +COLORDENOISE, // EvCDNEdgeTolerance, +COLORDENOISE, // EvCDNEdgeSensitive, +RETINEX, // EvSHEnabled, +RGBCURVE, // EvSHHighlights, +RGBCURVE, // EvSHShadows, +RGBCURVE, // EvSHHLTonalW, +RGBCURVE, // EvSHSHTonalW, +RGBCURVE, // EvSHLContrast, +RETINEX, // EvSHRadius, +ALL, // EvCTRotate, +ALL, // EvCTHFlip, +ALL, // EvCTVFlip, +TRANSFORM, // EvROTDegree, +TRANSFORM, // EvROTFill, +TRANSFORM, // EvDISTAmount, +ALL, // EvBookmarkSelected, +CROP, // EvCrop, +TRANSFORM, // EvCACorr, +ALL, // EvHREnabled, +ALL, // EvHRAmount, +ALL, // EvHRMethod, +ALL, // EvWProfile, +ALL, // EvOProfile, +ALL, // EvIProfile, +TRANSFORM, // EvVignetting, +RGBCURVE, // EvChMixer, +ALL, // EvResizeScale, +ALL, // EvResizeMethod, +EXIF, // EvExif, +IPTC, // EvIPTC +ALL, // EvResizeSpec, +ALL, // EvResizeWidth +ALL, // EvResizeHeight +ALL, // EvResizeEnabled +ALL, // EvProfileChangeNotification +RETINEX // EvShrHighQuality + }; + diff --git a/rtengine/refreshmap.h b/rtengine/refreshmap.h new file mode 100644 index 000000000..b7daf7be0 --- /dev/null +++ b/rtengine/refreshmap.h @@ -0,0 +1,53 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef __REFRESHMAP__ +#define __REFRESHMAP__ + +#include + +#define NUMOFEVENTS 83 + +#define FIRST 65535 +#define ALL 65535 +#define TRANSFORM 127 +#define RETINEX 63 +#define AUTOEXP 31 +#define RGBCURVE 15 +#define LUMINANCECURVE 6 +#define SHARPENING 2 +#define LUMADENOISE 2 +#define WHITEBALANCE 255 +#define COLORBOOST 1 +#define COLORDENOISE 1 +#define CROP 16384 +#define EXIF 32768 +#define IPTC 32768 +#define NONE 0 + +#define M_INIT 128 +#define M_TRANSFORM 64 +#define M_BLURMAP 32 +#define M_AUTOEXP 16 +#define M_RGBCURVE 8 +#define M_LUMACURVE 4 +#define M_LUMINANCE 2 +#define M_COLOR 1 + +extern int refreshmap[]; +#endif diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h new file mode 100644 index 000000000..afd56c85f --- /dev/null +++ b/rtengine/rtengine.h @@ -0,0 +1,386 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _RTENGINE_ +#define _RTENGINE_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/** + * @file + * This file contains the main functionality of the raw therapee engine. + * + */ + + +namespace rtengine { + + /** + * This class represents provides functions to obtain exif and IPTC metadata information + * from the image file + */ + class ImageMetaData { + + public: + /** Checks the availability of exif metadata tags. + * @return Returns true if image contains exif metadata tags */ + virtual bool hasExif () const =0; + /** Returns the directory of exif metadata tags. + * @return The directory of exif metadata tags */ + virtual const rtexif::TagDirectory* getExifData () const =0; + /** Checks the availability of IPTC tags. + * @return Returns true if image contains IPTC tags */ + virtual bool hasIPTC () const =0; + /** Returns the directory of IPTC tags. + * @return The directory of IPTC tags */ + virtual const std::vector getIPTCData () const =0; + /** @return a struct containing the date and time of the image */ + virtual struct tm getDateTime () const =0; + /** @return the ISO of the image */ + virtual int getISOSpeed () const =0; + /** @return the F number of the image */ + virtual double getFNumber () const =0; + /** @return the focal length used at the exposure */ + virtual double getFocalLen () const =0; + /** @return the shutter speed */ + virtual double getShutterSpeed () const =0; + /** @return the maker of the camera */ + virtual std::string getMake () const =0; + /** @return the model of the camera */ + virtual std::string getModel () const =0; + /** @return the lens on the camera */ + virtual std::string getLens () const =0; + /** Functions to convert between floating point and string representation of shutter and aperture */ + static std::string apertureToString (double aperture); + /** Functions to convert between floating point and string representation of shutter and aperture */ + static std::string shutterToString (double shutter); + /** Functions to convert between floating point and string representation of shutter and aperture */ + static double apertureFromString (std::string shutter); + /** Functions to convert between floating point and string representation of shutter and aperture */ + static double shutterFromString (std::string shutter); + + /** Reads metadata from file. + * @param fname is the name of the file + * @param rml is a struct containing information about metadata location. Use it only for raw files. In case + * of jpgs and tiffs pass a NULL pointer. + * @return The metadata */ + static ImageMetaData* fromFile (const Glib::ustring& fname, RawMetaDataLocation* rml); + }; + + /** This listener interface is used to indicate the progress of time consuming operations */ + class ProgressListener { + + public: + /** This member function is called when the percentage of the progress has been changed. + * @param p is a number between 0 and 1 */ + virtual void setProgress (double p) {} + /** This member function is called when a textual information corresponding to the progress has been changed. + * @param str is the textual information corresponding to the progress */ + virtual void setProgressStr (Glib::ustring str) {} + /** This member function is called when the state of the processing has been changed. + * @param state =1 if the processing has been started, =0 if it has been stopped */ + virtual void setProgressState (int state) {} + /** This member function is called when an error occurs during the operation. + * @param descr is the error message */ + virtual void error (Glib::ustring descr) {} + }; + + class ImageSource; + + /** + * This class represents an image loaded into the memory. It is the basis of further processing. + * In case of raw files the most time consuming operation, the demosaicing is already performed. + * The embedded icc profile and metadata information can be obtained through this class, too. + */ + class InitialImage { + + public: + /** Returns the file name of the image. + * @return The file name of the image */ + virtual Glib::ustring getFileName () =0; + /** Returns the embedded icc profile of the image. + * @return The handle of the embedded profile */ + virtual cmsHPROFILE getEmbeddedProfile () =0; + /** Returns a class providing access to the exif and iptc metadata tags of the image. + * @return An instance of the ImageMetaData class */ + virtual const ImageMetaData* getMetaData () =0; + /** This is a function used for internal purposes only. */ + virtual ImageSource* getImageSource () =0; + /** This class has manual reference counting. You have to call this function each time to make a new reference to an instance. */ + virtual void increaseRef () {} + /** This class has manual reference counting. You have to call this function each time to remove a reference + * (the last one deletes the instance automatically). */ + virtual void decreaseRef () {} + + + /** Loads an image into the memory. If it is a raw file, is is partially demosaiced (the time consuming part is done) + * @param fname the name of the file + * @param isRaw shall be true if it is a raw file + * @param errorCode is a pointer to a variable that is set to nonzero if an error happened (output) + * @param pl is a pointer pointing to an object implementing a progress listener. It can be NULL, in this case progress is not reported. + * @return an object representing the loaded and pre-processed image */ + static InitialImage* load (const Glib::ustring& fname, bool isRaw, int* errorCode, ProgressListener* pl = NULL); + }; + + /** When the preview image is ready for display during staged processing (thus the changes have been updated), + * the staged processor notifies the listener class implementing a PreviewImageListener. + * It is important to note that the file passed to the listener can be used in a shared manner (copying it is not + * needed) as long as the mutex corresponding to the image is used every time the image is accessed. + * If the scale of the preview image is >1, no sharpening, no denoising and no cropping is applied, and + * the transform operations (rotate, c/a, vignetting correction) are performed using a faster less quality algorithm. + * The image you get with this listener is created to display on the monitor (monitor profile has been already applied). */ + class PreviewImageListener { + public: + /** With this member function the staged processor notifies the listener that it allocated a new + * image to store the end result of the processing. It can be used in a shared manner. + * @param img is a pointer to the image + * @param scale describes the current scaling applied compared to the 100% size (preview scale + resize scale) + * @param cp holds the coordinates of the current crop rectangle */ + virtual void setImage (IImage8* img, double scale, procparams::CropParams cp) {} + /** With this member function the staged processor notifies the listener that the image passed as parameter + * will be deleted, and no longer used to store the preview image. + * @param img the pointer to the image to be destroyed. The listener has to free the image! */ + virtual void delImage (IImage8* img) {} + /** With this member function the staged processor notifies the listener that the preview image has been updated. + * @param cp holds the coordinates of the current crop rectangle */ + virtual void imageReady (procparams::CropParams cp) {} + }; + + /** When the detailed crop image is ready for display during staged processing (thus the changes have been updated), + * the staged processor notifies the listener class implementing a DetailedCropListener. + * It is important to note that the file passed to the listener can not be used in a shared manner, the class + * implementing this interface has to store a copy of it. */ + class DetailedCropListener { + public: + /** With this member function the staged processor notifies the listener that the detailed crop image has been updated. + * @param img is a pointer to the detailed crop image */ + virtual void setDetailedCrop (IImage8* img, procparams::CropParams cp, int cx, int cy, int cw, int ch, int skip) {} + virtual bool getWindow (int& cx, int& cy, int& cw, int& ch, int& skip) { return false; } + }; + + /** This listener is used when the full size of the final image has been changed (e.g. rotated by 90 deg.) */ + class SizeListener { + public: + /** This member function is called when the size of the final image has been changed + * @param w is the width of the final image (without cropping) + * @param h is the height of the final image (without cropping) + * @param ow is the width of the final image (without resizing and cropping) + * @param oh is the height of the final image (without resizing and cropping) */ + virtual void sizeChanged (int w, int h, int ow, int oh) {} + }; + + /** This listener is used when the histogram of the final image has changed. */ + class HistogramListener { + public: + /** This member function is called when the histogram of the final image has changed. + * @param redh is the array of size 256 containing the histogram of the red channel + * @param greenh is the array of size 256 containing the histogram of the green channel + * @param blueh is the array of size 256 containing the histogram of the blue channel + * @param lumah is the array of size 256 containing the histogram of the luminance channel */ + virtual void histogramChanged (unsigned int* redh, unsigned int* greenh, unsigned int* blueh, unsigned int* lumah, unsigned int* bcrgbhist, unsigned int* bcLhist) {} + }; + + /** This listener is used when the auto exposure has been recomputed (e.g. when the clipping ratio changed). */ + class AutoExpListener { + public: + /** This member function is called when the auto exposure has been recomputed. + * @param brightness is the new brightness value (in logarithmic scale) + * @param black is the new black level (measured in absolute pixel data) */ + virtual void autoExpChanged (double brightness, int black) {} + }; + + /** This class represents a detailed part of the image (looking through a kind of window). + * It can be created and destroyed with the appropriate members of StagedImageProcessor. + * Several crops can be assigned to the same image. */ + class DetailedCrop { + public: + /** Sets the window defining the crop. */ + virtual void setWindow (int cx, int cy, int cw, int ch, int skip) {} + /** Perform a full recalculation of the part of the image corresponding to the crop. */ + virtual void fullUpdate () {} + /** Sets the listener of the crop. */ + virtual void setListener (DetailedCropListener* il) {} + /** Destroys the crop. */ + virtual void destroy () {} + }; + + /** This is a staged, cached image processing manager with partial image update support. */ + class StagedImageProcessor { + + public: + /** Returns the inital image corresponding to the image processor. + * @return the inital image corresponding to the image processor */ + virtual InitialImage* getInitialImage () =0; + /** Returns the current processing parameters. + * @param dst is the location where the image processing parameters are copied (it is assumed that the memory is allocated by the caller) */ + virtual void getParams (procparams::ProcParams* dst) =0; + /** An essential member function. Call this when a setting has been changed. This function returns a pointer to the + * processing parameters, that you have to update to reflect the changed situation. When ready, call the paramsUpdateReady + * function to start the image update. + * @param change is the ID of the changed setting */ + virtual procparams::ProcParams* getParamsForUpdate (ProcEvent change) =0; + /** An essential member function. This indicates that you are ready with the update of the processing parameters you got + * with the getParamsForUpdate call, so the image can be updated. This function returns immediately. + * The image update starts immediately in the background. If it is ready, the result is passed to a PreviewImageListener + * and to a DetailedCropListener (if enabled). */ + virtual void paramsUpdateReady () =0; + /** Stops image processing. When it returns, the image processing is already stopped. */ + virtual void stopProcessing () =0; + /** Sets the scale of the preview image. The larger the number is, the faster the image updates are (typical values are 4-5). + * @param scale is the scale of the preview image */ + virtual void setPreviewScale (int scale) =0; + /** Returns the scale of the preview image. + * @return the current scale of the preview image */ + virtual int getPreviewScale () =0; + /** Performs a full update on the preview image. The resulting image is passed to the listener. */ + virtual void fullUpdatePreviewImage () =0; + /** Performs a full update on the detailed crops corresponding to the image. The resulting images are passed to the listeners of the crops. */ + virtual void fullUpdateDetailedCrops () =0; + /** Returns the full width of the resulting image (in 1:1 scale). + * @return the width of the final image */ + virtual int getFullWidth () =0; + /** Returns the full height of the resulting image (in 1:1 scale). + * @return the height of the final image */ + virtual int getFullHeight () =0; + /** Returns the width of the preview image. + * @return the width of the preview image */ + virtual int getPreviewWidth () =0; + /** Returns the height of the preview image. + * @return the height of the preview image */ + virtual int getPreviewHeight () =0; + + /** Creates and returns a Crop instance that acts as a window on the image */ + virtual DetailedCrop* createCrop () =0; + + virtual void getAutoWB (double& temp, double& green) =0; + virtual void getCamWB (double& temp, double& green) =0; + virtual void getSpotWB (int x, int y, int rectSize, double& temp, double& green) =0; + virtual void getAutoCrop (double ratio, int &x, int &y, int &w, int &h) =0; + + virtual void saveInputICCReference (const Glib::ustring& fname) =0; + + virtual void setProgressListener (ProgressListener* l) =0; + virtual void setSizeListener (SizeListener* l) =0; + virtual void delSizeListener (SizeListener* l) =0; + virtual void setAutoExpListener (AutoExpListener* l) =0; + virtual void setHistogramListener (HistogramListener *l) =0; + virtual void setPreviewImageListener (PreviewImageListener* l) =0; + + virtual ~StagedImageProcessor () {} + + /** Returns a staged, cached image processing manager supporting partial updates + * @param initialImage is a loaded and pre-processed initial image + * @return the staged image processing manager */ + static StagedImageProcessor* create (InitialImage* initialImage); + static void destroy (StagedImageProcessor* sip); + }; + + +/** + * Initializes the RT engine + * @param s is a struct of basic settings */ + int init (const Settings* s); + +/** Checks if a raw file is supported + * @param fname the name of the file + * @param rml is a struct constaining informations on the location of the metadata in the raw file + * @param rotation is the default angle of rotation (0, 90, 180, 270) + * @param thumbWidth is the width of the embedded thumbnail file + * @param thumbHeight is the height of the embedded thumbnail file + * @param thumbOffset is the offset of the embedded thumbnail in the raw file + * @param thumbType is the type of the embedded thumbnail (=0: no thumbnail, =1: jpeg format, =2: simple continuous image data in rgbrgb... order) + * @return =0 if not supported */ + int getRawFileBasicInfo (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, int& rotation, int& thumbWidth, int& thumbHeight, int& thumbOffset, int& thumbType); + +/** Returns the available output profile names + * @return a vector of the available output profile names */ + std::vector getOutputProfiles (); + +/** Returns the available working profile names + * @return a vector of the available working profile names */ + std::vector getWorkingProfiles (); + + /** This class holds all the necessary informations to accomplish the full processing of the image */ + class ProcessingJob { + + public: + + /** Creates a processing job from a file name. This function always succeeds. It only stores the data into the ProcessingJob class, it does not load + * the image thus it returns immediately. + * @param fname the name of the file + * @param isRaw shall be true if it is a raw file + * @param pparams is a struct containing the processing parameters + * @return an object containing the data above. It can be passed to the functions that do the actual image processing. */ + static ProcessingJob* create (const Glib::ustring& fname, bool isRaw, const procparams::ProcParams& pparams); + + /** Creates a processing job from a file name. This function always succeeds. It only stores the data into the ProcessingJob class, it does not load + * the image thus it returns immediately. This function increases the reference count of the initialImage. If you decide not the process the image you + * have to cancel it by calling the member function void cancel(). If the image is processed the reference count of initialImage is decreased automatically, thus the ProcessingJob + * instance gets invalid. You can not use a ProcessingJob instance to process an image twice. + * @param initialImage is a loaded and pre-processed initial image + * @param pparams is a struct containing the processing parameters + * @return an object containing the data above. It can be passed to the functions that do the actual image processing. */ + static ProcessingJob* create (InitialImage* initialImage, const procparams::ProcParams& pparams); + + /** Cancels and destroys a processing job. The reference count of the corresponding initialImage (if any) is decreased. After the call of this function the ProcessingJob instance + * gets invalid, you must not use it any more. Dont call this function while the job is being processed. + * @param job is the job to destroy */ + static void destroy (ProcessingJob* job); + }; + +/** This function performs all the image processinf steps corresponding to the given ProcessingJob. It returns when it is ready, so it can be slow. + * The ProcessingJob passed becomes invalid, you can not use it any more. + * @param job the ProcessingJob to cancel. + * @param errorCode is the error code if an error occured (e.g. the input image could not be loaded etc.) + * @param pl is an optional ProgressListener if you want to keep track of the progress + * @return the resulting image, with the output profile applied, exif and iptc data set. You have to save it or you can access the pixel data directly. */ + IImage16* processImage (ProcessingJob* job, int& errorCode, ProgressListener* pl = NULL); + +/** This class is used to control the batch processing. The class implementing this interface will be called when the full processing of an + * image is ready and the next job to process is needed. */ + class BatchProcessingListener : public ProgressListener { + public: + /** This function is called when an image gets ready during the batch processing. It has to return with the next job, or with NULL if + * there is no jobs left. + * @param img is the result of the last ProcessingJob + * @return the next ProcessingJob to process */ + virtual ProcessingJob* imageReady (IImage16* img) =0; + }; +/** This function performs all the image processinf steps corresponding to the given ProcessingJob. It runs in the background, thus it returns immediately, + * When it finishes, it calls the BatchProcessingListener with the resulting image and asks for the next job. It the listener gives a new job, it goes on + * with processing. If no new job is given, it finishes. + * The ProcessingJob passed becomes invalid, you can not use it any more. + * @param job the ProcessingJob to cancel. + * @param bpl is the BatchProcessingListener that is called when the image is ready or the next job is needed. It also acts as a ProgressListener. */ + void startBatchProcessing (ProcessingJob* job, BatchProcessingListener* bpl); + + + extern Glib::Mutex* lcmsMutex; +} + +#endif + diff --git a/rtengine/rtetest.cc b/rtengine/rtetest.cc new file mode 100644 index 000000000..5ee8409db --- /dev/null +++ b/rtengine/rtetest.cc @@ -0,0 +1,71 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +//#include +#include + +class PListener : public rtengine::ProgressListener { + + public: + void setProgressStr (Glib::ustring str) { + std::cout << str << std::endl; + } + void setProgress (double p) { + std::cout << p << std::endl; + } +}; + +int main (int argc, char* argv[]) { + + if (argc<4) { + std::cout << "Usage: rtcmd " << std::endl; + exit(1); + } + + rtengine::Settings s; + s.dualThreadEnabled = true; + s.demosaicMethod = "hphd"; + s.colorCorrectionSteps = 2; + s.iccDirectory = ""; + s.colorimetricIntent = 1; + s.monitorProfile = ""; + + Glib::thread_init (); + rtengine::init (s); + PListener pl; + + rtengine::InitialImage* ii; + int errorCode; + ii = rtengine::InitialImage::load (argv[1], true, errorCode, &pl); + if (!ii) + ii = rtengine::InitialImage::load (argv[1], false, errorCode, &pl); + if (!ii) { + std::cout << "Input file not supported." << std::endl; + exit(2); + } + + rtengine::procparams::ProcParams params; + params.load (argv[2]); + + rtengine::ProcessingJob* job = ProcessingJob::create (ii, params); + rtengine::IImage16* res = rtengine::processImage (job, errorCode, &pl); + res->saveToFile (argv[3]); +} + diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc new file mode 100644 index 000000000..ed47494ee --- /dev/null +++ b/rtengine/rtthumbnail.cc @@ -0,0 +1,893 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#include +extern jmp_buf jpeg_jmp_buf; +extern GLOBAL(struct jpeg_error_mgr *) +my_jpeg_std_error (struct jpeg_error_mgr * err); +extern GLOBAL(void) +my_jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile); +} + +#define MAXVAL 0xffff +#define CLIP(a) ((a)>0?((a)load (fname); + if (err) { + delete img; + return NULL; + } + + Thumbnail* tpp = new Thumbnail (); + + tpp->camwbRed = 1.0; + tpp->camwbGreen = 1.0; + tpp->camwbBlue = 1.0; + + tpp->embProfileLength = 0; + unsigned char* data; + img->getEmbeddedProfileData (tpp->embProfileLength, data); + if (data && tpp->embProfileLength) { + tpp->embProfileData = new unsigned char [tpp->embProfileLength]; + memcpy (tpp->embProfileData, data, tpp->embProfileLength); + } + else { + tpp->embProfileLength = 0; + tpp->embProfileData = NULL; + } + + tpp->redMultiplier = 1.0; + tpp->greenMultiplier = 1.0; + tpp->blueMultiplier = 1.0; + + tpp->scaleForSave = 8192; + tpp->defGain = 1.0; + tpp->gammaCorrected = false; + tpp->isRaw = 0; + memset (tpp->colorMatrix, 0, sizeof(tpp->colorMatrix)); + tpp->colorMatrix[0][0] = 1.0; + tpp->colorMatrix[1][1] = 1.0; + tpp->colorMatrix[2][2] = 1.0; + + if (fixwh==1) { + w = h * img->width / img->height; + tpp->scale = (double)img->height / h; + } + else { + h = w * img->height / img->width; + tpp->scale = (double)img->width / w; + } + + // bilinear interpolation + tpp->thumbImg = img->resize (w, h, TI_Bilinear); + + // histogram computation + tpp->aeHistCompression = 3; + tpp->aeHistogram = new unsigned int[65536>>tpp->aeHistCompression]; + memset (tpp->aeHistogram, 0, (65536>>tpp->aeHistCompression)*sizeof(int)); + int ix = 0; + for (int i=0; iheight*img->width; i++) { + tpp->aeHistogram[CurveFactory::igamma_srgb (img->data[ix++])>>tpp->aeHistCompression]++; + tpp->aeHistogram[CurveFactory::igamma_srgb (img->data[ix++])>>tpp->aeHistCompression]++; + tpp->aeHistogram[CurveFactory::igamma_srgb (img->data[ix++])>>tpp->aeHistCompression]++; + } + + // autowb computation + double avg_r = 0; + double avg_g = 0; + double avg_b = 0; + int n = 0; + int p = 6; + for (int i=1; iheight-1; i++) + for (int j=1; jwidth-1; j++) { + int ofs = 3*(i*img->width + j); + if (img->data[ofs]>250 || img->data[ofs+1]>250 || img->data[ofs+2]>250) + continue; + avg_r += StdImageSource::intpow((double)img->data[ofs]*256, p); + avg_g += StdImageSource::intpow((double)img->data[ofs+1]*256, p); + avg_b += StdImageSource::intpow((double)img->data[ofs+2]*256, p); + n++; + } + ColorTemp::mul2temp (pow(avg_r/n, 1.0/p), pow(avg_g/n, 1.0/p), pow(avg_b/n, 1.0/p), tpp->autowbTemp, tpp->autowbGreen); + + delete img; + tpp->init (); + return tpp; +} + +void Thumbnail::init () { + + RawImageSource::inverse33 (colorMatrix, iColorMatrix); + memset (camToD50, 0, sizeof(camToD50)); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + camToD50[i][j] += colorMatrix[k][i] * sRGB_d50[k][j]; + camProfile = iccStore.createFromMatrix (camToD50, false, "Camera"); +} + +bool Thumbnail::igammacomputed = false; +unsigned short Thumbnail::igammatab[256]; +unsigned char Thumbnail::gammatab[65536]; + +Thumbnail::Thumbnail () : + embProfile(NULL), camProfile(NULL), aeHistogram(NULL), thumbImg(NULL), embProfileData(NULL) { + + if (!igammacomputed) { + for (int i=0; i<256; i++) + igammatab[i] = (unsigned short)(255.0*pow(i/255.0,1.0/0.45)); + for (int i=0; i<65536; i++) + gammatab[i] = (unsigned char)(255.0*pow(i/65535.0,0.45)); + igammacomputed = true; + } +} + +Thumbnail::~Thumbnail () { + + delete thumbImg; + delete [] aeHistogram; + delete [] embProfileData; + if (embProfile) + cmsCloseProfile(embProfile); + if (camProfile) + cmsCloseProfile(camProfile); +} + +IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rheight, TypeInterpolation interp, double& myscale) { + + // compute WB multipliers + ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green); + if (params.wb.method=="Camera") { + double cam_r = colorMatrix[0][0]*camwbRed + colorMatrix[0][1]*camwbGreen + colorMatrix[0][2]*camwbBlue; + double cam_g = colorMatrix[1][0]*camwbRed + colorMatrix[1][1]*camwbGreen + colorMatrix[1][2]*camwbBlue; + double cam_b = colorMatrix[2][0]*camwbRed + colorMatrix[2][1]*camwbGreen + colorMatrix[2][2]*camwbBlue; + currWB = ColorTemp (cam_r, cam_g, cam_b); + } + else if (params.wb.method=="Auto") + currWB = ColorTemp (autowbTemp, autowbGreen); + double r, g, b; + currWB.getMultipliers (r, g, b); + double rm = iColorMatrix[0][0]*r + iColorMatrix[0][1]*g + iColorMatrix[0][2]*b; + double gm = iColorMatrix[1][0]*r + iColorMatrix[1][1]*g + iColorMatrix[1][2]*b; + double bm = iColorMatrix[2][0]*r + iColorMatrix[2][1]*g + iColorMatrix[2][2]*b; + rm = camwbRed / rm; + gm = camwbGreen / gm; + bm = camwbBlue / bm; + double mul_lum = 0.299*rm + 0.587*gm + 0.114*bm; + double logDefGain = log(defGain) / log(2.0); + int rmi, gmi, bmi; + if (!isRaw || !params.hlrecovery.enabled) { + logDefGain = 0.0; + rmi = 1024.0 * rm * defGain / mul_lum; + gmi = 1024.0 * gm * defGain / mul_lum; + bmi = 1024.0 * bm * defGain / mul_lum; + } + else { + rmi = 1024.0 * rm / mul_lum; + gmi = 1024.0 * gm / mul_lum; + bmi = 1024.0 * bm / mul_lum; + } + // resize to requested with and perform coarse transformation + int rwidth; + if (params.coarse.rotate==90 || params.coarse.rotate==270) { + rwidth = rheight; + rheight = thumbImg->height * rwidth / thumbImg->width; + } + else + rwidth = thumbImg->width * rheight / thumbImg->height; + + Image16* baseImg = thumbImg->resize (rwidth, rheight, interp); + + if (params.coarse.rotate) { + Image16* tmp = baseImg->rotate (params.coarse.rotate); + rwidth = tmp->width; + rheight = tmp->height; + delete baseImg; + baseImg = tmp; + } + if (params.coarse.hflip) { + Image16* tmp = baseImg->hflip (); + delete baseImg; + baseImg = tmp; + } + if (params.coarse.vflip) { + Image16* tmp = baseImg->vflip (); + delete baseImg; + baseImg = tmp; + } + // apply white balance + int val; + for (int i=0; ir[i][j]*rmi>>10; + baseImg->r[i][j] = CLIP(val); + val = baseImg->g[i][j]*gmi>>10; + baseImg->g[i][j] = CLIP(val); + val = baseImg->b[i][j]*bmi>>10; + baseImg->b[i][j] = CLIP(val); + } + + // appy highlight recovery, if needed + if (isRaw && params.hlrecovery.enabled) { + int maxval = 65535 / defGain; + if (params.hlrecovery.method=="Luminance" || params.hlrecovery.method=="Color") + for (int i=0; ir[i], baseImg->g[i], baseImg->b[i], baseImg->r[i], baseImg->g[i], baseImg->b[i], rwidth, maxval); + else if (params.hlrecovery.method=="CIELab blending") { + double icamToD50[3][3]; + RawImageSource::inverse33 (camToD50, icamToD50); + for (int i=0; ir[i], baseImg->g[i], baseImg->b[i], baseImg->r[i], baseImg->g[i], baseImg->b[i], rwidth, maxval, camToD50, icamToD50); + } + } + + // perform color space transformation + if (isRaw) + RawImageSource::colorSpaceConversion (baseImg, params.icm, embProfile, camProfile, camToD50, logDefGain); + else + StdImageSource::colorSpaceConversion (baseImg, params.icm, embProfile); + + int fw = baseImg->width; + int fh = baseImg->height; + + ImProcFunctions ipf; + unsigned int* hist16 = new unsigned int [65536]; + ipf.firstAnalysis (baseImg, ¶ms, hist16, isRaw ? 2.2 : 0.0); + + // perform transform + bool needstransform = fabs(params.rotate.degree)>1e-15 || fabs(params.distortion.amount)>1e-15 || fabs(params.cacorrection.red)>1e-15 || fabs(params.cacorrection.blue)>1e-15; + bool needsvignetting = params.vignetting.amount!=0; + + if (!needstransform && needsvignetting) { + Image16* trImg = new Image16 (fw, fh); + ipf.vignetting (baseImg, trImg, ¶ms, 0, 0, fw, fh); + delete baseImg; + baseImg = trImg; + } + else if (needstransform) { + Image16* trImg = new Image16 (fw, fh); + ipf.simpltransform (baseImg, trImg, ¶ms, 0, 0, 0, 0, fw, fh); + delete baseImg; + baseImg = trImg; + } + + // update blurmap + SHMap* shmap = NULL; + if (params.sh.enabled) { + unsigned short** buffer = NULL; + if (params.sh.hq) { + buffer = new unsigned short*[fh]; + for (int i=0; iupdate (baseImg, buffer, shradius, ipf.lumimul, params.sh.hq); + if (buffer) { + for (int i=0; iL[i][j]]++; + + // luminance processing + CurveFactory::complexCurve (0.0, 0.0, 0.0, 0.0, params.lumaCurve.brightness, params.lumaCurve.contrast, 0.0, 0.0, false, params.lumaCurve.curve, hist16, curve, NULL, 16); + + ipf.luminanceCurve (labView, labView, curve, 0, fh); + + delete [] curve; + delete [] hist16; + + // color processing + ipf.colorCurve (labView, labView, ¶ms); + + // obtain final image + Image8* readyImg = new Image8 (fw, fh); + ipf.lab2rgb (labView, readyImg); + ipf.release (); + delete baseImg; + + // calculate scale + if (params.coarse.rotate==90 || params.coarse.rotate==270) + myscale = scale * thumbImg->width / fh; + else + myscale = scale * thumbImg->height / fh; + + if (params.resize.enabled) { + if (params.resize.dataspec==0) + myscale *= params.resize.scale; + else if (params.resize.dataspec==1) + myscale *= (double)params.resize.width / (params.coarse.rotate==90 || params.coarse.rotate==270 ? thumbImg->height : thumbImg->width) / scale; + else if (params.resize.dataspec==2) + myscale *= (double)params.resize.height / (params.coarse.rotate==90 || params.coarse.rotate==270 ? thumbImg->width : thumbImg->height) / scale; + } + myscale = 1.0 / myscale; + +/* // apply crop + if (params.crop.enabled) { + int ix = 0; + for (int i=0; i(params.crop.y+params.crop.h)/myscale || j(params.crop.x+params.crop.w)/myscale) { + readyImg->data[ix++] /= 3; + readyImg->data[ix++] /= 3; + readyImg->data[ix++] /= 3; + } + else + ix += 3; + }*/ + return readyImg; +} + +int Thumbnail::getImageWidth (const procparams::ProcParams& params, int rheight) { + + int rwidth; + if (params.coarse.rotate==90 || params.coarse.rotate==270) + rwidth = thumbImg->height * rheight / thumbImg->width; + else + rwidth = thumbImg->width * rheight / thumbImg->height; + + return rwidth; +} + +void Thumbnail::getFinalSize (const rtengine::procparams::ProcParams& params, int& fullw, int& fullh) { + + double fw = thumbImg->width*scale; + double fh = thumbImg->height*scale; + + if (params.coarse.rotate==90 || params.coarse.rotate==270) { + fh = thumbImg->width*scale; + fw = thumbImg->height*scale; + } + if (!params.resize.enabled) { + fullw = fw; + fullh = fh; + } + else if (params.resize.dataspec==0) { + fullw = fw*params.resize.scale; + fullh = fh*params.resize.scale; + } + else if (params.resize.dataspec==1) { + fullw = params.resize.width; + fullh = (double)fh*params.resize.width/(params.coarse.rotate==90 || params.coarse.rotate==270 ? fh : fw); + } + else if (params.resize.dataspec==2) { + fullw = (double)fw*params.resize.height/(params.coarse.rotate==90 || params.coarse.rotate==270 ? fw : fh); + fullh = params.resize.height; + } +} + +void Thumbnail::getCamWB (double& temp, double& green) { + + double cam_r = colorMatrix[0][0]*camwbRed + colorMatrix[0][1]*camwbGreen + colorMatrix[0][2]*camwbBlue; + double cam_g = colorMatrix[1][0]*camwbRed + colorMatrix[1][1]*camwbGreen + colorMatrix[1][2]*camwbBlue; + double cam_b = colorMatrix[2][0]*camwbRed + colorMatrix[2][1]*camwbGreen + colorMatrix[2][2]*camwbBlue; + ColorTemp currWB = ColorTemp (cam_r, cam_g, cam_b); + temp = currWB.getTemp (); + green = currWB.getGreen (); +} + +void Thumbnail::getAutoWB (double& temp, double& green) { + + temp = autowbTemp; + green = autowbGreen; +} + +void Thumbnail::applyAutoExp (procparams::ProcParams& params) { + + if (params.toneCurve.autoexp && aeHistogram) + ImProcFunctions::getAutoExp (aeHistogram, aeHistCompression, log(defGain) / log(2.0), params.toneCurve.clip, params.toneCurve.expcomp, params.toneCurve.black); +} + +void Thumbnail::getSpotWB (const procparams::ProcParams& params, int xp, int yp, int rect, double& rtemp, double& rgreen) { + + std::vector points, red, green, blue; + for (int i=yp-rect; i<=yp+rect; i++) + for (int j=xp-rect; j<=xp+rect; j++) + points.push_back (Coord2D (j, i)); + + int fw = thumbImg->width, fh = thumbImg->height; + if (params.coarse.rotate==90 || params.coarse.rotate==270) { + fw = thumbImg->height; + fh = thumbImg->width; + } + ImProcFunctions ipf; + ipf.transCoord (¶ms, fw, fh, points, red, green, blue); + int tr = TR_NONE; + if (params.coarse.rotate==90) tr |= TR_R90; + if (params.coarse.rotate==180) tr |= TR_R180; + if (params.coarse.rotate==270) tr |= TR_R270; + if (params.coarse.hflip) tr |= TR_HFLIP; + if (params.coarse.vflip) tr |= TR_VFLIP; + + // calculate spot wb (copy & pasted from stdimagesource) + unsigned short igammatab[256]; + for (int i=0; i<256; i++) + igammatab[i] = (unsigned short)(255.0*pow(i/255.0,1.0/0.45)); + int x; int y; + double reds = 0, greens = 0, blues = 0; + int rn = 0, gn = 0, bn = 0; + for (int i=0; i=0 && y>=0 && xwidth && yheight) { + reds += thumbImg->r[y][x]; + rn++; + } + transformPixel (green[i].x, green[i].y, tr, x, y); + if (x>=0 && y>=0 && xwidth && yheight) { + greens += thumbImg->g[y][x]; + gn++; + } + transformPixel (blue[i].x, blue[i].y, tr, x, y); + if (x>=0 && y>=0 && xwidth && yheight) { + blues += thumbImg->b[y][x]; + bn++; + } + } + reds = reds/rn * camwbRed; + greens = greens/gn * camwbGreen; + blues = blues/bn * camwbBlue; + + double rm = colorMatrix[0][0]*reds + colorMatrix[0][1]*greens + colorMatrix[0][2]*blues; + double gm = colorMatrix[1][0]*reds + colorMatrix[1][1]*greens + colorMatrix[1][2]*blues; + double bm = colorMatrix[2][0]*reds + colorMatrix[2][1]*greens + colorMatrix[2][2]*blues; + + ColorTemp ct (rm, gm, bm); + rtemp = ct.getTemp (); + rgreen = ct.getGreen (); +} +void Thumbnail::transformPixel (int x, int y, int tran, int& tx, int& ty) { + + int W = thumbImg->width; + int H = thumbImg->height; + int sw = W, sh = H; + if ((tran & TR_ROT) == TR_R90 || (tran & TR_ROT) == TR_R270) { + sw = H; + sh = W; + } + + int ppx = x, ppy = y; + if (tran & TR_HFLIP) + ppx = sw - 1 - x ; + if (tran & TR_VFLIP) + ppy = sh - 1 - y; + + tx = ppx; + ty = ppy; + + if ((tran & TR_ROT) == TR_R180) { + tx = W - 1 - ppx; + ty = H - 1 - ppy; + } + else if ((tran & TR_ROT) == TR_R90) { + tx = ppy; + ty = H - 1 - ppx; + } + else if ((tran & TR_ROT) == TR_R270) { + tx = W - 1 - ppy; + ty = ppx; + } + tx/=scale; + ty/=scale; +} + +bool Thumbnail::writeImage (const Glib::ustring& fname, int format) { + + if (!thumbImg) + return false; + + if (format==1 || format==3) { + // to utilize the 8 bit color range of the thumbnail we brighten it and apply gamma correction + int max = 0; + for (int row=0; rowheight; row++) + for (int col=0; colwidth; col++) { + if (thumbImg->r[row][col]>max) + max = thumbImg->r[row][col]; + if (thumbImg->g[row][col]>max) + max = thumbImg->r[row][col]; + if (thumbImg->b[row][col]>max) + max = thumbImg->r[row][col]; + } + if (max < 16384) + max = 16384; + scaleForSave = 65535*8192 / max; + unsigned char* tmpdata = new unsigned char[thumbImg->height*thumbImg->width*3]; + int ix = 0; + if (gammaCorrected) { + for (int i=0; iheight; i++) + for (int j=0; jwidth; j++) { + tmpdata[ix++] = gammatab[thumbImg->r[i][j]*scaleForSave >> 13]; + tmpdata[ix++] = gammatab[thumbImg->g[i][j]*scaleForSave >> 13]; + tmpdata[ix++] = gammatab[thumbImg->b[i][j]*scaleForSave >> 13]; + } + } + else { + for (int i=0; iheight; i++) + for (int j=0; jwidth; j++) { + tmpdata[ix++] = thumbImg->r[i][j]*scaleForSave >> 21; + tmpdata[ix++] = thumbImg->g[i][j]*scaleForSave >> 21; + tmpdata[ix++] = thumbImg->b[i][j]*scaleForSave >> 21; + } + } + if (format==1) { + FILE* f = g_fopen (fname.c_str(), "wb"); + if (!f) { + delete [] tmpdata; + return false; + } + fwrite (&thumbImg->width, 1, sizeof (int), f); + fwrite (&thumbImg->height, 1, sizeof (int), f); + fwrite (tmpdata, thumbImg->width*thumbImg->height, 3, f); + fclose (f); + } + else if (format==3) { + FILE* f = g_fopen (fname.c_str(), "wb"); + if (!f) { + delete [] tmpdata; + return false; + } + jpeg_compress_struct cinfo; + jpeg_error_mgr jerr; + cinfo.err = jpeg_std_error (&jerr); + jpeg_create_compress (&cinfo); + jpeg_stdio_dest (&cinfo, f); + cinfo.image_width = thumbImg->width; + cinfo.image_height = thumbImg->height; + cinfo.in_color_space = JCS_RGB; + cinfo.input_components = 3; + jpeg_set_defaults (&cinfo); + cinfo.write_JFIF_header = FALSE; + jpeg_set_quality (&cinfo, 85, true); + jpeg_start_compress(&cinfo, TRUE); + int rowlen = thumbImg->width*3; + while (cinfo.next_scanline < cinfo.image_height) { + unsigned char* row = tmpdata + cinfo.next_scanline*thumbImg->width*3; + if (jpeg_write_scanlines (&cinfo, &row, 1) < 1) { + jpeg_finish_compress (&cinfo); + jpeg_destroy_compress (&cinfo); + fclose (f); + delete [] tmpdata; + return false; + } + } + jpeg_finish_compress (&cinfo); + jpeg_destroy_compress (&cinfo); + fclose (f); + } + delete [] tmpdata; + return true; + } + else if (format==2) { + FILE* f = g_fopen (fname.c_str(), "wb"); + if (!f) + return false; + fwrite (&thumbImg->width, 1, sizeof (int), f); + fwrite (&thumbImg->height, 1, sizeof (int), f); + for (int i=0; iheight; i++) + fwrite (thumbImg->r[i], thumbImg->width, 2, f); + for (int i=0; iheight; i++) + fwrite (thumbImg->g[i], thumbImg->width, 2, f); + for (int i=0; iheight; i++) + fwrite (thumbImg->b[i], thumbImg->width, 2, f); + fclose (f); + return true; + } + else + return false; +} + +bool Thumbnail::readImage (const Glib::ustring& fname) { + + delete thumbImg; + thumbImg = NULL; + + int imgType = 0; + if (Glib::file_test (fname+".cust16", Glib::FILE_TEST_EXISTS)) + imgType = 2; + if (Glib::file_test (fname+".cust", Glib::FILE_TEST_EXISTS)) + imgType = 1; + else if (Glib::file_test (fname+".jpg", Glib::FILE_TEST_EXISTS)) + imgType = 3; + + if (!imgType) + return false; + else if (imgType==1) { + FILE* f = g_fopen ((fname+".cust").c_str(), "rb"); + if (!f) + return false; + int width, height; + fread (&width, 1, sizeof (int), f); + fread (&height, 1, sizeof (int), f); + unsigned char* tmpdata = new unsigned char [width*height*3]; + fread (tmpdata, width*height, 3, f); + fclose (f); + thumbImg = new Image16 (width, height); + int ix = 0, val; + for (int i=0; ir[i][j] = CLIP(val); + val = igammatab[tmpdata[ix++]]*256*8192/scaleForSave; + thumbImg->g[i][j] = CLIP(val); + val = igammatab[tmpdata[ix++]]*256*8192/scaleForSave; + thumbImg->b[i][j] = CLIP(val); + } + else { + val = tmpdata[ix++]*256*8192/scaleForSave; + thumbImg->r[i][j] = CLIP(val); + val = tmpdata[ix++]*256*8192/scaleForSave; + thumbImg->g[i][j] = CLIP(val); + val = tmpdata[ix++]*256*8192/scaleForSave; + thumbImg->b[i][j] = CLIP(val); + } + delete [] tmpdata; + return true; + } + else if (imgType==2) { + FILE* f = g_fopen ((fname+".cust16").c_str(), "rb"); + if (!f) + return false; + int width, height; + fread (&width, 1, sizeof (int), f); + fread (&height, 1, sizeof (int), f); + thumbImg = new Image16 (width, height); + for (int i=0; ir[i], width, 2, f); + for (int i=0; ig[i], width, 2, f); + for (int i=0; ib[i], width, 2, f); + fclose (f); + return true; + } + else if (imgType==3) { + FILE* f = g_fopen ((fname+".jpg").c_str(), "rb"); + if (!f) + return false; + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + if (!setjmp(jpeg_jmp_buf)) { + cinfo.err = my_jpeg_std_error (&jerr); + jpeg_create_decompress (&cinfo); + my_jpeg_stdio_src (&cinfo,f); + jpeg_read_header (&cinfo, TRUE); + int width, height; + width = cinfo.image_width; + height = cinfo.image_height; + cinfo.dct_method = JDCT_FASTEST; + cinfo.do_fancy_upsampling = 1; + jpeg_start_decompress(&cinfo); + thumbImg = new Image16 (width, height); + unsigned char* row = new unsigned char [width*3]; + while (cinfo.output_scanline < cinfo.output_height) { + jpeg_read_scanlines (&cinfo, &row, 1); + int ix = 0, val; + for (int j=0; jr[cinfo.output_scanline-1][j] = CLIP(val); + val = igammatab[row[ix++]]*256*8192/scaleForSave; + thumbImg->g[cinfo.output_scanline-1][j] = CLIP(val); + val = igammatab[row[ix++]]*256*8192/scaleForSave; + thumbImg->b[cinfo.output_scanline-1][j] = CLIP(val); + } + else { + val = row[ix++]*256*8192/scaleForSave; + thumbImg->r[cinfo.output_scanline-1][j] = CLIP(val); + val = row[ix++]*256*8192/scaleForSave; + thumbImg->g[cinfo.output_scanline-1][j] = CLIP(val); + val = row[ix++]*256*8192/scaleForSave; + thumbImg->b[cinfo.output_scanline-1][j] = CLIP(val); + } + } + } + jpeg_finish_decompress (&cinfo); + jpeg_destroy_decompress (&cinfo); + fclose (f); + delete [] row; + return true; + } + else { + fclose (f); + return false; + } + return true; + } +} + +bool Thumbnail::readData (const Glib::ustring& fname) { + + SafeKeyFile keyFile; + + try { + if (!keyFile.load_from_file (fname)) + return false; + + if (keyFile.has_group ("LiveThumbData")) { + if (keyFile.has_key ("LiveThumbData", "CamWBRed")) camwbRed = keyFile.get_double ("LiveThumbData", "CamWBRed"); + if (keyFile.has_key ("LiveThumbData", "CamWBGreen")) camwbGreen = keyFile.get_double ("LiveThumbData", "CamWBGreen"); + if (keyFile.has_key ("LiveThumbData", "CamWBBlue")) camwbBlue = keyFile.get_double ("LiveThumbData", "CamWBBlue"); + if (keyFile.has_key ("LiveThumbData", "AutoWBTemp")) autowbTemp = keyFile.get_double ("LiveThumbData", "AutoWBTemp"); + if (keyFile.has_key ("LiveThumbData", "AutoWBGreen")) autowbGreen = keyFile.get_double ("LiveThumbData", "AutoWBGreen"); + if (keyFile.has_key ("LiveThumbData", "AEHistCompression")) aeHistCompression = keyFile.get_integer ("LiveThumbData", "AEHistCompression"); + if (keyFile.has_key ("LiveThumbData", "RedMultiplier")) redMultiplier = keyFile.get_double ("LiveThumbData", "RedMultiplier"); + if (keyFile.has_key ("LiveThumbData", "GreenMultiplier")) greenMultiplier = keyFile.get_double ("LiveThumbData", "GreenMultiplier"); + if (keyFile.has_key ("LiveThumbData", "BlueMultiplier")) blueMultiplier = keyFile.get_double ("LiveThumbData", "BlueMultiplier"); + if (keyFile.has_key ("LiveThumbData", "Scale")) scale = keyFile.get_double ("LiveThumbData", "Scale"); + if (keyFile.has_key ("LiveThumbData", "DefaultGain")) defGain = keyFile.get_double ("LiveThumbData", "DefaultGain"); + if (keyFile.has_key ("LiveThumbData", "ScaleForSave")) scaleForSave = keyFile.get_integer ("LiveThumbData", "ScaleForSave"); + if (keyFile.has_key ("LiveThumbData", "GammaCorrected")) gammaCorrected = keyFile.get_boolean ("LiveThumbData", "GammaCorrected"); + if (keyFile.has_key ("LiveThumbData", "ColorMatrix")) { + std::vector cm = keyFile.get_double_list ("LiveThumbData", "ColorMatrix"); + int ix = 0; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + colorMatrix[i][j] = cm[ix++]; + } + } + return true; + } + catch (Glib::Error) { + return false; + } +} + +bool Thumbnail::writeData (const Glib::ustring& fname) { + + SafeKeyFile keyFile; + + try { + keyFile.load_from_file (fname); + } catch (...) {} + + keyFile.set_double ("LiveThumbData", "CamWBRed", camwbRed); + keyFile.set_double ("LiveThumbData", "CamWBGreen", camwbGreen); + keyFile.set_double ("LiveThumbData", "CamWBBlue", camwbBlue); + keyFile.set_double ("LiveThumbData", "AutoWBTemp", autowbTemp); + keyFile.set_double ("LiveThumbData", "AutoWBGreen", autowbGreen); + keyFile.set_integer ("LiveThumbData", "AEHistCompression", aeHistCompression); + keyFile.set_double ("LiveThumbData", "RedMultiplier", redMultiplier); + keyFile.set_double ("LiveThumbData", "GreenMultiplier", greenMultiplier); + keyFile.set_double ("LiveThumbData", "BlueMultiplier", blueMultiplier); + keyFile.set_double ("LiveThumbData", "Scale", scale); + keyFile.set_double ("LiveThumbData", "DefaultGain", defGain); + keyFile.set_integer ("LiveThumbData", "ScaleForSave", scaleForSave); + keyFile.set_boolean ("LiveThumbData", "GammaCorrected", gammaCorrected); + Glib::ArrayHandle cm ((double*)colorMatrix, 9, Glib::OWNERSHIP_NONE); + keyFile.set_double_list ("LiveThumbData", "ColorMatrix", cm); + + FILE *f = g_fopen (fname.c_str(), "wt"); + if (!f) + return false; + else { + fprintf (f, "%s", keyFile.to_data().c_str()); + fclose (f); + return true; + } +} + +bool Thumbnail::readEmbProfile (const Glib::ustring& fname) { + + FILE* f = fopen (fname.c_str(), "rb"); + if (!f) { + embProfileData = NULL; + embProfile = NULL; + embProfileLength = 0; + } + else { + fseek (f, 0, SEEK_END); + embProfileLength = ftell (f); + fseek (f, 0, SEEK_SET); + embProfileData = new unsigned char[embProfileLength]; + fread (embProfileData, 1, embProfileLength, f); + fclose (f); + embProfile = cmsOpenProfileFromMem (embProfileData, embProfileLength); + return true; + } + return false; +} + +bool Thumbnail::writeEmbProfile (const Glib::ustring& fname) { + + if (embProfileLength) { + FILE* f = fopen (fname.c_str(), "wb"); + if (f) { + fwrite (embProfileData, 1, embProfileLength, f); + fclose (f); + return true; + } + } + return false; +} + +bool Thumbnail::readAEHistogram (const Glib::ustring& fname) { + + FILE* f = fopen (fname.c_str(), "rb"); + if (!f) + aeHistogram = NULL; + else { + aeHistogram = new unsigned int[65536>>aeHistCompression]; + fread (aeHistogram, 1, (65536>>aeHistCompression)*sizeof(int), f); + fclose (f); + return true; + } + return false; +} + +bool Thumbnail::writeAEHistogram (const Glib::ustring& fname) { + + if (aeHistogram) { + FILE* f = fopen (fname.c_str(), "wb"); + if (f) { + fwrite (aeHistogram, 1, (65536>>aeHistCompression)*sizeof(int), f); + fclose (f); + return true; + } + } + return false; +} + +} diff --git a/rtengine/rtthumbnail.h b/rtengine/rtthumbnail.h new file mode 100644 index 000000000..f45e4c691 --- /dev/null +++ b/rtengine/rtthumbnail.h @@ -0,0 +1,99 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _THUMBPROCESSINGPARAMETERS_ +#define _THUMBPROCESSINGPARAMETERS_ + +#include +#include +#include +#include +#include + +namespace rtengine { + + class Thumbnail { + + cmsHPROFILE camProfile; + double iColorMatrix[3][3]; + double camToD50[3][3]; + + + void transformPixel (int x, int y, int tran, int& tx, int& ty); + + static bool igammacomputed; + static unsigned short igammatab[256]; + static unsigned char gammatab[65536]; + + Image16* thumbImg; + double camwbRed; + double camwbGreen; + double camwbBlue; + double autowbTemp; + double autowbGreen; + unsigned int* aeHistogram; + int aeHistCompression; + int embProfileLength; + unsigned char* embProfileData; + cmsHPROFILE embProfile; + double redMultiplier; + double greenMultiplier; + double blueMultiplier; + double scale; + double defGain; + int scaleForSave; + bool gammaCorrected; + double colorMatrix[3][3]; + + public: + + bool isRaw; + + ~Thumbnail (); + Thumbnail (); + + void init (); + + IImage8* processImage (const procparams::ProcParams& pparams, int rheight, TypeInterpolation interp, double& scale); + int getImageWidth (const procparams::ProcParams& pparams, int rheight); + void getFinalSize (const rtengine::procparams::ProcParams& pparams, int& w, int& h); + + static Thumbnail* loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, int &w, int &h, int fixwh); + static Thumbnail* loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh); + + void getCamWB (double& temp, double& green); + void getAutoWB (double& temp, double& green); + void getSpotWB (const procparams::ProcParams& params, int x, int y, int rect, double& temp, double& green); + void applyAutoExp (procparams::ProcParams& pparams); + + bool writeImage (const Glib::ustring& fname, int format); + bool readImage (const Glib::ustring& fname); + + bool readData (const Glib::ustring& fname); + bool writeData (const Glib::ustring& fname); + + bool readEmbProfile (const Glib::ustring& fname); + bool writeEmbProfile (const Glib::ustring& fname); + + bool readAEHistogram (const Glib::ustring& fname); + bool writeAEHistogram (const Glib::ustring& fname); + }; +} + +#endif + diff --git a/rtengine/safekeyfile.h b/rtengine/safekeyfile.h new file mode 100644 index 000000000..005c83a3f --- /dev/null +++ b/rtengine/safekeyfile.h @@ -0,0 +1,78 @@ +#ifndef SAFE_KEY_FILE_H_INCLUDED +#define SAFE_KEY_FILE_H_INCLUDED + +#include +namespace rtengine { + +class SafeKeyFile : public Glib::KeyFile +{ + public : + +#ifdef GLIBMM_EXCEPTIONS_ENABLED +#define SAFE_KEY_FILE_METHOD_CODE(method,method_err) \ + do { try { res = Glib::KeyFile::method; }catch (const Glib::KeyFileError& e) { } ; \ + return res; }while(0) +#else +#define SAFE_KEY_FILE_METHOD_CODE(method,method_err) \ + do { std::auto_ptr error; \ + res = Glib::KeyFile::method_err; \ + if (error.get()){/* TODO */}; \ + return res;} while(0) +#endif //GLIBMM_EXCEPTIONS_ENABLED +#define SAFE_KEY_FILE_METHOD(method,method_err,ret_type) \ + { ret_type res = (ret_type)0; SAFE_KEY_FILE_METHOD_CODE(method,method_err);} + +#define SAFE_KEY_FILE_METHOD_NOINIT(method,method_err,ret_type) \ + { ret_type res; SAFE_KEY_FILE_METHOD_CODE(method,method_err);} + + Glib::ustring to_data() + SAFE_KEY_FILE_METHOD_NOINIT(to_data(), to_data(error), Glib::ustring); + + bool load_from_data(const Glib::ustring& data, Glib::KeyFileFlags flags = Glib::KEY_FILE_NONE) + SAFE_KEY_FILE_METHOD(load_from_data(data,flags), load_from_data(data,flags,error), bool); + + bool load_from_file(const std::string& filename, Glib::KeyFileFlags flags = Glib::KEY_FILE_NONE) + SAFE_KEY_FILE_METHOD(load_from_file(filename,flags), load_from_file(filename,flags,error), bool); + + bool has_key(const Glib::ustring& group_name, const Glib::ustring& key) const + SAFE_KEY_FILE_METHOD(has_key(group_name,key), has_key(group_name,key,error), bool); + + bool get_boolean(const Glib::ustring& group_name, const Glib::ustring& key) const + SAFE_KEY_FILE_METHOD(get_boolean(group_name,key), get_boolean(group_name,key,error), bool); + + int get_integer(const Glib::ustring& group_name, const Glib::ustring& key) const + SAFE_KEY_FILE_METHOD(get_integer(group_name,key), get_integer(group_name,key,error), int); + + double get_double(const Glib::ustring& group_name, const Glib::ustring& key) const + SAFE_KEY_FILE_METHOD(get_double(group_name,key), get_double(group_name,key,error), double); + + typedef std::vector DoubleArrayType; + + DoubleArrayType get_double_list(const Glib::ustring& group_name, const Glib::ustring& key) const + SAFE_KEY_FILE_METHOD_NOINIT(get_double_list(group_name,key), get_double_list(group_name,key,error), DoubleArrayType); + + typedef std::vector IntArrayType; + + IntArrayType get_integer_list(const Glib::ustring& group_name, const Glib::ustring& key) const + SAFE_KEY_FILE_METHOD_NOINIT(get_integer_list(group_name,key), get_integer_list(group_name,key,error), IntArrayType); + + Glib::ustring get_string(const Glib::ustring& group_name, const Glib::ustring& key) const + SAFE_KEY_FILE_METHOD_NOINIT(get_string(group_name,key), get_string(group_name,key,error), Glib::ustring); + + typedef std::vector StringArrayType; + + StringArrayType get_string_list(const Glib::ustring& group_name, const Glib::ustring& key) const + SAFE_KEY_FILE_METHOD_NOINIT(get_string_list(group_name,key), get_string_list(group_name,key,error), StringArrayType); + + StringArrayType get_keys(const Glib::ustring& group_name) const + SAFE_KEY_FILE_METHOD_NOINIT(get_keys(group_name), get_keys(group_name,error), StringArrayType); + +#undef SAFE_KEY_FILE_METHOD_CODE +#undef SAFE_KEY_FILE_METHOD +#undef SAFE_KEY_FILE_METHOD_NOINIT + +}; + +} + +#endif diff --git a/rtengine/settings.h b/rtengine/settings.h new file mode 100644 index 000000000..bfe53173e --- /dev/null +++ b/rtengine/settings.h @@ -0,0 +1,47 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _RTSETTINGS_ +#define _RTSETTINGS_ + +namespace rtengine { + + /** This structure holds the global parameters used by the RT engine. */ + class Settings { + public: + bool dualThreadEnabled; ///< If true, the image processing operations with utilize two processor cores (if possible) + std::string demosaicMethod; ///< The algorithm used for demosaicing. Can be "eahd", "hphd" or "vng4". + int colorCorrectionSteps; ///< The number of color correction steps applied right after the demosaicing + Glib::ustring iccDirectory; ///< The directory containing the possible output icc profiles + int colorimetricIntent; ///< Colorimetric intent used at color space conversions + Glib::ustring monitorProfile; ///< ICC profile of the monitor (full path recommended) + bool verbose; + int dcb_iterations; // number of dcb iterations + bool dcb_enhance; // whether to do image refinment + + /** Creates a new instance of Settings. + * @return a pointer to the new Settings instance. */ + static Settings* create (); + /** Destroys an instance of Settings. + * @param s a pointer to the Settings instance to destroy. */ + static void destroy (Settings* s); + }; +} + +#endif + diff --git a/rtengine/shmap.cc b/rtengine/shmap.cc new file mode 100644 index 000000000..f0e4579d4 --- /dev/null +++ b/rtengine/shmap.cc @@ -0,0 +1,135 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include + +#undef THREAD_PRIORITY_NORMAL +#define MAXVAL 0xffff +#define CLIP(a) ((a)>0?((a)r[i][j] + lumi[1]*img->g[i][j] + lumi[2]*img->b[i][j]; + map[i][j] = CLIP(val); + } + +//MyTime t1,t2; +//t1.set (); + + if (!hq) { + + AlignedBuffer* buffer1 = new AlignedBuffer (MAX(W,H)*5); + AlignedBuffer* buffer2 = new AlignedBuffer (MAX(W,H)*5); + + // blur + if (settings->dualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussHorizontal_unsigned), map, map, buffer1, W, 0, H/2, radius), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussHorizontal_unsigned), map, map, buffer2, W, H/2, H, radius), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + thread1 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussVertical_unsigned), map, map, buffer1, H, 0, W/2, radius), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread2 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(gaussVertical_unsigned), map, map, buffer2, H, W/2, W, radius), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else { + gaussHorizontal_unsigned (map, map, buffer1, W, 0, H, radius); + gaussVertical_unsigned (map, map, buffer1, H, 0, W, radius); + } + + delete buffer1; + delete buffer2; + } + else { + if (settings->dualThreadEnabled) { + bilateralparams r1, r2; + r1.row_from = 0; + r1.row_to = H/2; + r2.row_from = H/2; + r2.row_to = H; + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(bilateral_box_unsigned), map, buffer, W, H, 8000, radius, r1), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::ptr_fun(bilateral_box_unsigned), map, buffer, W, H, 8000, radius, r2), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else { + bilateralparams r1; + r1.row_from = 0; + r1.row_to = H; + bilateral_box_unsigned (map, buffer, W, H, 8000, radius, r1); + } + for (int i=0; i0 && j>0 && i max) + max = val; + _avg = 1.0/n * val + (1.0 - 1.0/n) * _avg; + n++; + } + avg = (int) _avg; +} + +void SHMap::forceStat (unsigned short max_, unsigned short min_, unsigned short avg_) { + + max = max_; + min = min_; + avg = avg_; +} } + diff --git a/rtengine/shmap.h b/rtengine/shmap.h new file mode 100644 index 000000000..1a7b6064e --- /dev/null +++ b/rtengine/shmap.h @@ -0,0 +1,40 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef __SHMAP__ +#define __SHMAP__ + +#include + +namespace rtengine { + +class SHMap { + + public: + int W, H; + unsigned short** map; + unsigned short max, min, avg; + + SHMap (int w, int h); + ~SHMap (); + + void update (Image16* img, unsigned short** buffer, double radius, double lumi[3], bool hq); + void forceStat (unsigned short max_, unsigned short min_, unsigned short avg_); +}; +}; +#endif diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc new file mode 100644 index 000000000..ab9dccb8f --- /dev/null +++ b/rtengine/simpleprocess.cc @@ -0,0 +1,232 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#undef THREAD_PRIORITY_NORMAL + +namespace rtengine { + +IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* pl) { + + errorCode = 0; + + ProcessingJobImpl* job = (ProcessingJobImpl*) pjob; + + if (pl) { + pl->setProgressStr ("Processing..."); + pl->setProgress (0.0); + } + + InitialImage* ii = job->initialImage; + if (!ii) { + ii = InitialImage::load (job->fname, job->isRaw, &errorCode); + if (errorCode) { + ii->decreaseRef (); + delete job; + return NULL; + } + } + procparams::ProcParams& params = job->pparams; + + // aquire image from imagesource + ImageSource* imgsrc = ii->getImageSource (); + ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green); + if (params.wb.method=="Camera") + currWB = imgsrc->getWB (); + else if (params.wb.method=="Auto") + currWB = imgsrc->getAutoWB (); + + int tr = TR_NONE; + if (params.coarse.rotate==90) tr |= TR_R90; + if (params.coarse.rotate==180) tr |= TR_R180; + if (params.coarse.rotate==270) tr |= TR_R270; + if (params.coarse.hflip) tr |= TR_HFLIP; + if (params.coarse.vflip) tr |= TR_VFLIP; + + int fw, fh; + imgsrc->getFullSize (fw, fh, tr); + + ImProcFunctions ipf; + + Image16* baseImg; + PreviewProps pp (0, 0, fw, fh, 1); + if (fabs(params.resize.scale-1.0)<1e-5) { + baseImg = new Image16 (fw, fh); + imgsrc->getImage (currWB, tr, baseImg, pp, params.hlrecovery, params.icm); + } + else { + Image16* oorig = new Image16 (fw, fh); + imgsrc->getImage (currWB, tr, oorig, pp, params.hlrecovery, params.icm); + fw *= params.resize.scale; + fh *= params.resize.scale; + baseImg = new Image16 (fw, fh); + ipf.resize (oorig, baseImg, params.resize); + delete oorig; + } + if (pl) + pl->setProgress (0.25); + + // perform first analysis + unsigned int* hist16 = new unsigned int[65536]; + ipf.firstAnalysis (baseImg, ¶ms, hist16, imgsrc->getGamma()); + + // perform transform + bool needstransform = fabs(params.rotate.degree)>1e-15 || fabs(params.distortion.amount)>1e-15 || fabs(params.cacorrection.red)>1e-15 || fabs(params.cacorrection.blue)>1e-15; + bool needsvignetting = params.vignetting.amount!=0; + + if (!needstransform && needsvignetting) { + Image16* trImg = new Image16 (fw, fh); + ipf.vignetting (baseImg, trImg, ¶ms, 0, 0, fw, fh); + delete baseImg; + baseImg = trImg; + } + else if (needstransform) { + Image16* trImg = new Image16 (fw, fh); + ipf.transform (baseImg, trImg, ¶ms, 0, 0, 0, 0, fw, fh); + delete baseImg; + baseImg = trImg; + } + + // update blurmap + int** buffer = new int*[fh]; + for (int i=0; iupdate (baseImg, (unsigned short**)buffer, shradius, ipf.lumimul, params.sh.hq); + } + // RGB processing +//!!!// auto exposure!!! + double br = params.toneCurve.expcomp; + int bl = params.toneCurve.black; + + if (params.toneCurve.autoexp) { + unsigned int aehist[65536]; int aehistcompr; + imgsrc->getAEHistogram (aehist, aehistcompr); + ipf.getAutoExp (aehist, aehistcompr, imgsrc->getDefGain(), params.toneCurve.clip, br, bl); + } + + int* curve = new int [65536]; + + CurveFactory::complexCurve (br, bl/65535.0, params.toneCurve.hlcompr, params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, imgsrc->getDefGain(), imgsrc->getGamma(), true, params.toneCurve.curve, hist16, curve, NULL); + + LabImage* labView = new LabImage (baseImg); + ipf.rgbProc (baseImg, labView, ¶ms, curve, shmap); + + if (shmap) + delete shmap; + + if (pl) + pl->setProgress (0.5); + + // luminance histogram update + memset (hist16, 0, 65536*sizeof(int)); + for (int i=0; iL[i][j]]++; + + // luminance processing + CurveFactory::complexCurve (0.0, 0.0, 0.0, 0.0, params.lumaCurve.brightness, params.lumaCurve.contrast, 0.0, 0.0, false, params.lumaCurve.curve, hist16, curve, NULL); + ipf.luminanceCurve (labView, labView, curve, 0, fh); + ipf.lumadenoise (labView, ¶ms, 1, buffer); + ipf.sharpening (labView, ¶ms, 1, (unsigned short**)buffer); + + delete [] curve; + delete [] hist16; + + // color processing + ipf.colorCurve (labView, labView, ¶ms); + ipf.colordenoise (labView, ¶ms, 1, buffer); + + for (int i=0; isetProgress (0.75); + + // obtain final image + Image16* readyImg; + int cx = 0, cy = 0, cw = labView->W, ch = labView->H; + if (params.crop.enabled) { + cx = params.crop.x; + cy = params.crop.y; + cw = params.crop.w; + ch = params.crop.h; + } + readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output); + ipf.release (); + + if (pl) + pl->setProgress (1.0); + + readyImg->setMetadata (ii->getMetaData()->getExifData (), params.exif, params.iptc); + + ProfileContent pc; + if (params.icm.output.compare (0, 6, "No ICM") && params.icm.output!="") + pc = iccStore.getContent (params.icm.output); + + readyImg->setOutputProfile (pc.data, pc.length); + + delete baseImg; + + if (!job->initialImage) + ii->decreaseRef (); + + delete job; + + if (pl) { + pl->setProgress (1.0); + pl->setProgressStr ("Ready."); + } + + return readyImg; +} + +void batchProcessingThread (ProcessingJob* job, BatchProcessingListener* bpl) { + + ProcessingJob* currentJob = job; + + while (currentJob) { + int errorCode; + IImage16* img = processImage (currentJob, errorCode, bpl); + if (errorCode) + bpl->error ("Can not load input image."); + currentJob = bpl->imageReady (img); + } +} + +void startBatchProcessing (ProcessingJob* job, BatchProcessingListener* bpl) { + + if (bpl) + Glib::Thread::create(sigc::bind(sigc::ptr_fun(batchProcessingThread), job, bpl), 0, false, true, Glib::THREAD_PRIORITY_NORMAL); +} + +} diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc new file mode 100644 index 000000000..5b25b6ec4 --- /dev/null +++ b/rtengine/stdimagesource.cc @@ -0,0 +1,546 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#define MAXVAL 0xffff +#define CLIP(a) ((a)>0?((a) + +#undef THREAD_PRIORITY_NORMAL + +namespace rtengine { + +extern const Settings* settings; + +template void freeArray (T** a, int H) { + for (int i=0; i T** allocArray (int W, int H) { + + T** t = new T*[H]; + for (int i=0; iheight/HR_SCALE; + freeArray(hrmap[0], dh); + freeArray(hrmap[1], dh); + freeArray(hrmap[2], dh); + } + + delete img; + + if (needhr) + freeArray(needhr, img->height); +} + +int StdImageSource::load (Glib::ustring fname) { + + fileName = fname; + + img = new Image16 (); + if (plistener) { + plistener->setProgressStr ("Loading..."); + plistener->setProgress (0.0); + img->setProgressListener (plistener); + } + + int error = img->load (fname); + if (error) { + delete img; + img = NULL; + return error; + } + + embProfile = img->getEmbeddedProfile (); + idata = new ImageData (fname); + + if (plistener) { + plistener->setProgressStr ("Ready."); + plistener->setProgress (1.0); + } + + wb = ColorTemp (1.0, 1.0, 1.0); + + return 0; +} + +void StdImageSource::transform (PreviewProps pp, int tran, int &sx1, int &sy1, int &sx2, int &sy2) { + + int W = img->width; + int H = img->height; + int sw = W, sh = H; + if ((tran & TR_ROT) == TR_R90 || (tran & TR_ROT) == TR_R270) { + sw = H; + sh = W; + } + int ppx = pp.x, ppy = pp.y; + if (tran & TR_HFLIP) + ppx = sw - pp.x - pp.w; + if (tran & TR_VFLIP) + ppy = sh - pp.y - pp.h; + + sx1 = ppx; + sy1 = ppy; + sx2 = ppx + pp.w; + sy2 = ppy + pp.h; + + if ((tran & TR_ROT) == TR_R180) { + sx1 = W - ppx - pp.w; + sy1 = H - ppy - pp.h; + sx2 = sx1 + pp.w; + sy2 = sy1 + pp.h; + } + else if ((tran & TR_ROT) == TR_R90) { + sx1 = ppy; + sy1 = H - ppx - pp.w; + sx2 = sx1 + pp.h; + sy2 = sy1 + pp.w; + } + else if ((tran & TR_ROT) == TR_R270) { + sx1 = W - ppy - pp.h; + sy1 = ppx; + sx2 = sx1 + pp.h; + sy2 = sy1 + pp.w; + } + printf ("ppx %d ppy %d ppw %d pph %d s: %d %d %d %d\n",pp.x, pp.y,pp.w,pp.h,sx1,sy1,sx2,sy2); +} + +void StdImageSource::getImage_ (ColorTemp ctemp, int tran, Image16* image, PreviewProps pp, bool first, HRecParams hrp) { + + // compute channel multipliers + double rm, gm, bm; + ctemp.getMultipliers (rm, gm, bm); + rm = 1.0 / rm; + gm = 1.0 / gm; + bm = 1.0 / bm; + double mul_lum = 0.299*rm + 0.587*gm + 0.114*bm; + rm /= mul_lum; + gm /= mul_lum; + bm /= mul_lum; + + int sx1, sy1, sx2, sy2; + transform (pp, tran, sx1, sy1, sx2, sy2); + + int imwidth = (sx2 - sx1) / pp.skip + ((sx2 - sx1) % pp.skip > 0); + int imheight = (sy2 - sy1) / pp.skip + ((sy2 - sy1) % pp.skip > 0); + + int istart = sy1, iend = sy2, ix = 0; + if (first) { + iend = istart; + while (iend<(sy1+sy2)/2) { + iend+=pp.skip; + } + } + else { + while (istart<(sy1+sy2)/2) { + ix++; + istart+=pp.skip; + } + } + + int mtran = tran; + int skip = pp.skip; + + unsigned short* red = new unsigned short[imwidth]; + unsigned short* grn = new unsigned short[imwidth]; + unsigned short* blue = new unsigned short[imwidth]; + + for (int i=istart; ir[i][jx]; + grn[j] = img->g[i][jx]; + blue[j] = img->b[i][jx]; + } +// if (hrp.enabled) +// hlRecovery (red, grn, blue, i, sx1, sx2, pp.skip); + + if ((mtran & TR_ROT) == TR_R180) + for (int j=0; jr[imheight-1-ix][imwidth-1-j] = (int)CLIP(rm*red[j]); + image->g[imheight-1-ix][imwidth-1-j] = (int)CLIP(gm*grn[j]); + image->b[imheight-1-ix][imwidth-1-j] = (int)CLIP(bm*blue[j]); + } + else if ((mtran & TR_ROT) == TR_R90) + for (int j=0,jx=sx1; jr[j][imheight-1-ix] = (int)CLIP(rm*red[j]); + image->g[j][imheight-1-ix] = (int)CLIP(gm*grn[j]); + image->b[j][imheight-1-ix] = (int)CLIP(bm*blue[j]); + } + else if ((mtran & TR_ROT) == TR_R270) + for (int j=0,jx=sx1; jr[imwidth-1-j][ix] = (int)CLIP(rm*red[j]); + image->g[imwidth-1-j][ix] = (int)CLIP(gm*grn[j]); + image->b[imwidth-1-j][ix] = (int)CLIP(bm*blue[j]); + } + else { + for (int j=0,jx=sx1; jr[ix][j] = (int)CLIP(rm*red[j]); + image->g[ix][j] = (int)CLIP(gm*grn[j]); + image->b[ix][j] = (int)CLIP(bm*blue[j]); + } + } + } + + delete [] red; + delete [] grn; + delete [] blue; +} + +void StdImageSource::getImage (ColorTemp ctemp, int tran, Image16* image, PreviewProps pp, HRecParams hrp, ColorManagementParams cmp) { + + MyTime t1,t2; + + t1.set (); + +// if (hrp.enabled==true && hrmap[0]==NULL) +// updateHLRecoveryMap (); + if (settings->dualThreadEnabled) { + Glib::Thread *thread1 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &StdImageSource::getImage_), ctemp, tran, image, pp, true, hrp), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + Glib::Thread *thread2 = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &StdImageSource::getImage_), ctemp, tran, image, pp, false, hrp), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + thread1->join (); + thread2->join (); + } + else { + getImage_ (ctemp, tran, image, pp, true, hrp); + getImage_ (ctemp, tran, image, pp, false, hrp); + } + + colorSpaceConversion (image, cmp, embProfile); + + // Flip if needed + if (tran & TR_HFLIP) + hflip (image); + if (tran & TR_VFLIP) + vflip (image); + + t2.set (); +} + +void StdImageSource::colorSpaceConversion (Image16* im, ColorManagementParams cmp, cmsHPROFILE embedded) { + + cmsHPROFILE in; + cmsHPROFILE out = iccStore.workingSpace (cmp.working); + if (cmp.input=="(embedded)" || cmp.input=="" || cmp.input=="(camera)") { + if (embedded) + in = embedded; + else + in = iccStore.getsRGBProfile (); + } + else if (cmp.input!="(none)") { + in = iccStore.getProfile (cmp.input); + if (in==NULL && embedded) + in = embedded; + else if (in==NULL) + in = iccStore.getsRGBProfile (); + else if (cmp.gammaOnInput) + for (int i=0; iheight; i++) + for (int j=0; jwidth; j++) { + im->r[i][j] = CurveFactory::gamma (im->r[i][j]); + im->g[i][j] = CurveFactory::gamma (im->g[i][j]); + im->b[i][j] = CurveFactory::gamma (im->b[i][j]); + } + } + + if (cmp.input!="(none)") { + lcmsMutex->lock (); + cmsHTRANSFORM hTransform = cmsCreateTransform (in, TYPE_RGB_16_PLANAR, out, TYPE_RGB_16_PLANAR, settings->colorimetricIntent, 0); + lcmsMutex->unlock (); + cmsDoTransform (hTransform, im->data, im->data, im->planestride/2); + cmsDeleteTransform(hTransform); + } +} + +void StdImageSource::getFullSize (int& w, int& h, int tr) { + + w = img->width; + h = img->height; + if ((tr & TR_ROT) == TR_R90 || (tr & TR_ROT) == TR_R270) { + w = img->height; + h = img->width; + } +} + +void StdImageSource::getSize (int tran, PreviewProps pp, int& w, int& h) { + + w = pp.w / pp.skip + (pp.w % pp.skip > 0); + h = pp.h / pp.skip + (pp.h % pp.skip > 0); +} + +void StdImageSource::hflip (Image16* image) { + int width = image->width; + int height = image->height; + + unsigned short* rowr = new unsigned short[width]; + unsigned short* rowg = new unsigned short[width]; + unsigned short* rowb = new unsigned short[width]; + for (int i=0; ir[i][width-1-j]; + rowg[j] = image->g[i][width-1-j]; + rowb[j] = image->b[i][width-1-j]; + } + memcpy (image->r[i], rowr, width*sizeof(unsigned short)); + memcpy (image->g[i], rowg, width*sizeof(unsigned short)); + memcpy (image->b[i], rowb, width*sizeof(unsigned short)); + } + delete [] rowr; + delete [] rowg; + delete [] rowb; +} + +void StdImageSource::vflip (Image16* image) { + int width = image->width; + int height = image->height; + + register unsigned short tmp; + for (int i=0; ir[i][j]; + image->r[i][j] = image->r[height-1-i][j]; + image->r[height-1-i][j] = tmp; + tmp = image->g[i][j]; + image->g[i][j] = image->g[height-1-i][j]; + image->g[height-1-i][j] = tmp; + tmp = image->b[i][j]; + image->b[i][j] = image->b[height-1-i][j]; + image->b[height-1-i][j] = tmp; + } +} +/* +void hlRecovery (unsigned short* red, unsigned short* green, unsigned short* blue, int H, int W, int i, int sx1, int sx2, int skip, char** needhr, float** hrmap[3]); +void hlmultipliers (int** rec[3], int max[3], int dh, int dw); + +void StdImageSource::updateHLRecoveryMap () { + + // detect maximal pixel values + int maxr = 0, maxg = 0, maxb = 0; + for (int i=32; iheight-32; i++) + for (int j=32; jwidth-32; j++) { + if (img->r[i][j] > maxr) maxr = img->r[i][j]; + if (img->g[i][j] > maxg) maxg = img->g[i][j]; + if (img->b[i][j] > maxb) maxb = img->b[i][j]; + } + + maxr = maxr * 19 / 20; + maxg = maxg * 19 / 20; + maxb = maxb * 19 / 20; + max[0] = maxr; + max[1] = maxg; + max[2] = maxb; + + // downscale image + int dw = img->width/HR_SCALE; + int dh = img->height/HR_SCALE; + Image16* ds = new Image16 (dw, dh); + + // overburnt areas + int** rec[3]; + for (int i=0; i<3; i++) + rec[i] = allocArray (dw, dh); + + if (needhr) + freeArray(needhr, img->height); + needhr = allocArray (img->width, img->height); + + for (int i=0; iheight; i++) + for (int j=0; jwidth; j++) + if (img->r[i][j]>=max[0] || img->g[i][j]>=max[1] || img->b[i][j]>=max[2]) + needhr[i][j] = 1; + else + needhr[i][j] = 0; + + + for (int i=0; iheight; i++) + for (int j=0; jwidth; j++) { + int sumr = 0; int cr = 0; + int sumg = 0; int cg = 0; + int sumb = 0; int cb = 0; + for (int x=0; xr[ix][jy]; + if (img->r[ix][jy] < maxr) cr++; + sumg += img->g[ix][jy]; + if (img->g[ix][jy] < maxg) cg++; + sumb += img->b[ix][jy]; + if (img->b[ix][jy] < maxb) cb++; + } + if (crr[i][j] = sumr / HR_SCALE/HR_SCALE; + ds->g[i][j] = sumg / HR_SCALE/HR_SCALE; + ds->b[i][j] = sumb / HR_SCALE/HR_SCALE; + + } + + hlmultipliers (rec, max, dh, dw); + + if (hrmap[0]!=NULL) { + freeArray (hrmap[0], dh); + freeArray (hrmap[1], dh); + freeArray (hrmap[2], dh); + } + + hrmap[0] = allocArray (dw, dh); + hrmap[1] = allocArray (dw, dh); + hrmap[2] = allocArray (dw, dh); + + for (int i=0; ir[i][j]>0 ? (double)rec[0][i][j] / ds->r[i][j] : 1.0; + hrmap[1][i][j] = ds->g[i][j]>0 ? (double)rec[1][i][j] / ds->g[i][j] : 1.0; + hrmap[2][i][j] = ds->b[i][j]>0 ? (double)rec[2][i][j] / ds->b[i][j] : 1.0; + } + + delete ds; + + freeArray (rec[0], dh); + freeArray (rec[1], dh); + freeArray (rec[2], dh); +} + +void StdImageSource::hlRecovery (unsigned short* red, unsigned short* green, unsigned short* blue, int i, int sx1, int sx2, int skip) { + + rtengine::hlRecovery (red, green, blue, img->height, img->width, i, sx1, sx2, skip, needhr, hrmap); +} +*/ +int StdImageSource::getAEHistogram (unsigned int* histogram, int& histcompr) { + + histcompr = 3; + + memset (histogram, 0, (65536>>histcompr)*sizeof(int)); + + for (int i=0; iheight; i++) + for (int j=0; jwidth; j++) { + histogram[CurveFactory::igamma_srgb (img->r[i][j])>>histcompr]++; + histogram[CurveFactory::igamma_srgb (img->g[i][j])>>histcompr]++; + histogram[CurveFactory::igamma_srgb (img->b[i][j])>>histcompr]++; + } + return 1; +} + +ColorTemp StdImageSource::getAutoWB () { + + double avg_r = 0; + double avg_g = 0; + double avg_b = 0; + int n = 0; + int p = 6; + + for (int i=1; iheight-1; i++) + for (int j=1; jwidth-1; j++) { + if (img->r[i][j]>64000 || img->g[i][j]>64000 || img->b[i][j]>64000) + continue; + avg_r += intpow((double)img->r[i][j], p); + avg_g += intpow((double)img->g[i][j], p); + avg_b += intpow((double)img->b[i][j], p); + n++; + } + return ColorTemp (pow(avg_r/n, 1.0/p), pow(avg_g/n, 1.0/p), pow(avg_b/n, 1.0/p)); +} + +void StdImageSource::transformPixel (int x, int y, int tran, int& tx, int& ty) { + + int W = img->width; + int H = img->height; + int sw = W, sh = H; + if ((tran & TR_ROT) == TR_R90 || (tran & TR_ROT) == TR_R270) { + sw = H; + sh = W; + } + + int ppx = x, ppy = y; + if (tran & TR_HFLIP) + ppx = sw - 1 - x ; + if (tran & TR_VFLIP) + ppy = sh - 1 - y; + + tx = ppx; + ty = ppy; + + if ((tran & TR_ROT) == TR_R180) { + tx = W - 1 - ppx; + ty = H - 1 - ppy; + } + else if ((tran & TR_ROT) == TR_R90) { + tx = ppy; + ty = H - 1 - ppx; + } + else if ((tran & TR_ROT) == TR_R270) { + tx = W - 1 - ppy; + ty = ppx; + } +} + +ColorTemp StdImageSource::getSpotWB (std::vector red, std::vector green, std::vector& blue, int tran) { + + int x; int y; + double reds = 0, greens = 0, blues = 0; + int rn = 0, gn = 0, bn = 0; + for (int i=0; i=0 && y>=0 && xwidth && yheight) { + reds += img->r[y][x]; +// img->r[y][x]=0; // debug!!! + rn++; + } + transformPixel (green[i].x, green[i].y, tran, x, y); + if (x>=0 && y>=0 && xwidth && yheight) { + greens += img->g[y][x]; +// img->g[y][x]=0; // debug!!! + gn++; + } + transformPixel (blue[i].x, blue[i].y, tran, x, y); + if (x>=0 && y>=0 && xwidth && yheight) { + blues += img->b[y][x]; +// img->b[y][x]=0; // debug!!! + bn++; + } + } + double img_r, img_g, img_b; + wb.getMultipliers (img_r, img_g, img_b); + printf ("AVG: %g %g %g\n", reds/rn, greens/gn, blues/bn); + + return ColorTemp (reds/rn*img_r, greens/gn*img_g, blues/bn*img_b); +} +} + diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h new file mode 100644 index 000000000..ef0c626f5 --- /dev/null +++ b/rtengine/stdimagesource.h @@ -0,0 +1,73 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _STDIMAGESOURCE_ +#define _STDIMAGESOURCE_ + +#include + +namespace rtengine { + +class StdImageSource : public ImageSource { + + protected: + Image16* img; + ColorTemp wb; + ProgressListener* plistener; + bool full; + float** hrmap[3]; + char** needhr; + int max[3]; + + void updateHLRecoveryMap (); + void hlRecovery (unsigned short* red, unsigned short* green, unsigned short* blue, int i, int sx1, int sx2, int skip); + void transform (PreviewProps pp, int tran, int &sx1, int &sy1, int &sx2, int &sy2); + void transformPixel (int x, int y, int tran, int& tx, int& ty); + + public: + StdImageSource (); + ~StdImageSource (); + + int load (Glib::ustring fname); + void getImage (ColorTemp ctemp, int tran, Image16* image, PreviewProps pp, HRecParams hrp, ColorManagementParams cmp); + ColorTemp getWB () { return wb; } + ColorTemp getAutoWB (); + ColorTemp getSpotWB (std::vector red, std::vector green, std::vector& blue, int tran); + + int getAEHistogram (unsigned int* histogram, int& histcompr); + + double getDefGain () { return 0.0; } + double getGamma () { return 0.0; } + + void getFullSize (int& w, int& h, int tr = TR_NONE); + void getSize (int tran, PreviewProps pp, int& w, int& h); + + ImageData* getImageData () { return idata; } + void setProgressListener (ProgressListener* pl) { plistener = pl; } + static void colorSpaceConversion (Image16* im, ColorManagementParams cmp, cmsHPROFILE embedded); + + + static inline double intpow (double a, int b) { double r = 1.0; for (int i=0; i + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +Updater::Updater () : + change (0), + ipc (NULL), + pl (NULL), + running (false) +{ +} + +ProcParams* Updater::changing (int what) { + + mutex.lock (); + change |= what; + return ¶ms; +} + +void Updater::changed () { + + mutex.unlock (); + startProcessing (); +} + +void Updater::clearState () { + + mutex.lock (); + change = 0; + mutex.unlock (); +} + +ProcParams* Updater::getParams () { + + return ¶ms; +} + +void Updater::startProcessing () { + + #undef THREAD_PRIORITY_NORMAL + + tstart.lock (); + if (ipc && !running) { + running = true; + tstart.unlock (); + Glib::Thread::create(sigc::mem_fun(*this, &Updater::process), 0, false, true, Glib::THREAD_PRIORITY_NORMAL); + } + else + tstart.unlock (); +} + +void Updater::process () { + + processing.lock (); + if (pl) + pl->setProcessingState (true); + + int ch; + + mutex.lock (); + while (change && ipc) { + ipc->params.copy (¶ms); + ch = change; + change = 0; + mutex.unlock (); + if (ch<=16384) + ipc->update (ch); + mutex.lock (); + } + mutex.unlock (); + tstart.lock (); + running = false; + tstart.unlock (); + + if (pl) + pl->setProcessingState (false); + processing.unlock (); +} + +void Updater::stop () { + + if (running) { + change = 0; + processing.lock (); + processing.unlock (); + + } +} + diff --git a/rtengine/updater.h b/rtengine/updater.h new file mode 100644 index 000000000..550e73f5f --- /dev/null +++ b/rtengine/updater.h @@ -0,0 +1,57 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _UPDATER_ +#define _UPDATER_ + +#include +#include +#include +#include + +class Updater { + + protected: + int change; + ProcParams params; + Glib::Mutex mutex; + Glib::Mutex tstart; + Glib::Mutex processing; + ImProcCoordinator* ipc; + ProgressListener* pl; + bool running; + + public: + + Updater (); + void setProgressListener (ProgressListener* l) { pl = l; } + void setIPC (ImProcCoordinator* ipc) { this->ipc = ipc; } + + ProcParams* changing (int what); + void changed (); + void clearState (); + int getClear (); + ProcParams* getParams (); + int getChange (); + void startProcessing (); + void process (); + + void stop (); +}; + +#endif diff --git a/rtengine/utils.cc b/rtengine/utils.cc new file mode 100644 index 000000000..cefd38bec --- /dev/null +++ b/rtengine/utils.cc @@ -0,0 +1,144 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +namespace rtengine { + +void bilinearInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh) { + + int ix = 0; + for (int i=0; i=sh) sy = sh-1; + double dy = (double)i*sh/dh - sy; + int ny = sy+1; + if (ny>=sh) ny = sy; + int or1 = 3*sw*sy; + int or2 = 3*sw*ny; + for (int j=0; j=sw) sx = sw; + double dx = (double)j*sw/dw - sx; + int nx = sx+1; + if (nx>=sw) nx = sx; + int ofs11 = or1 + 3*sx; + int ofs12 = or1 + 3*nx; + int ofs21 = or2 + 3*sx; + int ofs22 = or2 + 3*nx; + unsigned int val = src[ofs11]*(1-dx)*(1-dy) + src[ofs12]*dx*(1-dy) + src[ofs21]*(1-dx)*dy + src[ofs22]*dx*dy; + dst[ix++] = val; + ofs11++; ofs12++; ofs21++; ofs22++; + val = src[ofs11]*(1-dx)*(1-dy) + src[ofs12]*dx*(1-dy) + src[ofs21]*(1-dx)*dy + src[ofs22]*dx*dy; + dst[ix++] = val; + ofs11++; ofs12++; ofs21++; ofs22++; + val = src[ofs11]*(1-dx)*(1-dy) + src[ofs12]*dx*(1-dy) + src[ofs21]*(1-dx)*dy + src[ofs22]*dx*dy; + dst[ix++] = val; + } + } +} + +void nearestInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh) { + + int ix = 0; + for (int i=0; i + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _SIMPLEUTILS_ +#define _SIMPLEUTILS_ + +namespace rtengine { + +void bilinearInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh); +void nearestInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh); +void rotate (unsigned char* img, int& w, int& h, int deg); +void hflip (unsigned char* img, int w, int h); +void vflip (unsigned char* img, int w, int h); + +} +#endif diff --git a/rtexif/CMakeLists.txt b/rtexif/CMakeLists.txt new file mode 100644 index 000000000..17a6c18c8 --- /dev/null +++ b/rtexif/CMakeLists.txt @@ -0,0 +1,13 @@ +include_directories (.) +add_library (rtexif rtexif.cc stdattribs.cc nikonattribs.cc canonattribs.cc + pentaxattribs.cc fujiattribs.cc sonyminoltaattribs.cc olympusattribs.cc) + +IF (WIN32) + set_target_properties (rtexif PROPERTIES COMPILE_FLAGS "-O3 -ffast-math -fexpensive-optimizations") +ELSE (WIN32) + set_target_properties (rtexif PROPERTIES COMPILE_FLAGS "-O3 -ffast-math -fexpensive-optimizations -fPIC") +ENDIF (WIN32) + +IF (BUILD_SHARED_LIBS) + INSTALL(TARGETS rtexif DESTINATION ${LIBDIR}) +ENDIF (BUILD_SHARED_LIBS) diff --git a/rtexif/canonattribs.cc b/rtexif/canonattribs.cc new file mode 100644 index 000000000..cd2eed60d --- /dev/null +++ b/rtexif/canonattribs.cc @@ -0,0 +1,859 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _CANONATTRIBS_ +#define _CANONATTRIBS_ + +#include +#include +#include +#include +#include +#include + +namespace rtexif { + +class CAIntSerNumInterpreter : public Interpreter { + public: + CAIntSerNumInterpreter () {} + virtual std::string toString (Tag* t) { return ""; } +}; + +CAIntSerNumInterpreter caIntSerNumInterpreter; + +class CAFocalLengthInterpreter : public Interpreter { + public: + CAFocalLengthInterpreter () {} + virtual std::string toString (Tag* t) { + std::ostringstream str; + str << "FocalType = " << t->toInt(0,SHORT) << std::endl; + str << "FocalLength = " << t->toInt(2,SHORT) << std::endl; + str << "FocalPlaneXSize = " << t->toInt(4,SHORT) << std::endl; + str << "FocalPlaneYSize = " << t->toInt(6,SHORT); + return str.str(); + } +}; +CAFocalLengthInterpreter caFocalLengthInterpreter; + + +class CACameraSettingsInterpreter : public Interpreter { + std::map machoices; + std::map qlchoices; + std::map fmchoices; + std::map cdchoices; + std::map fochoices; + std::map rmchoices; + std::map ischoices; + std::map mmchoices; + std::map dzchoices; + std::map emchoices; + std::map frchoices; + std::map afchoices; + std::map exchoices; + std::map fcchoices; + std::map aechoices; + std::map stchoices; + std::map smchoices; + std::map pechoices; + std::map mfchoices; + std::map choices; + public: + CACameraSettingsInterpreter () { + machoices[1] = "Macro"; + machoices[2] = "Normal"; + qlchoices[1] = "Economy"; + qlchoices[2] = "Normal"; + qlchoices[3] = "Fine"; + qlchoices[4] = "RAW"; + qlchoices[5] = "Superfine"; + fmchoices[0] = "Off"; + fmchoices[1] = "Auto"; + fmchoices[2] = "On"; + fmchoices[3] = "Red-eye reduction"; + fmchoices[4] = "Slow-sync"; + fmchoices[5] = "Red-eye reduction (Auto)"; + fmchoices[6] = "Red-eye reduction (On)"; + fmchoices[16] = "External flash"; + cdchoices[0] = "Single"; + cdchoices[1] = "Continuous"; + cdchoices[2] = "Movie"; + cdchoices[3] = "Continuous, Speed Priority"; + cdchoices[4] = "Continuous, Low"; + cdchoices[5] = "Continuous, High"; + fochoices[0] = "One-shot AF"; + fochoices[1] = "AI Servo AF"; + fochoices[2] = "AI Focus AF"; + fochoices[3] = "Manual Focus"; + fochoices[4] = "Single"; + fochoices[5] = "Continuous"; + fochoices[6] = "Manual Focus"; + fochoices[16] = "Pan Focus"; + rmchoices[1] = "JPEG"; + rmchoices[2] = "CRW+THM"; + rmchoices[3] = "AVI+THM"; + rmchoices[4] = "TIF"; + rmchoices[5] = "TIF+JPEG"; + rmchoices[6] = "CR2"; + rmchoices[7] = "CR2+JPEG"; + ischoices[0] = "Large"; + ischoices[1] = "Medium"; + ischoices[2] = "Small"; + ischoices[5] = "Medium 1"; + ischoices[6] = "Medium 2"; + ischoices[7] = "Medium 3"; + ischoices[8] = "Postcard"; + ischoices[9] = "Widescreen"; + emchoices[0] = "Full auto "; + emchoices[1] = "Manual "; + emchoices[2] = "Landscape "; + emchoices[3] = "Fast shutter "; + emchoices[4] = "Slow shutter "; + emchoices[5] = "Night "; + emchoices[6] = "Gray Scale "; + emchoices[7] = "Sepia "; + emchoices[8] = "Portrait "; + emchoices[9] = "Sports "; + emchoices[10] = "Macro "; + emchoices[11] = "Black & White"; + emchoices[12] = "Pan focus"; + emchoices[13] = "Vivid"; + emchoices[14] = "Neutral"; + emchoices[15] = "Flash Off"; + emchoices[16] = "Long Shutter"; + emchoices[17] = "Super Macro"; + emchoices[18] = "Foliage"; + emchoices[19] = "Indoor"; + emchoices[20] = "Fireworks"; + emchoices[21] = "Beach"; + emchoices[22] = "Underwater"; + emchoices[23] = "Snow"; + emchoices[24] = "Kids & Pets"; + emchoices[25] = "Night Snapshot"; + emchoices[26] = "Digital Macro"; + emchoices[27] = "My Colors"; + emchoices[28] = "Still Image"; + emchoices[30] = "Color Accent"; + emchoices[31] = "Color Swap"; + emchoices[32] = "Aquarium"; + emchoices[33] = "ISO 3200"; + dzchoices[0] = "None"; + dzchoices[1] = "2x"; + dzchoices[2] = "4x"; + dzchoices[3] = "Other"; + mmchoices[0] = "Default"; + mmchoices[1] = "Spot"; + mmchoices[2] = "Average"; + mmchoices[3] = "Evaluative"; + mmchoices[4] = "Partial"; + mmchoices[5] = "Center-weighted averaging"; + frchoices[0] = "Manual"; + frchoices[1] = "Auto"; + frchoices[2] = "Not Known"; + frchoices[3] = "Macro"; + frchoices[4] = "Very Close"; + frchoices[5] = "Close"; + frchoices[6] = "Middle Range"; + frchoices[7] = "Far Range"; + frchoices[8] = "Pan Focus"; + frchoices[9] = "Super Macro"; + frchoices[10] = "Infinity"; + afchoices[0x2005] = "Manual AF point selection "; + afchoices[0x3000] = "None (MF)"; + afchoices[0x3001] = "Auto AF point selection "; + afchoices[0x3002] = "Right "; + afchoices[0x3003] = "Center "; + afchoices[0x3004] = "Left "; + afchoices[0x4001] = "Auto AF point selection "; + afchoices[0x4006] = "Face Detect"; + exchoices[0] = "Easy"; + exchoices[1] = "Program AE"; + exchoices[2] = "Shutter speed priority AE"; + exchoices[3] = "Aperture-priority AE"; + exchoices[4] = "Manual"; + exchoices[5] = "Depth-of-field AE"; + exchoices[6] = "M-Dep"; + fcchoices[0] = "Single"; + fcchoices[1] = "Continuous"; + aechoices[0] = "Normal AE"; + aechoices[1] = "Exposure Compensation"; + aechoices[2] = "AE Lock"; + aechoices[3] = "AE Lock + Exposure Comp."; + aechoices[4] = "No AE"; + stchoices[0] = "Off"; + stchoices[1] = "On"; + stchoices[2] = "On, Shot Only"; + stchoices[3] = "On, Panning"; + smchoices[0] = "Center"; + smchoices[1] = "AF Point"; + pechoices[0] = "Off"; + pechoices[1] = "Vivid"; + pechoices[2] = "Neutral"; + pechoices[3] = "Smooth"; + pechoices[4] = "Sepia"; + pechoices[5] = "B&W"; + pechoices[6] = "Custom"; + pechoices[100] = "My Color Data"; + mfchoices[0] = "N/A"; + mfchoices[0x500] = "Full"; + mfchoices[0x502] = "Medium"; + mfchoices[0x504] = "Low"; + mfchoices[0x7fff] = "N/A"; + choices[1] = "Canon EF 50mm f/1.8"; + choices[2] = "Canon EF 28mm f/2.8"; + choices[3] = "Canon EF 135mm f/2.8 Soft"; + choices[4] = "Canon EF 35-105mm f/3.5-4.5 or Sigma Lens"; + choices[5] = "Canon EF 35-70mm f/3.5-4.5"; + choices[6] = "Canon EF 28-70mm f/3.5-4.5 or Sigma or Tokina Lens"; + choices[7] = "Canon EF 100-300mm F5.6L"; + choices[8] = "Canon EF 100-300mm f/5.6 or Sigma or Tokina Lens"; + choices[9] = "Canon EF 70-210mm f/4 orSigma Lens"; + choices[10] = "Canon EF 50mm f/2.5 Macro or Sigma Lens"; + choices[11] = "Canon EF 35mm f/2"; + choices[13] = "Canon EF 15mm f/2.8"; + choices[14] = "Canon EF 50-200mm f/3.5-4.5L"; + choices[15] = "Canon EF 50-200mm f/3.5-4.5"; + choices[16] = "Canon EF 35-135mm f/3.5-4.5"; + choices[17] = "Canon EF 35-70mm f/3.5-4.5A"; + choices[18] = "Canon EF 28-70mm f/3.5-4.5"; + choices[20] = "Canon EF 100-200mm f/4.5A"; + choices[21] = "Canon EF 80-200mm f/2.8L"; + choices[22] = "Canon EF 20-35mm f/2.8L or Tokina 28-80mm F2.8"; + choices[23] = "Canon EF 35-105mm f/3.5-4.5"; + choices[24] = "Canon EF 35-80mm f/4-5.6 Power Zoom"; + choices[25] = "Canon EF 35-80mm f/4-5.6 Power Zoom"; + choices[26] = "Canon EF 100mm f/2.8 Macro or Cosina 100mm f/3.5 Macro AF or Tamron"; + choices[28] = "Tamron AF Aspherical 28-200mm f/3.8-5.6 or 28-75mm f/2.8 or 28-105mm f/2.8"; + choices[27] = "Canon EF 35-80mm f/4-5.6"; + choices[28] = "Canon EF 80-200mm f/4.5-5.6 or Tamron Lens"; + choices[29] = "Canon EF 50mm f/1.8 MkII"; + choices[30] = "Canon EF 35-105mm f/4.5-5.6"; + choices[31] = "Tamron SP AF 300mm f/2.8 LD IF"; + choices[32] = "Canon EF 24mm f/2.8 or Sigma 15mm f/2.8 EX Fisheye"; + choices[33] = "Voigtlander Ultron 40mm f/2 SLII Aspherical"; + choices[35] = "Canon EF 35-80mm f/4-5.6"; + choices[36] = "Canon EF 38-76mm f/4.5-5.6"; + choices[37] = "Canon EF 35-80mm f/4-5.6 or Tamron Lens"; + choices[38] = "Canon EF 80-200mm f/4.5-5.6"; + choices[39] = "Canon EF 75-300mm f/4-5.6"; + choices[40] = "Canon EF 28-80mm f/3.5-5.6"; + choices[41] = "Canon EF 28-90mm f/4-5.6"; + choices[42] = "Canon EF 28-200mm f/3.5-5.6 or Tamron AF 28-300mm f/3.5-6.3"; + choices[43] = "Canon EF 28-105mm f/4-5.6"; + choices[44] = "Canon EF 90-300mm f/4.5-5.6"; + choices[45] = "Canon EF-S 18-55mm f/3.5-5.6"; + choices[46] = "Canon EF 28-90mm f/4-5.6"; + choices[48] = "Canon EF-S 18-55mm f/3.5-5.6 IS"; + choices[49] = "Canon EF-S 55-250mm f/4-5.6 IS"; + choices[50] = "Canon EF-S 18-200mm f/3.5-5.6 IS"; + choices[51] = "Canon EF-S 18-135mm f/3.5-5.6 IS"; + choices[94] = "Canon TS-E 17mm f/4L"; + choices[95] = "Canon TS-E 24.0mm f/3.5 L II"; + choices[124] = "Canon MP-E 65mm f/2.8 1-5x Macro Photo"; + choices[125] = "Canon TS-E 24mm f/3.5L"; + choices[126] = "Canon TS-E 45mm f/2.8"; + choices[127] = "Canon TS-E 90mm f/2.8"; + choices[129] = "Canon EF 300mm f/2.8L"; + choices[130] = "Canon EF 50mm f/1.0L"; + choices[131] = "Canon EF 28-80mm f/2.8-4L or Sigma Lens"; + choices[132] = "Canon EF 1200mm f/5.6L"; + choices[134] = "Canon EF 600mm f/4L IS"; + choices[135] = "Canon EF 200mm f/1.8L"; + choices[136] = "Canon EF 300mm f/2.8L"; + choices[137] = "Canon EF 85mm f/1.2L or Sigma Lens"; + choices[138] = "Canon EF 28-80mm f/2.8-4L"; + choices[139] = "Canon EF 400mm f/2.8L"; + choices[140] = "Canon EF 500mm f/4.5L"; + choices[141] = "Canon EF 500mm f/4.5L"; + choices[142] = "Canon EF 300mm f/2.8L IS"; + choices[143] = "Canon EF 500mm f/4L IS"; + choices[144] = "Canon EF 35-135mm f/4-5.6 USM"; + choices[145] = "Canon EF 100-300mm f/4.5-5.6 USM"; + choices[146] = "Canon EF 70-210mm f/3.5-4.5 USM"; + choices[147] = "Canon EF 35-135mm f/4-5.6 USM"; + choices[148] = "Canon EF 28-80mm f/3.5-5.6 USM"; + choices[149] = "Canon EF 100mm f/2"; + choices[150] = "Canon EF 14mm f/2.8L or Sigma Lens"; + choices[151] = "Canon EF 200mm f/2.8L"; + choices[152] = "Canon EF 300mm f/4L IS or Sigma Lens"; + choices[153] = "Canon EF 35-350mm f/3.5-5.6L or Tamron or Sigma Lens"; + choices[154] = "Canon EF 20mm f/2.8 USM"; + choices[155] = "Canon EF 85mm f/1.8 USM"; + choices[156] = "Canon EF 28-105mm f/3.5-4.5 USM"; + choices[160] = "Canon EF 20-35mm f/3.5-4.5 USM or Tamron AF 19-35mm f/3.5-4.5"; + choices[161] = "Canon EF 28-70mm f/2.8L or Sigma or Tamron Lens"; + choices[162] = "Canon EF 200mm f/2.8L"; + choices[163] = "Canon EF 300mm f/4L"; + choices[164] = "Canon EF 400mm f/5.6L"; + choices[165] = "Canon EF 70-200mm f/2.8 L"; + choices[166] = "Canon EF 70-200mm f/2.8 L + x1.4"; + choices[167] = "Canon EF 70-200mm f/2.8 L + x2"; + choices[168] = "Canon EF 28mm f/1.8 USM"; + choices[169] = "Canon EF17-35mm f/2.8L or Sigma Lens"; + choices[170] = "Canon EF 200mm f/2.8L II"; + choices[171] = "Canon EF 300mm f/4L"; + choices[172] = "Canon EF 400mm f/5.6L"; + choices[173] = "Canon EF 180mm Macro f/3.5L or Sigma 180mm F3.5 or 150mm f/2.8 Macro"; + choices[174] = "Canon EF 135mm f/2L"; + choices[175] = "Canon EF 400mm f/2.8L"; + choices[176] = "Canon EF 24-85mm f/3.5-4.5 USM"; + choices[177] = "Canon EF 300mm f/4L IS"; + choices[178] = "Canon EF 28-135mm f/3.5-5.6 IS"; + choices[179] = "Canon EF 24mm f/1.4L USM"; + choices[180] = "Canon EF 35mm f/1.4L"; + choices[181] = "Canon EF 100-400mm f/4.5-5.6L IS + x1.4"; + choices[182] = "Canon EF 100-400mm f/4.5-5.6L IS + x2"; + choices[183] = "Canon EF 100-400mm f/4.5-5.6L IS"; + choices[184] = "Canon EF 400mm f/2.8L + x2"; + choices[185] = "Canon EF 600mm f/4L IS"; + choices[186] = "Canon EF 70-200mm f/4L"; + choices[187] = "Canon EF 70-200mm f/4L + 1.4x"; + choices[188] = "Canon EF 70-200mm f/4L + 2x"; + choices[189] = "Canon EF 70-200mm f/4L + 2.8x"; + choices[190] = "Canon EF 100mm f/2.8 Macro"; + choices[191] = "Canon EF 400mm f/4 DO IS"; + choices[193] = "Canon EF 35-80mm f/4-5.6 USM"; + choices[194] = "Canon EF 80-200mm f/4.5-5.6 USM"; + choices[195] = "Canon EF 35-105mm f/4.5-5.6 USM"; + choices[196] = "Canon EF 75-300mm f/4-5.6 USM"; + choices[197] = "Canon EF 75-300mm f/4-5.6 IS"; + choices[198] = "Canon EF 50mm f/1.4 USM"; + choices[199] = "Canon EF 28-80mm f/3.5-5.6 USM"; + choices[200] = "Canon EF 75-300mm f/4-5.6 USM"; + choices[201] = "Canon EF 28-80mm f/3.5-5.6 USM"; + choices[202] = "Canon EF 28-80 f/3.5-5.6 USM IV"; + choices[208] = "Canon EF 22-55mm f/4-5.6 USM"; + choices[209] = "Canon EF 55-200mm f/4.5-5.6"; + choices[210] = "Canon EF 28-90mm f/4-5.6 USM"; + choices[211] = "Canon EF 28-200mm f/3.5-5.6"; + choices[212] = "Canon EF 28-105mm f/4-5.6 USM"; + choices[213] = "Canon EF 90-300mm f/4.5-5.6"; + choices[214] = "Canon EF-S 18-55mm f/3.5-4.5 USM"; + choices[215] = "Canon EF 55-200mm f/4.5-5.6 II USM"; + choices[224] = "Canon EF 70-200mm f/2.8L IS USM"; + choices[225] = "Canon EF 70-200mm f/2.8L IS USM + x1.4"; + choices[226] = "Canon EF 70-200mm f/2.8L IS USM + x2"; + choices[227] = "Canon EF 70-200mm f/2.8L IS + 2.8x"; + choices[228] = "Canon EF 28-105mm f/3.5-4.5 USM"; + choices[229] = "Canon EF 16-35mm f/2.8L"; + choices[230] = "Canon EF 24-70mm f/2.8L"; + choices[231] = "Canon EF 17-40mm f/4L"; + choices[232] = "Canon EF 70-300mm f/4.5-5.6 DO IS USM"; + choices[233] = "Canon EF 28-300mm f/3.5-5.6L IS"; + choices[234] = "Canon EF-S 17-85mm f4-5.6 IS USM"; + choices[235] = "Canon EF-S10-22mm F3.5-4.5 USM"; + choices[236] = "Canon EF-S60mm F2.8 Macro USM"; + choices[237] = "Canon EF 24-105mm f/4L IS"; + choices[238] = "Canon EF 70-300mm f/4-5.6 IS USM"; + choices[239] = "Canon EF 85mm f/1.2L II USM"; + choices[240] = "Canon EF-S 17-55mm f/2.8 IS USM"; + choices[241] = "Canon EF 50mm f/1.2L USM"; + choices[242] = "Canon EF 70-200mm f/4L IS USM"; + choices[243] = "Canon EF 70-200mm f/4L IS + 1.4x"; + choices[244] = "Canon EF 70-200mm f/4L IS + 2x"; + choices[245] = "Canon EF 70-200mm f/4L IS + 2.8x"; + choices[246] = "Canon EF 16-35mm f/2.8L II"; + choices[247] = "Canon EF 14mm f/2.8L II USM"; + choices[248] = "Canon EF 200mm f/2L IS"; + choices[249] = "Canon EF 800mm f/5.6L IS"; + choices[250] = "Canon EF 24 f/1.4L II"; + choices[254] = "Canon EF 100mm f/2.8L Macro IS USM"; + choices[488] = "Canon EF-S 15-85mm f/3.5-5.6 IS USM"; + } + virtual std::string toString (Tag* t) { + std::ostringstream str; + str << "MacroMode = " << machoices[t->toInt(2,SHORT)] << std::endl; + str << "Self-timer = " << t->toInt(4,SHORT) << std::endl; + str << "Quality = " << qlchoices[t->toInt(6,SHORT)] << std::endl; + str << "CanonFlashMode = " << fmchoices[t->toInt(8,SHORT)] << std::endl; + str << "ContinuousDrive = " << cdchoices[t->toInt(10,SHORT)] << std::endl; + str << "FocusMode = " << fochoices[t->toInt(14,SHORT)] << std::endl; + str << "RecordMode = " << rmchoices[t->toInt(18,SHORT)] << std::endl; + str << "CanonImageSize = " << ischoices[t->toInt(20,SHORT)] << std::endl; + str << "EasyMode = " << emchoices[t->toInt(22,SHORT)] << std::endl; + str << "DigitalZoom = " << dzchoices[t->toInt(24,SHORT)] << std::endl; + str << "Contrast = " << t->toInt(26,SHORT) << std::endl; + str << "Saturation = " << t->toInt(28,SHORT) << std::endl; + str << "Sharpness = " << t->toInt(30,SHORT) << std::endl; + str << "CameraISO = " << t->toInt(32,SHORT) << std::endl; + str << "MeteringMode = " << mmchoices[t->toInt(34,SHORT)] << std::endl; + str << "FocusRange = " << frchoices[t->toInt(36,SHORT)] << std::endl; + str << "AFPoint = " << afchoices[t->toInt(38,SHORT)] << std::endl; + str << "CanonExposureMode = " << exchoices[t->toInt(40,SHORT)] << std::endl; + str << "LensType = " << choices[t->toInt(44,SHORT)] << " (" << t->toInt(44,SHORT) << ")" << std::endl; + str << "LongFocal = " << (double)t->toInt(46,SHORT)/t->toInt(50,SHORT) << " mm" << std::endl; + str << "ShortFocal = " << (double)t->toInt(48,SHORT)/t->toInt(50,SHORT) << " mm" << std::endl; + str << "FocalUnits = " << t->toInt(50,SHORT) << std::endl; + str << "MaxAperture = " << pow (2, t->toInt(52,SHORT)/64.0) << std::endl; + str << "MinAperture = " << pow (2, t->toInt(54,SHORT)/64.0) << std::endl; + str << "FlashActivity = " << t->toInt(56,SHORT) << std::endl; + str << "FlashBits = "; + int f = t->toInt(58,SHORT); + if (f&1) + str << "Manual "; + if (f&2) + str << "TTL "; + if (f&4) + str << "A-TTL "; + if (f&8) + str << "E-TTL "; + if (f&16) + str << "FP sync enabled "; + if (f&(1<<7)) + str << "2nd-curtain sync used "; + if (f&(1<<11)) + str << "FP sync used "; + if (f&(1<<13)) + str << "Built-in "; + if (f&(1<<14)) + str << "External "; + str << std::endl; + str << "FocusContinuous = " << fcchoices[t->toInt(64,SHORT)] << std::endl; + str << "AESetting = " << aechoices[t->toInt(66,SHORT)] << std::endl; + str << "ImageStabilization = " << stchoices[t->toInt(68,SHORT)] << " (" << t->toInt(68,SHORT) << ")" << std::endl; + str << "DisplayAperture = " << t->toInt(70,SHORT) << std::endl; + str << "ZoomSourceWidth = " << t->toInt(72,SHORT) << std::endl; + str << "ZoomTargetWidth = " << t->toInt(74,SHORT) << std::endl; + str << "SpotMeteringMode = " << smchoices[t->toInt(78,SHORT)] << std::endl; + str << "PhotoEffect = " << pechoices[t->toInt(80,SHORT)] << std::endl; + str << "ManualFlashOutput = " << mfchoices[t->toInt(82,SHORT)] << std::endl; + str << "ColorTone = " << t->toInt(84,SHORT); + return str.str(); + } +}; +CACameraSettingsInterpreter caCameraSettingsInterpreter; + + +class CAProcessingInfoInterpreter : public Interpreter { + std::map tcchoices; + std::map sfchoices; + std::map wbchoices; + std::map pschoices; + public: + CAProcessingInfoInterpreter () { + tcchoices[0] = "Standard"; + tcchoices[1] = "Manual"; + tcchoices[2] = "Custom"; + sfchoices[0] = "N/A"; + sfchoices[1] = "Lowest"; + sfchoices[2] = "Low"; + sfchoices[3] = "Standard"; + sfchoices[4] = "High"; + sfchoices[5] = "Highest"; + wbchoices[0] = "Auto"; + wbchoices[1] = "Daylight"; + wbchoices[2] = "Cloudy"; + wbchoices[3] = "Tungsten"; + wbchoices[4] = "Fluorescent"; + wbchoices[5] = "Flash"; + wbchoices[6] = "Custom"; + wbchoices[7] = "Black & White"; + wbchoices[8] = "Shade"; + wbchoices[9] = "Manual Temperature (Kelvin)"; + wbchoices[10] = "PC Set1"; + wbchoices[11] = "PC Set2"; + wbchoices[12] = "PC Set3"; + wbchoices[14] = "Daylight Fluorescent"; + wbchoices[15] = "Custom 1"; + wbchoices[16] = "Custom 2"; + wbchoices[17] = "Underwater"; + pschoices[0] = "None"; + pschoices[1] = "Standard "; + pschoices[2] = "Set 1"; + pschoices[3] = "Set 2"; + pschoices[4] = "Set 3"; + pschoices[0x21] = "User Def. 1"; + pschoices[0x22] = "User Def. 2"; + pschoices[0x23] = "User Def. 3"; + pschoices[0x41] = "External 1"; + pschoices[0x42] = "External 2"; + pschoices[0x43] = "External 3"; + pschoices[0x81] = "Standard"; + pschoices[0x82] = "Portrait"; + pschoices[0x83] = "Landscape"; + pschoices[0x84] = "Neutral"; + pschoices[0x85] = "Faithful"; + pschoices[0x86] = "Monochrome"; + } + virtual std::string toString (Tag* t) { + std::ostringstream str; + str << "ToneCurve = " << tcchoices[t->toInt(2,SHORT)] << std::endl; + str << "Sharpness = " << t->toInt(4,SHORT) << std::endl; + str << "SharpnessFrequency = " << sfchoices[t->toInt(6,SHORT)] << std::endl; + str << "SensorRedLevel = " << t->toInt(8,SHORT) << std::endl; + str << "SensorBlueLevel = " << t->toInt(10,SHORT) << std::endl; + str << "WhiteBalanceRed = " << t->toInt(12,SHORT) << std::endl; + str << "WhiteBalanceBlue = " << t->toInt(14,SHORT) << std::endl; + str << "WhiteBalance = " << wbchoices[t->toInt(16,SHORT)] << std::endl; + str << "ColorTemperature = " << t->toInt(18,SHORT) << std::endl; + str << "PictureStyle = " << pschoices[t->toInt(20,SHORT)] << std::endl; + str << "DigitalGain = " << t->toInt(22,SHORT) << std::endl; + str << "WBShiftAB = " << t->toInt(24,SHORT) << std::endl; + str << "WBShiftGM = " << t->toInt(26,SHORT); + return str.str(); + } +}; +CAProcessingInfoInterpreter caProcessingInfoInterpreter; + +class CAShotInfoInterpreter : public Interpreter { + std::map sschoices; + std::map afchoices; + std::map aechoices; + std::map wbchoices; + std::map ctchoices; + std::map cmchoices; + std::map archoices; + std::map ndchoices; + public: + CAShotInfoInterpreter () { + sschoices[0] = "Off"; + sschoices[1] = "Night Scene"; + sschoices[2] = "On"; + sschoices[3] = "None"; + afchoices[0x3000] = "None (MF)"; + afchoices[0x3001] = "Right"; + afchoices[0x3002] = "Center"; + afchoices[0x3003] = "Center+Right"; + afchoices[0x3004] = "Left"; + afchoices[0x3005] = "Left+Right"; + afchoices[0x3006] = "Left+Center"; + afchoices[0x3007] = "All"; + wbchoices[0] = "Auto"; + wbchoices[1] = "Daylight"; + wbchoices[2] = "Cloudy"; + wbchoices[3] = "Tungsten"; + wbchoices[4] = "Fluorescent"; + wbchoices[5] = "Flash"; + wbchoices[6] = "Custom"; + wbchoices[7] = "Black & White"; + wbchoices[8] = "Shade"; + wbchoices[9] = "Manual Temperature (Kelvin)"; + wbchoices[10] = "PC Set1"; + wbchoices[11] = "PC Set2"; + wbchoices[12] = "PC Set3"; + wbchoices[14] = "Daylight Fluorescent"; + wbchoices[15] = "Custom 1"; + wbchoices[16] = "Custom 2"; + wbchoices[17] = "Underwater"; + aechoices[-1] = "On "; + aechoices[0] = "Off "; + aechoices[1] = "On (shot 1)"; + aechoices[2] = "On (shot 2)"; + aechoices[3] = "On (shot 3)"; + cmchoices[0] = "n/a"; + cmchoices[1] = "Camera Local Control"; + cmchoices[3] = "Computer Remote Control"; + ctchoices[248] = "EOS High-end"; + ctchoices[250] = "Compact"; + ctchoices[252] = "EOS Mid-end"; + ctchoices[255] = "DV Camera"; + ctchoices[0x23] = "User Def. 3"; + archoices[-1] = "Rotated by Software"; + archoices[0] = "None"; + archoices[1] = "Rotate 90 CW"; + archoices[2] = "Rotate 180"; + archoices[3] = "Rotate 270 CW"; + ndchoices[0] = "Off"; + ndchoices[1] = "On"; + } + virtual std::string toString (Tag* t) { + std::ostringstream str; + str << "AutoISO = " << t->toInt(2,SHORT) << std::endl; + str << "BaseISO = " << pow (2, t->toInt(4,SHORT)/32.0 - 4) * 50 << std::endl; + str << "MeasuredEV = " << t->toInt(6,SHORT) << std::endl; + str << "TargetAperture = " << pow (2, t->toInt(8,SHORT)/64.0) << std::endl; + str << "TargetExposureTime = " << pow (2, -t->toInt(10,SHORT)/32.0) << std::endl; + str << "ExposureCompensation = " << t->toInt(12,SHORT)/32.0 << std::endl; + str << "WhiteBalance = " << wbchoices[t->toInt(14,SHORT)] << std::endl; + str << "SlowShutter = " << sschoices[t->toInt(16,SHORT)] << std::endl; + str << "SequenceNumber = " << t->toInt(18,SHORT) << std::endl; + str << "OpticalZoomCode = " << t->toInt(20,SHORT) << std::endl; + str << "FlashGuideNumber = " << t->toInt(26,SHORT) << std::endl; + str << "AFPointsInFocus = " << afchoices[t->toInt(28,SHORT)] << std::endl; + str << "FlashExposureComp = " << t->toInt(30,SHORT) << std::endl; + str << "AutoExposureBracketing = " << afchoices[t->toInt(32,SHORT)] << std::endl; + str << "AEBBracketValue = " << t->toInt(34,SHORT) << std::endl; + str << "ControlMode = " << cmchoices[t->toInt(36,SHORT)] << std::endl; + str << "FocusDistanceUpper = " << t->toInt(38,SHORT) << std::endl; + str << "FocusDistanceLower = " << t->toInt(40,SHORT) << std::endl; + str << "FNumber = " << pow (2, t->toInt(42,SHORT)/64.0) << std::endl; + str << "ExposureTime = " << pow (2, -t->toInt(44,SHORT)/32.0) << std::endl; + str << "BulbDuration = " << t->toInt(48,SHORT) << std::endl; + str << "CameraType = " << ctchoices[t->toInt(52,SHORT)] << std::endl; + str << "AutoRotate = " << archoices[t->toInt(54,SHORT)] << std::endl; + str << "NDFilter = " << ndchoices[t->toInt(56,SHORT)] << std::endl; + str << "Self-timer2 = " << t->toInt(58,SHORT) << std::endl; + str << "FlashOutput = " << t->toInt(66,SHORT); + return str.str(); + } +}; +CAShotInfoInterpreter caShotInfoInterpreter; + + +class CAFileInfoInterpreter : public Interpreter { + std::map bmchoices; + std::map rjqchoices; + std::map rjschoices; + std::map nrchoices; + std::map wbchoices; + std::map fechoices; + std::map techoices; + public: + CAFileInfoInterpreter () { + bmchoices[0] = "Off"; + bmchoices[1] = "AEB"; + bmchoices[2] = "FEB"; + bmchoices[3] = "ISO"; + bmchoices[4] = "WB"; + + rjqchoices[1] = "Economy"; + rjqchoices[2] = "Normal"; + rjqchoices[3] = "Fine"; + rjqchoices[4] = "RAW"; + rjqchoices[5] = "Superfine"; + + rjschoices[0] = "Large"; + rjschoices[1] = "Medium"; + rjschoices[2] = "Small"; + rjschoices[5] = "Medium 1"; + rjschoices[6] = "Medium 2"; + rjschoices[7] = "Medium 3"; + rjschoices[8] = "Postcard"; + rjschoices[9] = "Widescreen"; + + nrchoices[0] = "Off"; + nrchoices[1] = "On (mode 1)"; + nrchoices[2] = "On (mode 2)"; + nrchoices[3] = "On (mode 3)"; + nrchoices[4] = "On (mode 4)"; + + wbchoices[0] = "Off"; + wbchoices[1] = "On (shift AB)"; + wbchoices[2] = "On (shift GM)"; + + fechoices[0] = "None"; + fechoices[1] = "Yellow"; + fechoices[2] = "Orange"; + fechoices[3] = "Red"; + fechoices[4] = "Green"; + + techoices[0] = "None"; + techoices[1] = "Sepia"; + techoices[2] = "Blue"; + techoices[3] = "Purple"; + techoices[4] = "Green"; + + } + virtual std::string toString (Tag* t) { + + std::ostringstream str; + str << "FileNumber = " << t->toInt(1,SHORT) << std::endl; + str << "ShutterCount = " << t->toInt(0,LONG) << std::endl; + str << "BracketMode = " << bmchoices[t->toInt(6,SHORT)] << std::endl; + str << "BracketValue = " << t->toInt(8,SHORT) << std::endl; + str << "BracketShotNumber = " << t->toInt(10,SHORT) << std::endl; + str << "RawJpgQuality = " << rjqchoices[t->toInt(12,SHORT)] << std::endl; + str << "RawJpgSize = " << rjschoices[t->toInt(14,SHORT)] << std::endl; + str << "NoiseReduction = " << nrchoices[t->toInt(16,SHORT)] << std::endl; + str << "WBBracketMode = " << t->toInt(18,SHORT) << std::endl; + str << "WBBracketValueAB = " << t->toInt(24,SHORT) << std::endl; + str << "FilterEffect = " << fechoices[t->toInt(26,SHORT)] << std::endl; + str << "ToningEffect = " << techoices[t->toInt(30,SHORT)]; + return str.str(); + } +}; +CAFileInfoInterpreter caFileInfoInterpreter; + +class CAModelIDInterpreter : public ChoiceInterpreter { + public: + CAModelIDInterpreter () { + choices[0x1010000] = "PowerShot A30"; + choices[0x1040000] = "PowerShot S300 / Digital IXUS 300 / IXY Digital 300"; + choices[0x1060000] = "PowerShot A20"; + choices[0x1080000] = "PowerShot A10"; + choices[0x1090000] = "PowerShot S110 / Digital IXUS v / IXY Digital 200"; + choices[0x1100000] = "PowerShot G2"; + choices[0x1110000] = "PowerShot S40"; + choices[0x1120000] = "PowerShot S30"; + choices[0x1130000] = "PowerShot A40"; + choices[0x1140000] = "EOS D30"; + choices[0x1150000] = "PowerShot A100"; + choices[0x1160000] = "PowerShot S200 / Digital IXUS v2 / IXY Digital 200a"; + choices[0x1170000] = "PowerShot A200"; + choices[0x1180000] = "PowerShot S330 / Digital IXUS 330 / IXY Digital 300a"; + choices[0x1190000] = "PowerShot G3"; + choices[0x1210000] = "PowerShot S45"; + choices[0x1230000] = "PowerShot SD100 / Digital IXUS II / IXY Digital 30"; + choices[0x1240000] = "PowerShot S230 / Digital IXUS v3 / IXY Digital 320"; + choices[0x1250000] = "PowerShot A70"; + choices[0x1260000] = "PowerShot A60"; + choices[0x1270000] = "PowerShot S400 / Digital IXUS 400 / IXY Digital 400"; + choices[0x1290000] = "PowerShot G5"; + choices[0x1300000] = "PowerShot A300"; + choices[0x1310000] = "PowerShot S50"; + choices[0x1340000] = "PowerShot A80"; + choices[0x1350000] = "PowerShot SD10 / Digital IXUS i / IXY Digital L"; + choices[0x1360000] = "PowerShot S1 IS"; + choices[0x1370000] = "PowerShot Pro1"; + choices[0x1380000] = "PowerShot S70"; + choices[0x1390000] = "PowerShot S60"; + choices[0x1400000] = "PowerShot G6"; + choices[0x1410000] = "PowerShot S500 / Digital IXUS 500 / IXY Digital 500"; + choices[0x1420000] = "PowerShot A75"; + choices[0x1440000] = "PowerShot SD110 / Digital IXUS IIs / IXY Digital 30a"; + choices[0x1450000] = "PowerShot A400"; + choices[0x1470000] = "PowerShot A310"; + choices[0x1490000] = "PowerShot A85"; + choices[0x1520000] = "PowerShot S410 / Digital IXUS 430 / IXY Digital 450"; + choices[0x1530000] = "PowerShot A95"; + choices[0x1540000] = "PowerShot SD300 / Digital IXUS 40 / IXY Digital 50"; + choices[0x1550000] = "PowerShot SD200 / Digital IXUS 30 / IXY Digital 40"; + choices[0x1560000] = "PowerShot A520"; + choices[0x1570000] = "PowerShot A510"; + choices[0x1590000] = "PowerShot SD20 / Digital IXUS i5 / IXY Digital L2"; + choices[0x1640000] = "PowerShot S2 IS"; + choices[0x1650000] = "PowerShot SD430 / IXUS Wireless / IXY Wireless"; + choices[0x1660000] = "PowerShot SD500 / Digital IXUS 700 / IXY Digital 600"; + choices[0x1668000] = "EOS D60"; + choices[0x1700000] = "PowerShot SD30 / Digital IXUS i zoom / IXY Digital L3"; + choices[0x1740000] = "PowerShot A430"; + choices[0x1750000] = "PowerShot A410"; + choices[0x1760000] = "PowerShot S80"; + choices[0x1780000] = "PowerShot A620"; + choices[0x1790000] = "PowerShot A610"; + choices[0x1800000] = "PowerShot SD630 / Digital IXUS 65 / IXY Digital 80"; + choices[0x1810000] = "PowerShot SD450 / Digital IXUS 55 / IXY Digital 60"; + choices[0x1820000] = "PowerShot TX1"; + choices[0x1870000] = "PowerShot SD400 / Digital IXUS 50 / IXY Digital 55"; + choices[0x1880000] = "PowerShot A420"; + choices[0x1890000] = "PowerShot SD900 / Digital IXUS 900 Ti / IXY Digital 1000"; + choices[0x1900000] = "PowerShot SD550 / Digital IXUS 750 / IXY Digital 700"; + choices[0x1920000] = "PowerShot A700"; + choices[0x1940000] = "PowerShot SD700 IS / Digital IXUS 800 IS / IXY Digital 800 IS"; + choices[0x1950000] = "PowerShot S3 IS"; + choices[0x1960000] = "PowerShot A540"; + choices[0x1970000] = "PowerShot SD600 / Digital IXUS 60 / IXY Digital 70"; + choices[0x1980000] = "PowerShot G7"; + choices[0x1990000] = "PowerShot A530"; + choices[0x2000000] = "PowerShot SD800 IS / Digital IXUS 850 IS / IXY Digital 900 IS"; + choices[0x2010000] = "PowerShot SD40 / Digital IXUS i7 / IXY Digital L4"; + choices[0x2020000] = "PowerShot A710 IS"; + choices[0x2030000] = "PowerShot A640"; + choices[0x2040000] = "PowerShot A630"; + choices[0x2090000] = "PowerShot S5 IS"; + choices[0x2100000] = "PowerShot A460"; + choices[0x2120000] = "PowerShot SD850 IS / Digital IXUS 950 IS / IXY Digital 810 IS"; + choices[0x2130000] = "PowerShot A570 IS"; + choices[0x2140000] = "PowerShot A560"; + choices[0x2150000] = "PowerShot SD750 / Digital IXUS 75 / IXY Digital 90"; + choices[0x2160000] = "PowerShot SD1000 / Digital IXUS 70 / IXY Digital 10"; + choices[0x2180000] = "PowerShot A550"; + choices[0x2190000] = "PowerShot A450"; + choices[0x2230000] = "PowerShot G9"; + choices[0x2240000] = "PowerShot A650 IS"; + choices[0x2260000] = "PowerShot A720 IS"; + choices[0x2290000] = "PowerShot SX100 IS"; + choices[0x2300000] = "PowerShot SD950 IS / Digital IXUS 960 IS / IXY Digital 2000 IS"; + choices[0x2310000] = "PowerShot SD870 IS / Digital IXUS 860 IS / IXY Digital 910 IS"; + choices[0x3010000] = "PowerShot Pro90 IS"; + choices[0x4040000] = "PowerShot G1"; + choices[0x6040000] = "PowerShot S100 / Digital IXUS / IXY Digital"; + choices[0x4007d675] = "HV10"; + choices[0x4007d777] = "iVIS DC50"; + choices[0x4007d778] = "iVIS HV20"; + choices[0x80000001] = "EOS-1D"; + choices[0x80000167] = "EOS-1DS"; + choices[0x80000168] = "EOS 10D"; + choices[0x80000169] = "EOS-1D Mark III"; + choices[0x80000170] = "EOS Digital Rebel / 300D / Kiss Digital"; + choices[0x80000174] = "EOS-1D Mark II"; + choices[0x80000175] = "EOS 20D"; + choices[0x80000188] = "EOS-1Ds Mark II"; + choices[0x80000189] = "EOS Digital Rebel XT / 350D / Kiss Digital N"; + choices[0x80000190] = "EOS 40D"; + choices[0x80000213] = "EOS 5D"; + choices[0x80000215] = "EOS-1Ds Mark III"; + choices[0x80000232] = "EOS-1D Mark II N"; + choices[0x80000234] = "EOS 30D"; + choices[0x80000236] = "EOS Digital Rebel XTi / 400D / Kiss Digital X"; + choices[0x80000254] = "EOS Rebel XS / 1000D / Kiss F"; + choices[0x80000261] = "EOS 50D"; + } +}; + +CAModelIDInterpreter caModelIDInterpreter; + + +const TagAttrib canonAttribs[] = { + 0, 1, 0, 0, 0x0001, "CanonCameraSettings", &caCameraSettingsInterpreter, + 0, 1, 0, 0, 0x0002, "CanonFocalLength", &caFocalLengthInterpreter, + 0, 1, 0, 0, 0x0003, "CanonFlashInfo", &stdInterpreter, + 0, 1, 0, 0, 0x0004, "CanonShotInfo", &caShotInfoInterpreter, + 0, 1, 0, 0, 0x0005, "CanonPanorama", &stdInterpreter, + 0, 1, 0, 0, 0x0006, "CanonImageType", &stdInterpreter, + 0, 1, 0, 0, 0x0007, "CanonFirmwareVersion", &stdInterpreter, + 0, 1, 0, 0, 0x0008, "FileNumber", &stdInterpreter, + 0, 1, 0, 0, 0x0009, "OwnerName", &stdInterpreter, + 0, 1, 0, 0, 0x000a, "ColorInfoD30", &stdInterpreter, + 0, 1, 0, 0, 0x000c, "SerialNumber", &stdInterpreter, + 0, 1, 0, 0, 0x000d, "CanonCameraInfo", &stdInterpreter, + 0, 1, 0, 0, 0x000e, "CanonFileLength", &stdInterpreter, + 0, 1, 0, 0, 0x000f, "CustomFunctions", &stdInterpreter, + 0, 1, 0, 0, 0x0010, "CanonModelID", &caModelIDInterpreter, + 0, 1, 0, 0, 0x0012, "CanonAFInfo", &stdInterpreter, + 0, 1, 0, 0, 0x0015, "SerialNumberFormat", &stdInterpreter, + 0, 1, 0, 0, 0x001c, "DateStampMode", &stdInterpreter, + 0, 1, 0, 0, 0x001d, "MyColors", &stdInterpreter, + 0, 1, 0, 0, 0x001e, "FirmwareRevision", &stdInterpreter, + 0, 3, 0, 0, 0x0024, "FaceDetect1", &stdInterpreter, + 0, 3, 0, 0, 0x0025, "FaceDetect2", &stdInterpreter, + 0, 1, 0, 0, 0x0026, "CanonAFInfo2", &stdInterpreter, + 0, 1, 0, 0, 0x0083, "OriginalDecisionData", &stdInterpreter, + 0, 1, 0, 0, 0x0090, "CustomFunctions1D", &stdInterpreter, + 0, 1, 0, 0, 0x0091, "PersonalFunctions", &stdInterpreter, + 0, 1, 0, 0, 0x0092, "PersonalFunctionValues", &stdInterpreter, + 0, 1, 0, 0, 0x0093, "CanonFileInfo", &caFileInfoInterpreter, + 0, 1, 0, 0, 0x0094, "AFPointsInFocus1D", &stdInterpreter, + 0, 1, 0, 0, 0x0095, "LensType", &stdInterpreter, + 0, 1, 0, 0, 0x0096, "InternalSerialNumber", &caIntSerNumInterpreter, + 0, 1, 0, 0, 0x0097, "DustRemovalData", &stdInterpreter, + 0, 1, 0, 0, 0x0099, "CustomFunctions2", &stdInterpreter, + 0, 1, 0, 0, 0x00a0, "ProccessingInfo", &caProcessingInfoInterpreter, + 0, 1, 0, 0, 0x00a1, "ToneCurveTable", &stdInterpreter, + 0, 1, 0, 0, 0x00a2, "SharpnessTable", &stdInterpreter, + 0, 1, 0, 0, 0x00a3, "SharpnessFreqTable", &stdInterpreter, + 0, 1, 0, 0, 0x00a4, "WhiteBalanceTable", &stdInterpreter, + 0, 1, 0, 0, 0x00a9, "ColorBalance", &stdInterpreter, + 0, 1, 0, 0, 0x00ae, "ColorTemperature", &stdInterpreter, + 0, 3, 0, 0, 0x00b0, "CanonFlags", &stdInterpreter, + 0, 1, 0, 0, 0x00b1, "ModifiedInfo", &stdInterpreter, + 0, 1, 0, 0, 0x00b2, "ToneCurveMatching", &stdInterpreter, + 0, 1, 0, 0, 0x00b3, "WhiteBalanceMatching", &stdInterpreter, + 0, 1, 0, 0, 0x00b4, "ColorSpace", &stdInterpreter, + 1, 1, 0, 0, 0x00b6, "PreviewImageInfo", &stdInterpreter, + 0, 1, 0, 0, 0x00d0, "VRDOffset", &stdInterpreter, + 0, 1, 0, 0, 0x00e0, "SensorInfo", &stdInterpreter, + 0, 1, 0, 0, 0x4001, "ColorBalance", &stdInterpreter, + 0, 1, 0, 0, 0x4002, "UnknownBlock1", &stdInterpreter, + 0, 1, 0, 0, 0x4003, "ColorInfo", &stdInterpreter, + 1, 1, 0, 0, 0x4005, "UnknownBlock2", &stdInterpreter, + 1, 1, 0, 0, 0x4008, "BlackLevel", &stdInterpreter, + -1, 0, 0, 0, 0, "", NULL}; + +}; + #endif + diff --git a/rtexif/fujiattribs.cc b/rtexif/fujiattribs.cc new file mode 100644 index 000000000..9f946dd03 --- /dev/null +++ b/rtexif/fujiattribs.cc @@ -0,0 +1,263 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _FUJIATTRIBS_ +#define _FUJIATTRIBS_ + +#include +#include +#include +#include +#include +#include + +namespace rtexif { + +class FAOnOffInterpreter : public ChoiceInterpreter { + public: + FAOnOffInterpreter () { + choices[0] = "Off"; + choices[1] = "On"; + } +}; +FAOnOffInterpreter faOnOffInterpreter; + +class FASharpnessInterpreter : public ChoiceInterpreter { + public: + FASharpnessInterpreter () { + choices[1] = "Soft"; + choices[2] = "Soft2"; + choices[3] = "Normal"; + choices[4] = "Hard"; + choices[5] = "Hard2"; + choices[0x82] = "Medium Soft"; + choices[0x84] = "Medium Hard"; + choices[0x8000] = "Film Simulation"; + choices[0xffff] = "n/a"; + } +}; +FASharpnessInterpreter faSharpnessInterpreter; + +class FAWhiteBalanceInterpreter : public ChoiceInterpreter { + public: + FAWhiteBalanceInterpreter () { + choices[0] = "Auto"; + choices[0x100] = "Daylight"; + choices[0x200] = "Cloudy"; + choices[0x300] = "Daylight Fluorescent"; + choices[0x301] = "Day White Fluorescent"; + choices[0x302] = "White Fluorescent"; + choices[0x303] = "Warm White Fluorescent"; + choices[0x304] = "Living Room Warm White Fluorescent"; + choices[0x400] = "Incandescent"; + choices[0x500] = "Flash"; + choices[0xf00] = "Custom"; + choices[0xf01] = "Custom2"; + choices[0xf02] = "Custom3"; + choices[0xf03] = "Custom4"; + choices[0xf04] = "Custom5"; + choices[0xff0] = "Kelvin"; + } +}; +FAWhiteBalanceInterpreter faWhiteBalanceInterpreter; + +class FASaturationInterpreter : public ChoiceInterpreter { + public: + FASaturationInterpreter () { + choices[0] = "Normal"; + choices[0x80] = "Medium High"; + choices[0x100] = "High"; + choices[0x180] = "Medium Low"; + choices[0x200] = "Low"; + choices[0x300] = "None (B&W)"; + choices[0x8000] = "Film Simulation"; + } +}; +FASaturationInterpreter faSaturationInterpreter; + +class FAContrastInterpreter : public ChoiceInterpreter { + public: + FAContrastInterpreter () { + choices[0] = "Normal"; + choices[0x80] = "Medium High"; + choices[0x100] = "High"; + choices[0x180] = "Medium Low"; + choices[0x200] = "Low"; + choices[0x8000] = "Film Simulation"; + } +}; +FAContrastInterpreter faContrastInterpreter; + +class FAContrast2Interpreter : public ChoiceInterpreter { + public: + FAContrast2Interpreter () { + choices[0] = "Normal"; + choices[0x100] = "High"; + choices[0x300] = "Low"; + } +}; +FAContrast2Interpreter faContrast2Interpreter; + +class FANoiseReductionInterpreter : public ChoiceInterpreter { + public: + FANoiseReductionInterpreter () { + choices[0x40] = "Low"; + choices[0x80] = "Normal"; + } +}; +FANoiseReductionInterpreter faNoiseReductionInterpreter; + +class FAFlashInterpreter : public ChoiceInterpreter { + public: + FAFlashInterpreter () { + choices[0] = "Auto"; + choices[1] = "On"; + choices[2] = "Off"; + choices[3] = "Red-eye reduction"; + choices[4] = "External"; + } +}; +FAFlashInterpreter faFlashInterpreter; + +class FAFocusModeInterpreter : public ChoiceInterpreter { + public: + FAFocusModeInterpreter () { + choices[0] = "Auto"; + choices[1] = "Manual"; + } +}; +FAFocusModeInterpreter faFocusModeInterpreter; + +class FAColorModeInterpreter : public ChoiceInterpreter { + public: + FAColorModeInterpreter () { + choices[0] = "Standard"; + choices[0x10] = "Chrome"; + choices[0x30] = "B & W"; + } +}; +FAColorModeInterpreter faColorModeInterpreter; + +class FADynamicRangeInterpreter : public ChoiceInterpreter { + public: + FADynamicRangeInterpreter () { + choices[1] = "Standard"; + choices[3] = "Wide"; + } +}; +FADynamicRangeInterpreter faDynamicRangeInterpreter; + +class FAFilmModeInterpreter : public ChoiceInterpreter { + public: + FAFilmModeInterpreter () { + choices[0] = "F0/Standard"; + choices[0x100] = "F1/Studio Portrait"; + choices[0x110] = "F1a/Studio Portrait Enhanced Saturation"; + choices[0x120] = "F1b/Studio Portrait Smooth Skin Tone"; + choices[0x130] = "F1c/Studio Portrait Increased Sharpness "; + choices[0x200] = "F2/Fujichrome"; + choices[0x300] = "F3/Studio Portrait Ex"; + choices[0x400] = "F4/Velvia"; + } +}; +FAFilmModeInterpreter faFilmModeInterpreter; + +class FADRSettingInterpreter : public ChoiceInterpreter { + public: + FADRSettingInterpreter () { + choices[0] = "Auto (100-400%)"; + choices[0x1] = "RAW"; + choices[0x100] = "Standard (100%)"; + choices[0x200] = "Wide1 (230%)"; + choices[0x201] = "Wide2 (400%)"; + choices[0x8000] = "Film Simulation"; + } +}; +FADRSettingInterpreter faDRSettingInterpreter; + +class FAPictureModeInterpreter : public ChoiceInterpreter { + public: + FAPictureModeInterpreter () { + choices[0] = "Auto"; + choices[1] = "Portrait"; + choices[2] = "Landscape"; + choices[3] = "Macro"; + choices[4] = "Sports"; + choices[5] = "Night Scene"; + choices[6] = "Program AE"; + choices[7] = "Natural Light"; + choices[8] = "Anti-blur"; + choices[9] = "Beach & Snow"; + choices[10] = "Sunset"; + choices[11] = "Museum"; + choices[12] = "Party"; + choices[13] = "Flower"; + choices[14] = "Text"; + choices[15] = "Natural Light & Flash"; + choices[16] = "Beach"; + choices[17] = "Fireworks"; + choices[18] = "Underwater"; + choices[0x100] = "Aperture-priority AE"; + choices[0x200] = "Shutter speed priority AE"; + choices[0x300] = "Manual"; + } +}; +FAPictureModeInterpreter faPictureModeInterpreter; + + + +const TagAttrib fujiAttribs[] = { + 0, 1, 0, 0, 0x0000, "Version", &stdInterpreter, + 0, 1, 0, 0, 0x0010, "InternalSerialNumber", &stdInterpreter, + 0, 1, 0, 0, 0x1000, "Quality", &stdInterpreter, + 0, 1, 0, 0, 0x1001, "Sharpness", &faSharpnessInterpreter, + 0, 1, 0, 0, 0x1002, "WhiteBalance", &faWhiteBalanceInterpreter, + 0, 1, 0, 0, 0x1003, "Saturation", &faSaturationInterpreter, + 0, 1, 0, 0, 0x1004, "Contrast", &faContrastInterpreter, + 0, 1, 0, 0, 0x1005, "ColorTemperature", &stdInterpreter, + 0, 1, 0, 0, 0x1006, "Contrast2", &faContrast2Interpreter, + 0, 1, 0, 0, 0x100a, "WhiteBalanceFineTune", &stdInterpreter, + 0, 1, 0, 0, 0x100b, "NoiseReduction", &faNoiseReductionInterpreter, + 0, 1, 0, 0, 0x100b, "FujiFlashMode", &faFlashInterpreter, + 0, 1, 0, 0, 0x1011, "FlashExposureComp", &stdInterpreter, + 0, 1, 0, 0, 0x1020, "Macro", &faOnOffInterpreter, + 0, 1, 0, 0, 0x1021, "FocusMode", &faFocusModeInterpreter, + 0, 1, 0, 0, 0x1023, "FocusPixel", &stdInterpreter, + 0, 1, 0, 0, 0x1030, "SlowSync", &faOnOffInterpreter, + 0, 1, 0, 0, 0x1031, "PictureMode", &faPictureModeInterpreter, + 0, 1, 0, 0, 0x1100, "AutoBracketing", &faOnOffInterpreter, + 0, 1, 0, 0, 0x1101, "SequenceNumber", &stdInterpreter, + 0, 1, 0, 0, 0x1210, "ColorMode", &faColorModeInterpreter, + 0, 1, 0, 0, 0x1300, "BlurWarning", &faOnOffInterpreter, + 0, 1, 0, 0, 0x1301, "FocusWarning", &faOnOffInterpreter, + 0, 1, 0, 0, 0x1302, "ExposureWarning", &faOnOffInterpreter, + 0, 1, 0, 0, 0x1400, "DynamicRange", &faDynamicRangeInterpreter, + 0, 1, 0, 0, 0x1401, "FilmMode", &faFilmModeInterpreter, + 0, 1, 0, 0, 0x1402, "DynamicRangeSetting", &faDRSettingInterpreter, + 0, 1, 0, 0, 0x1403, "DevelopmentDynamicRange", &stdInterpreter, + 0, 1, 0, 0, 0x1404, "MinFocalLength", &stdInterpreter, + 0, 1, 0, 0, 0x1405, "MaxFocalLength", &stdInterpreter, + 0, 1, 0, 0, 0x1406, "MaxApertureAtMinFocal", &stdInterpreter, + 0, 1, 0, 0, 0x1407, "MaxApertureAtMaxFocal", &stdInterpreter, + 0, 1, 0, 0, 0x8000, "FileSource", &stdInterpreter, + 0, 1, 0, 0, 0x8002, "OrderNumber", &stdInterpreter, + 0, 1, 0, 0, 0x8003, "FrameNumber", &stdInterpreter, + -1, 0, 0, 0, 0, "", NULL}; +}; + #endif + diff --git a/rtexif/nikonattribs.cc b/rtexif/nikonattribs.cc new file mode 100644 index 000000000..905089714 --- /dev/null +++ b/rtexif/nikonattribs.cc @@ -0,0 +1,718 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _NIKONATTRIBS_ +#define _NIKONATTRIBS_ + +#include +#include +#include +#include +#include +#include +#include + +namespace rtexif { + +class NAISOInterpreter : public Interpreter { + public: + NAISOInterpreter () {} + virtual std::string toString (Tag* t) { + sprintf (buffer, "%d", t->toInt(2)); + return buffer; + } +}; +NAISOInterpreter naISOInterpreter; + +class NALensTypeInterpreter : public Interpreter { + public: + NALensTypeInterpreter () {} + virtual std::string toString (Tag* t) { + int a = t->toInt(); + std::ostringstream str; + str << "MF = " << (a&1 ? "Yes" : "No") << std::endl; + str << "D = " << (a&2 ? "Yes" : "No") << std::endl; + str << "G = " << (a&4 ? "Yes" : "No") << std::endl; + str << "VR = " << (a&8 ? "Yes" : "No"); + return str.str(); + } +}; +NALensTypeInterpreter naLensTypeInterpreter; + +class NAFlashModeInterpreter : public ChoiceInterpreter { + public: + NAFlashModeInterpreter () { + choices[0] = "Did Not Fire"; + choices[1] = "Fired, Manual"; + choices[7] = "Fired, External"; + choices[8] = "Fired, Commander Mode"; + choices[9] = "Fired, TTL Mode"; + } +}; +NAFlashModeInterpreter naFlashModeInterpreter; + +class NAHiISONRInterpreter : public ChoiceInterpreter { + public: + NAHiISONRInterpreter () { + choices[0] = "Off"; + choices[1] = "Minimal"; + choices[2] = "Low"; + choices[4] = "Normal"; + choices[6] = "High"; + } +}; +NAHiISONRInterpreter naHiISONRInterpreter; + +class NAShootingModeInterpreter : public Interpreter { + public: + NAShootingModeInterpreter () {} + virtual std::string toString (Tag* t) { + int a = t->toInt(); + std::ostringstream str; + str << "Continuous = " << (a&1 ? "Yes" : "No") << std::endl; + str << "Delay = " << (a&2 ? "Yes" : "No") << std::endl; + str << "PC Control = " << (a&4 ? "Yes" : "No") << std::endl; + str << "Exposure Bracketing = " << (a&8 ? "Yes" : "No") << std::endl; + str << "Auto ISO = " << (a&16 ? "Yes" : "No") << std::endl; + str << "White-Balance Bracketing = " << (a&32 ? "Yes" : "No") << std::endl; + str << "IR Control = " << (a&64 ? "Yes" : "No"); + return str.str(); + } +}; +NAShootingModeInterpreter naShootingModeInterpreter; + +class NAAFInfoInterpreter : public Interpreter { + std::map amchoices; + std::map afpchoices; + public: + NAAFInfoInterpreter () { + amchoices[0] = "Single Area"; + amchoices[1] = "Dynamic Area"; + amchoices[2] = "Dynamic Area, Closest Subject"; + amchoices[3] = "Group Dynamic"; + amchoices[4] = "Single Area (wide)"; + amchoices[5] = "Dynamic Area (wide)"; + afpchoices[0] = "Center"; + afpchoices[1] = "Top"; + afpchoices[2] = "Bottom"; + afpchoices[3] = "Left"; + afpchoices[4] = "Right"; + afpchoices[5] = "Upper-left"; + afpchoices[6] = "Upper-right"; + afpchoices[7] = "Lower-left"; + afpchoices[8] = "Lower-right"; + afpchoices[9] = "Far Left"; + afpchoices[10] = "Far Right"; + } + virtual std::string toString (Tag* t) { + int am = t->toInt (0, BYTE); + int afp = t->toInt (1, BYTE); + int aff = t->toInt (2, SHORT); + std::ostringstream str; + str << "AFAreaMode = " << amchoices[am] << std::endl; + str << "AFAreaMode = " << afpchoices[afp] << std::endl; + + std::ostringstream af; + if (aff&1) + if (af.str()=="") af << "Center"; + else af << ", Center"; + else if (aff&2) + if (af.str()=="") af << "Top"; + else af << ", Top"; + else if (aff&4) + if (af.str()=="") af << "Bottom"; + else af << ", Bottom"; + else if (aff&8) + if (af.str()=="") af << "Left"; + else af << ", Left"; + else if (aff&16) + if (af.str()=="") af << "Right"; + else af << ", Right"; + else if (aff&32) + if (af.str()=="") af << "Upper-left"; + else af << ", Upper-left"; + else if (aff&64) + if (af.str()=="") af << "Upper-right"; + else af << ", Upper-right"; + else if (aff&128) + if (af.str()=="") af << " Lower-left"; + else af << ", Lower-left"; + else if (aff&256) + if (af.str()=="") af << "Lower-right"; + else af << ", Lower-right"; + else if (aff&512) + if (af.str()=="") af << "Far Left"; + else af << ", Far Left"; + else if (aff&1024) + if (af.str()=="") af << "Far Right"; + else af << ", Far Right"; + + str << "AFPointsInFocus = " << af.str(); + return str.str(); + } +}; +NAAFInfoInterpreter naAFInfoInterpreter; + +class NALensDataInterpreter : public Interpreter { + std::map lenses; + public: + NALensDataInterpreter () { + lenses["00 00 00 00 00 00 00 01"] = "Manual Lens No CPU "; + lenses["00 00 00 00 00 00 E1 12"] = "TC-17E II "; + lenses["00 00 00 00 00 00 F1 0C"] = "TC-14E [II] or Sigma APO Tele Converter 1.4x EX DG or Kenko Teleplus PRO 300 DG 1.4x"; + lenses["00 00 00 00 00 00 F2 18"] = "TC-20E [II] or Sigma APO Tele Converter 2x EX DG or Kenko Teleplus PRO 300 DG 2.0x"; + lenses["00 36 1C 2D 34 3C 00 06"] = "Tamron SP AF11-18mm f/4.5-5.6 Di II LD Aspherical (IF)"; + lenses["00 3C 1F 37 30 30 00 06"] = "Tokina AT-X 124 AF PRO DX - AF 12-24mm F4"; + lenses["00 3E 80 A0 38 3F 00 02"] = "Tamron SP AF200-500mm f/5-6.3 Di LD (IF)"; + lenses["00 3F 2D 80 2B 40 00 06"] = "Tamron AF18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF)"; + lenses["00 3F 2D 80 2C 40 00 06"] = "Tamron AF18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) Macro"; + lenses["00 3F 80 A0 38 3F 00 02"] = "Tamron SP AF200-500mm f/5-6.3 Di"; + lenses["00 40 18 2B 2C 34 00 06"] = "Tokina AT-X 107 DX Fish-Eye - AF 10-17mm F3.5-4.5"; + lenses["00 40 2A 72 2C 3C 00 06"] = "Tokina AT-X 16.5-135 DX (AF 16.5-135mm F3.5-5.6)"; + lenses["00 40 2B 2B 2C 2C 00 02"] = "Tokina AT-X 17 AF PRO - AF 17mm F3.5"; + lenses["00 40 2D 80 2C 40 00 06"] = "Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) Macro (A14NII)"; + lenses["00 40 2D 88 2C 40 00 06"] = "Tamron AF 18-250mm f/3.5-6.3 Di II LD Aspherical (IF) Macro (A18NII)"; + lenses["00 40 2D 88 2C 40 62 06"] = "Tamron AF 18-250mm f/3.5-6.3 Di II LD Aspherical (IF) Macro (A18)"; + lenses["00 40 31 31 2C 2C 00 00"] = "Voigtlander Color Skopar 20mm F3.5 SLII Aspherical"; + lenses["00 44 60 98 34 3C 00 02"] = "Tokina AT-X 840D 80-400mm F4.5-5.6"; + lenses["00 47 10 10 24 24 00 00"] = "Fisheye Nikkor 8mm f/2.8 AiS"; + lenses["00 47 44 44 24 24 00 06"] = "Tokina AT-X M35 PRO DX (AF 35mm f/2.8 Macro)"; + lenses["00 47 53 80 30 3C 00 06"] = "Tamron AF55-200mm f/4-5.6 Di II LD"; + lenses["00 48 1C 29 24 24 00 06"] = "Tokina AT-X 116 PRO DX (AF 11-16mm f/2.8)"; + lenses["00 48 29 50 24 24 00 06"] = "Tokina AT-X 165 PRO DX - AF 16-50mm F2.8"; + lenses["00 48 3C 60 24 24 00 02"] = "Tokina AT-X 280 AF PRO 28-80mm F2.8 Aspherical"; + lenses["00 48 3C 6A 24 24 00 02"] = "Tamron SP AF28-105mm f/2.8"; + lenses["00 48 50 50 18 18 00 00"] = "Nikkor H 50mm f/2"; + lenses["00 48 50 72 24 24 00 06"] = "Tokina AT-X 535 PRO DX - AF 50-135mm F2.8"; + lenses["00 48 5C 8E 30 3C 00 06"] = "Tamron AF 70-300mm f/4-5.6 Di LD Macro 1:2 (A17)"; + lenses["00 48 68 68 24 24 00 00"] = "Series E 100mm f/2.8"; + lenses["00 48 80 80 30 30 00 00"] = "Nikkor 200mm f/4 AiS"; + lenses["00 49 30 48 22 2B 00 02"] = "Tamron SP AF20-40mm f/2.7-3.5"; + lenses["00 4C 6A 6A 20 20 00 00"] = "Nikkor 105mm f/2.5 AiS"; + lenses["00 4C 7C 7C 2C 2C 00 02"] = "Tamron SP AF180mm f/3.5 Di Model B01"; + lenses["00 53 2B 50 24 24 00 06"] = "Tamron SP AF17-50mm f/2.8 (A16)"; + lenses["00 54 2B 50 24 24 00 06"] = "Tamron SP AF 17-50mm f/2.8 XR Di II LD Aspherical (IF) (A16NII)"; + lenses["00 54 44 44 0C 0C 00 00"] = "Nikkor 35mm f/1.4 AiS"; + lenses["00 54 48 48 18 18 00 00"] = "Voigtlander Ultron 40mm F2 SLII Aspherical"; + lenses["00 54 55 55 0C 0C 00 00"] = "Voigtlander Nokton 58mm F1.4 SLII"; + lenses["00 54 56 56 30 30 00 00"] = "Coastal Optical Systems 60mm 1:4 UV-VIS-IR Macro Apo"; + lenses["00 54 68 68 24 24 00 02"] = "Tokina AT-X M100 PRO D - 100mm F2.8"; + lenses["00 54 8E 8E 24 24 00 02"] = "Tokina AT-X 300 AF PRO 300mm F2.8"; + lenses["01 00 00 00 00 00 02 00"] = "AF Teleconverter TC-16A 1.6x"; + lenses["01 00 00 00 00 00 08 00"] = "AF Teleconverter TC-16A 1.6x"; + lenses["01 58 50 50 14 14 02 00"] = "AF Nikkor 50mm f/1.8"; + lenses["02 2F 98 98 3D 3D 02 00"] = "Sigma 400mm F5.6 APO"; + lenses["02 37 5E 8E 35 3D 02 00"] = "Sigma 75-300mm F4.5-5.6 APO"; + lenses["02 37 A0 A0 34 34 02 00"] = "Sigma APO 500mm F4.5"; + lenses["02 3A 5E 8E 32 3D 02 00"] = "Sigma 75-300mm F4.0-5.6"; + lenses["02 3B 44 61 30 3D 02 00"] = "Sigma 35-80mm F4-5.6"; + lenses["02 3F 24 24 2C 2C 02 00"] = "Sigma 14mm F3.5"; + lenses["02 3F 3C 5C 2D 35 02 00"] = "Sigma 28-70mm F3.5-4.5 UC"; + lenses["02 40 44 73 2B 36 02 00"] = "Sigma 35-135mm F3.5-4.5 a"; + lenses["02 42 44 5C 2A 34 02 00"] = "AF Zoom-Nikkor 35-70mm f/3.3-4.5"; + lenses["02 42 44 5C 2A 34 08 00"] = "AF Zoom-Nikkor 35-70mm f/3.3-4.5"; + lenses["02 46 37 37 25 25 02 00"] = "Sigma 24mm F2.8 Macro"; + lenses["02 46 3C 5C 25 25 02 00"] = "Sigma 28-70mm F2.8"; + lenses["02 46 5C 82 25 25 02 00"] = "Sigma 70-210mm F2.8 APO"; + lenses["02 48 65 65 24 24 02 00"] = "Sigma 90mm F2.8 Macro"; + lenses["03 43 5C 81 35 35 02 00"] = "Soligor AF C/D ZOOM UMCS 70-210mm 1:4.5"; + lenses["03 48 5C 81 30 30 02 00"] = "AF Zoom-Nikkor 70-210mm f/4"; + lenses["04 48 3C 3C 24 24 03 00"] = "AF Nikkor 28mm f/2.8"; + lenses["05 54 50 50 0C 0C 04 00"] = "AF Nikkor 50mm f/1.4"; + lenses["06 3F 68 68 2C 2C 06 00"] = "Cosina 100mm f/3.5 Macro"; + lenses["06 54 53 53 24 24 06 00"] = "AF Micro-Nikkor 55mm f/2.8"; + lenses["07 36 3D 5F 2C 3C 03 00"] = "Cosina AF Zoom 28-80mm F3.5-5.6 MC Macro"; + lenses["07 3E 30 43 2D 35 03 00"] = "Soligor AF Zoom 19-35mm 1:3.5-4.5 MC"; + lenses["07 40 2F 44 2C 34 03 02"] = "Tamron AF19-35mm f/3.5-4.5 N"; + lenses["07 40 30 45 2D 35 03 02"] = "Tamron AF19-35mm f/3.5-4.5"; + lenses["07 40 3C 62 2C 34 03 00"] = "AF Zoom-Nikkor 28-85mm f/3.5-4.5"; + lenses["07 46 2B 44 24 30 03 02"] = "Tamron SP AF17-35mm f/2.8-4 Di LD Aspherical (IF)"; + lenses["07 46 3D 6A 25 2F 03 00"] = "Cosina AF Zoom 28-105mm F2.8-3.8 MC"; + lenses["07 47 3C 5C 25 35 03 00"] = "Tokina AF 287 SD (AF 28-70mm f/2.8-4.5)"; + lenses["07 48 3C 5C 24 24 03 00"] = "Tokina AT-X 287 AF (AF 28-70mm f/2.8)"; + lenses["08 40 44 6A 2C 34 04 00"] = "AF Zoom-Nikkor 35-105mm f/3.5-4.5"; + lenses["09 48 37 37 24 24 04 00"] = "AF Nikkor 24mm f/2.8"; + lenses["0A 48 8E 8E 24 24 03 00"] = "AF Nikkor 300mm f/2.8 IF-ED"; + lenses["0B 3E 3D 7F 2F 3D 0E 00"] = "Tamron AF28-200mm f/3.8-5.6"; + lenses["0B 3E 3D 7F 2F 3D 0E 02"] = "Tamron AF28-200mm f/3.8-5.6D"; + lenses["0B 48 7C 7C 24 24 05 00"] = "AF Nikkor 180mm f/2.8 IF-ED"; + lenses["0D 40 44 72 2C 34 07 00"] = "AF Zoom-Nikkor 35-135mm f/3.5-4.5"; + lenses["0E 48 5C 81 30 30 05 00"] = "AF Zoom-Nikkor 70-210mm f/4"; + lenses["0E 4A 31 48 23 2D 0E 02"] = "Tamron SP AF20-40mm f/2.7-3.5"; + lenses["0F 58 50 50 14 14 05 00"] = "AF Nikkor 50mm f/1.8 N"; + lenses["10 3D 3C 60 2C 3C D2 02"] = "Tamron AF28-80mm f/3.5-5.6 Aspherical"; + lenses["10 48 8E 8E 30 30 08 00"] = "AF Nikkor 300mm f/4 IF-ED"; + lenses["11 48 44 5C 24 24 08 00"] = "AF Zoom-Nikkor 35-70mm f/2.8"; + lenses["12 36 5C 81 35 3D 09 00"] = "Cosina AF Zoom 70-210mm F4.5-5.6 MC Macro"; + lenses["12 39 5C 8E 34 3D 08 02"] = "Cosina AF Zoom 70-300mm F4.5-5.6 MC Macro"; + lenses["12 3B 68 8D 3D 43 09 02"] = "Unknown 100-290mm f/5.6-6.7"; + lenses["12 3D 3C 80 2E 3C DF 02"] = "Tamron AF 28-200mm f/3.8-5.6 AF Aspherical LD (IF) (271D)"; + lenses["12 48 5C 81 30 3C 09 00"] = "AF Nikkor 70-210mm f/4-5.6"; + lenses["12 4A 5C 81 31 3D 09 00"] = "Soligor AF C/D Auto Zoom+Macro 70-210mm 1:4-5.6 UMCS"; + lenses["13 42 37 50 2A 34 0B 00"] = "AF Zoom-Nikkor 24-50mm f/3.3-4.5"; + lenses["14 48 60 80 24 24 0B 00"] = "AF Zoom-Nikkor 80-200mm f/2.8 ED"; + lenses["14 48 68 8E 30 30 0B 00"] = "Tokina AT-X 340 AF II 100-300mm F4"; + lenses["14 54 60 80 24 24 0B 00"] = "Tokina AT-X 828 AF 80-200mm F2.8"; + lenses["15 4C 62 62 14 14 0C 00"] = "AF Nikkor 85mm f/1.8"; + lenses["17 3C A0 A0 30 30 0F 00"] = "Nikkor 500mm f/4 P ED IF"; + lenses["17 3C A0 A0 30 30 11 00"] = "Nikkor 500mm f/4 P ED IF"; + lenses["18 40 44 72 2C 34 0E 00"] = "AF Zoom-Nikkor 35-135mm f/3.5-4.5 N"; + lenses["1A 54 44 44 18 18 11 00"] = "AF Nikkor 35mm f/2"; + lenses["1B 44 5E 8E 34 3C 10 00"] = "AF Zoom-Nikkor 75-300mm f/4.5-5.6"; + lenses["1C 48 30 30 24 24 12 00"] = "AF Nikkor 20mm f/2.8"; + lenses["1D 42 44 5C 2A 34 12 00"] = "AF Zoom-Nikkor 35-70mm f/3.3-4.5 N"; + lenses["1E 54 56 56 24 24 13 00"] = "AF Micro-Nikkor 60mm f/2.8"; + lenses["1E 5D 64 64 20 20 13 00"] = "Unknown 90mm f/2.5"; + lenses["1F 54 6A 6A 24 24 14 00"] = "AF Micro-Nikkor 105mm f/2.8"; + lenses["20 3C 80 98 3D 3D 1E 02"] = "Tamron AF200-400mm f/5.6 LD IF"; + lenses["20 48 60 80 24 24 15 00"] = "AF Zoom-Nikkor ED 80-200mm f/2.8"; + lenses["21 40 3C 5C 2C 34 16 00"] = "AF Zoom-Nikkor 28-70mm f/3.5-4.5"; + lenses["22 48 72 72 18 18 16 00"] = "AF DC-Nikkor 135mm f/2"; + lenses["23 30 BE CA 3C 48 17 00"] = "Zoom-Nikkor 1200-1700mm f/5.6-8 P ED IF"; + lenses["24 44 60 98 34 3C 1A 02"] = "Tokina AT-X 840 AF II 80-400mm F4.5-5.6"; + lenses["24 48 60 80 24 24 1A 02"] = "AF Zoom-Nikkor ED 80-200mm f/2.8D"; + lenses["25 48 3C 5C 24 24 1B 02"] = "Tokina AT-X 287 AF PRO SV 28-70mm F2.8"; + lenses["25 48 44 5C 24 24 1B 02"] = "AF Zoom-Nikkor 35-70mm f/2.8D"; + lenses["25 48 44 5C 24 24 52 02"] = "AF Zoom-Nikkor 35-70mm f/2.8D"; + lenses["26 3C 54 80 30 3C 1C 06"] = "Sigma 55-200mm F4-5.6 DC"; + lenses["26 3C 5C 82 30 3C 1C 02"] = "Sigma 70-210mm F4-5.6 UC-II"; + lenses["26 3C 5C 8E 30 3C 1C 02"] = "Sigma 70-300mm F4-5.6 DG Macro"; + lenses["26 3D 3C 80 2F 3D 1C 02"] = "Sigma 28-300mm F3.8-5.6 Aspherical"; + lenses["26 3E 3C 6A 2E 3C 1C 02"] = "Sigma 28-105mm F3.8-5.6 UC-III Aspherical IF"; + lenses["26 40 27 3F 2C 34 1C 02"] = "Sigma 15-30mm F3.5-4.5 EX Aspherical DG DF"; + lenses["26 40 2D 44 2B 34 1C 02"] = "Sigma 18-35 F3.5-4.5 Aspherical"; + lenses["26 40 2D 50 2C 3C 1C 06"] = "Sigma 18-50mm F3.5-5.6 DC"; + lenses["26 40 2D 70 2B 3C 1C 06"] = "Sigma 18-125mm F3.5-5.6 DC"; + lenses["26 40 2D 80 2C 40 1C 06"] = "Sigma 18-200mm F3.5-6.3 DC"; + lenses["26 40 37 5C 2C 3C 1C 02"] = "Sigma 24-70mm F3.5-5.6 Aspherical HF"; + lenses["26 40 3C 60 2C 3C 1C 02"] = "Sigma 28-80mm F3.5-5.6 Mini Zoom Macro II Aspherical"; + lenses["26 40 3C 65 2C 3C 1C 02"] = "Sigma 28-90mm F3.5-5.6 Macro"; + lenses["26 40 3C 80 2B 3C 1C 02"] = "Sigma 28-200mm F3.5-5.6 Compact Aspherical Hyperzoom Macro"; + lenses["26 40 3C 80 2C 3C 1C 02"] = "Sigma 28-200mm F3.5-5.6 Compact Aspherical Hyperzoom Macro"; + lenses["26 40 3C 8E 2C 40 1C 02"] = "Sigma 28-300mm F3.5-6.3 Macro"; + lenses["26 40 7B A0 34 40 1C 02"] = "Sigma APO 170-500mm F5-6.3 Aspherical RF"; + lenses["26 41 3C 8E 2C 40 1C 02"] = "Sigma 28-300mm F3.5-6.3 DG Macro"; + lenses["26 44 73 98 34 3C 1C 02"] = "Sigma 135-400mm F4.5-5.6 APO Aspherical"; + lenses["26 48 11 11 30 30 1C 02"] = "Sigma 8mm F4 EX Circular Fisheye"; + lenses["26 48 27 27 24 24 1C 02"] = "Sigma 15mm F2.8 EX Diagonal Fish-Eye"; + lenses["26 48 2D 50 24 24 1C 06"] = "Sigma 18-50mm F2.8 EX DC"; + lenses["26 48 31 49 24 24 1C 02"] = "Sigma 20-40mm F2.8"; + lenses["26 48 37 56 24 24 1C 02"] = "Sigma 24-60mm F2.8 EX DG"; + lenses["26 48 3C 5C 24 24 1C 06"] = "Sigma 28-70mm F2.8 EX DG"; + lenses["26 48 3C 5C 24 30 1C 02"] = "Sigma 28-70mm F2.8-4 High Speed Zoom"; + lenses["26 48 3C 6A 24 30 1C 02"] = "Sigma 28-105mm F2.8-4 Aspherical"; + lenses["26 48 8E 8E 30 30 1C 02"] = "Sigma APO TELE MACRO 300mm F4"; + lenses["26 54 2B 44 24 30 1C 02"] = "Sigma 17-35mm F2.8-4 EX Aspherical"; + lenses["26 54 37 5C 24 24 1C 02"] = "Sigma 24-70mm F2.8 EX DG Macro"; + lenses["26 54 37 73 24 34 1C 02"] = "Sigma 24-135mm F2.8-4.5"; + lenses["26 54 3C 5C 24 24 1C 02"] = "Sigma 28-70mm F2.8 EX"; + lenses["26 58 31 31 14 14 1C 02"] = "Sigma 20mm F1.8 EX Aspherical DG DF RF"; + lenses["26 58 37 37 14 14 1C 02"] = "Sigma 24mm F1.8 EX Aspherical DG DF MACRO"; + lenses["26 58 3C 3C 14 14 1C 02"] = "Sigma 28mm F1.8 EX DG DF"; + lenses["27 48 8E 8E 24 24 1D 02"] = "AF-I Nikkor 300mm f/2.8D IF-ED"; + lenses["27 48 8E 8E 24 24 E1 02"] = "AF-I Nikkor 300mm f/2.8D IF-ED + TC-17E"; + lenses["27 48 8E 8E 24 24 F1 02"] = "AF-I Nikkor 300mm f/2.8D IF-ED + TC-14E"; + lenses["27 48 8E 8E 24 24 F2 02"] = "AF-I Nikkor 300mm f/2.8D IF-ED + TC-20E"; + lenses["28 3C A6 A6 30 30 1D 02"] = "AF-I Nikkor 600mm f/4D IF-ED"; + lenses["28 3C A6 A6 30 30 E1 02"] = "AF-I Nikkor 600mm f/4D IF-ED + TC-17E"; + lenses["28 3C A6 A6 30 30 F1 02"] = "AF-I Nikkor 600mm f/4D IF-ED + TC-14E"; + lenses["28 3C A6 A6 30 30 F2 02"] = "AF-I Nikkor 600mm f/4D IF-ED + TC-20E"; + lenses["2A 54 3C 3C 0C 0C 26 02"] = "AF Nikkor 28mm f/1.4D"; + lenses["2B 3C 44 60 30 3C 1F 02"] = "AF Zoom-Nikkor 35-80mm f/4-5.6D"; + lenses["2C 48 6A 6A 18 18 27 02"] = "AF DC-Nikkor 105mm f/2D"; + lenses["2D 48 80 80 30 30 21 02"] = "AF Micro-Nikkor 200mm f/4D IF-ED"; + lenses["2E 48 5C 82 30 3C 28 02"] = "AF Nikkor 70-210mm f/4-5.6D"; + lenses["2F 40 30 44 2C 34 29 02"] = "Unknown 20-35mm f/3.5-4.5D"; + lenses["2F 48 30 44 24 24 29 02"] = "Tokina AT-X 235 AF PRO - AF 20-35mm f/2.8"; + lenses["30 48 98 98 24 24 24 02"] = "AF-I Nikkor 400mm f/2.8D IF-ED"; + lenses["30 48 98 98 24 24 E1 02"] = "AF-I Nikkor 400mm f/2.8D IF-ED + TC-17E"; + lenses["30 48 98 98 24 24 F1 02"] = "AF-I Nikkor 400mm f/2.8D IF-ED + TC-14E"; + lenses["30 48 98 98 24 24 F2 02"] = "AF-I Nikkor 400mm f/2.8D IF-ED + TC-20E"; + lenses["31 54 56 56 24 24 25 02"] = "AF Micro-Nikkor 60mm f/2.8D"; + lenses["32 53 64 64 24 24 35 02"] = "Tamron SP AF90mm f/2.8 Di Macro 1:2 (272E)"; + lenses["32 54 50 50 24 24 35 02"] = "Sigma 50mm F2.8 EX DG Macro"; + lenses["32 54 6A 6A 24 24 35 02"] = "AF Micro-Nikkor 105mm f/2.8D"; + lenses["33 48 2D 2D 24 24 31 02"] = "AF Nikkor 18mm f/2.8D"; + lenses["33 54 3C 5E 24 24 62 02"] = "Tamron SP AF28-75mm f/2.8 XR Di LD Aspherical (IF) Macro"; + lenses["34 48 29 29 24 24 32 02"] = "AF Fisheye Nikkor 16mm f/2.8D"; + lenses["35 3C A0 A0 30 30 33 02"] = "AF-I Nikkor 500mm f/4D IF-ED"; + lenses["35 3C A0 A0 30 30 E1 02"] = "AF-I Nikkor 500mm f/4D IF-ED + TC-17E"; + lenses["35 3C A0 A0 30 30 F1 02"] = "AF-I Nikkor 500mm f/4D IF-ED + TC-14E"; + lenses["35 3C A0 A0 30 30 F2 02"] = "AF-I Nikkor 500mm f/4D IF-ED + TC-20E"; + lenses["36 48 37 37 24 24 34 02"] = "AF Nikkor 24mm f/2.8D"; + lenses["37 48 30 30 24 24 36 02"] = "AF Nikkor 20mm f/2.8D"; + lenses["38 4C 62 62 14 14 37 02"] = "AF Nikkor 85mm f/1.8D"; + lenses["3A 40 3C 5C 2C 34 39 02"] = "AF Zoom-Nikkor 28-70mm f/3.5-4.5D"; + lenses["3B 48 44 5C 24 24 3A 02"] = "AF Zoom-Nikkor 35-70mm f/2.8D N"; + lenses["3C 48 60 80 24 24 3B 02"] = "AF Zoom-Nikkor 80-200mm f/2.8D ED"; + lenses["3D 3C 44 60 30 3C 3E 02"] = "AF Zoom-Nikkor 35-80mm f/4-5.6D"; + lenses["3E 48 3C 3C 24 24 3D 02"] = "AF Nikkor 28mm f/2.8D"; + lenses["3F 40 44 6A 2C 34 45 02"] = "AF Zoom-Nikkor 35-105mm f/3.5-4.5D"; + lenses["41 48 7C 7C 24 24 43 02"] = "AF Nikkor 180mm f/2.8D IF-ED"; + lenses["42 54 44 44 18 18 44 02"] = "AF Nikkor 35mm f/2D"; + lenses["43 54 50 50 0C 0C 46 02"] = "AF Nikkor 50mm f/1.4D"; + lenses["44 44 60 80 34 3C 47 02"] = "AF Zoom-Nikkor 80-200mm f/4.5-5.6D "; + lenses["45 3D 3C 60 2C 3C 48 02"] = "Tamron AF28-80mm f/3.5-5.6 Aspherical"; + lenses["45 40 3C 60 2C 3C 48 02"] = "AF Zoom-Nikkor 28-80mm F/3.5-5.6D"; + lenses["45 41 37 72 2C 3C 48 02"] = "Tamron SP AF24-135mm f/3.5-5.6 AD Aspherical (IF) Macro"; + lenses["46 3C 44 60 30 3C 49 02"] = "AF Zoom-Nikkor 35-80mm f/4-5.6D N"; + lenses["47 42 37 50 2A 34 4A 02"] = "AF Zoom-Nikkor 24-50mm f/3.3-4.5D"; + lenses["48 38 1F 37 34 3C 4B 06"] = "Sigma 12-24mm F4.5-5.6 EX Aspherical DG HSM"; + lenses["48 3C 19 31 30 3C 4B 06"] = "Sigma 10-20mm F4-5.6 EX DC HSM"; + lenses["48 3C 50 A0 30 40 4B 02"] = "Sigma 50-500mm F4-6.3 EX APO RF HSM"; + lenses["48 3C 8E B0 3C 3C 4B 02"] = "Sigma APO 300-800 F5.6 EX DG HSM"; + lenses["48 3C B0 B0 3C 3C 4B 02"] = "Sigma APO 800mm F5.6 EX HSM"; + lenses["48 44 A0 A0 34 34 4B 02"] = "Sigma APO 500mm F4.5 EX HSM"; + lenses["48 48 24 24 24 24 4B 02"] = "Sigma 14mm F2.8 EX Aspherical HSM"; + lenses["48 48 2B 44 24 30 4B 06"] = "Sigma 17-35mm F2.8-4 EX DG Aspherical HSM"; + lenses["48 48 68 8E 30 30 4B 02"] = "Sigma 100-300mm F4 EX IF HSM"; + lenses["48 48 76 76 24 24 4B 06"] = "Sigma 150mm F2.8 EX DG APO Macro HSM"; + lenses["48 48 8E 8E 24 24 4B 02"] = "AF-S Nikkor 300mm f/2.8D IF-ED"; + lenses["48 48 8E 8E 24 24 E1 02"] = "AF-S Nikkor 300mm f/2.8D IF-ED + TC-17E"; + lenses["48 48 8E 8E 24 24 F1 02"] = "AF-S Nikkor 300mm f/2.8D IF-ED + TC-14E"; + lenses["48 48 8E 8E 24 24 F2 02"] = "AF-S Nikkor 300mm f/2.8D IF-ED + TC-20E"; + lenses["48 4C 7C 7C 2C 2C 4B 02"] = "Sigma 180mm F3.5 EX DG Macro"; + lenses["48 4C 7D 7D 2C 2C 4B 02"] = "Sigma APO MACRO 180mm F3.5 EX DG HSM"; + lenses["48 54 3E 3E 0C 0C 4B 06"] = "Sigma 30mm F1.4 EX DC HSM"; + lenses["48 54 5C 80 24 24 4B 02"] = "Sigma 70-200mm F2.8 EX APO IF HSM"; + lenses["48 54 6F 8E 24 24 4B 02"] = "Sigma APO 120-300mm F2.8 EX DG HSM"; + lenses["48 54 8E 8E 24 24 4B 02"] = "Sigma APO 300mm F2.8 EX DG HSM"; + lenses["49 3C A6 A6 30 30 4C 02"] = "AF-S Nikkor 600mm f/4D IF-ED"; + lenses["49 3C A6 A6 30 30 E1 02"] = "AF-S Nikkor 600mm f/4D IF-ED + TC-17E"; + lenses["49 3C A6 A6 30 30 F1 02"] = "AF-S Nikkor 600mm f/4D IF-ED + TC-14E"; + lenses["49 3C A6 A6 30 30 F2 02"] = "AF-S Nikkor 600mm f/4D IF-ED + TC-20E"; + lenses["4A 54 62 62 0C 0C 4D 02"] = "AF Nikkor 85mm f/1.4D IF"; + lenses["4B 3C A0 A0 30 30 4E 02"] = "AF-S Nikkor 500mm f/4D IF-ED"; + lenses["4B 3C A0 A0 30 30 E1 02"] = "AF-S Nikkor 500mm f/4D IF-ED + TC-17E"; + lenses["4B 3C A0 A0 30 30 F1 02"] = "AF-S Nikkor 500mm f/4D IF-ED + TC-14E"; + lenses["4B 3C A0 A0 30 30 F2 02"] = "AF-S Nikkor 500mm f/4D IF-ED + TC-20E"; + lenses["4C 40 37 6E 2C 3C 4F 02"] = "AF Zoom-Nikkor 24-120mm f/3.5-5.6D IF"; + lenses["4D 40 3C 80 2C 3C 62 02"] = "AF Zoom-Nikkor 28-200mm f/3.5-5.6D IF"; + lenses["4D 41 3C 8E 2B 40 62 02"] = "Tamron AF28-300mm f/3.5-6.3 XR Di LD Aspherical (IF)"; + lenses["4D 41 3C 8E 2C 40 62 02"] = "Tamron AF28-300mm f/3.5-6.3 XR LD Aspherical (IF)"; + lenses["4E 48 72 72 18 18 51 02"] = "AF DC-Nikkor 135mm f/2D"; + lenses["4F 40 37 5C 2C 3C 53 06"] = "IX-Nikkor 24-70mm f/3.5-5.6"; + lenses["50 48 56 7C 30 3C 54 06"] = "IX-Nikkor 60-180mm f/4-5.6"; + lenses["53 48 60 80 24 24 57 02"] = "AF Zoom-Nikkor 80-200mm f/2.8D ED"; + lenses["53 48 60 80 24 24 60 02"] = "AF Zoom-Nikkor 80-200mm f/2.8D ED"; + lenses["54 44 5C 7C 34 3C 58 02"] = "AF Zoom-Micro Nikkor 70-180mm f/4.5-5.6D ED"; + lenses["56 3C 5C 8E 30 3C 1C 02"] = "Sigma 70-300mm F4-5.6 APO Macro Super II"; + lenses["56 48 5C 8E 30 3C 5A 02"] = "AF Zoom-Nikkor 70-300mm f/4-5.6D ED"; + lenses["59 48 98 98 24 24 5D 02"] = "AF-S Nikkor 400mm f/2.8D IF-ED"; + lenses["59 48 98 98 24 24 E1 02"] = "AF-S Nikkor 400mm f/2.8D IF-ED + TC-17E"; + lenses["59 48 98 98 24 24 F1 02"] = "AF-S Nikkor 400mm f/2.8D IF-ED + TC-14E"; + lenses["59 48 98 98 24 24 F2 02"] = "AF-S Nikkor 400mm f/2.8D IF-ED + TC-20E"; + lenses["5A 3C 3E 56 30 3C 5E 06"] = "IX-Nikkor 30-60mm f/4-5.6"; + lenses["5B 44 56 7C 34 3C 5F 06"] = "IX-Nikkor 60-180mm f/4.5-5.6"; + lenses["5D 48 3C 5C 24 24 63 02"] = "AF-S Zoom-Nikkor 28-70mm f/2.8D IF-ED"; + lenses["5E 48 60 80 24 24 64 02"] = "AF-S Zoom-Nikkor 80-200mm f/2.8D IF-ED"; + lenses["5F 40 3C 6A 2C 34 65 02"] = "AF Zoom-Nikkor 28-105mm f/3.5-4.5D IF"; + lenses["60 40 3C 60 2C 3C 66 02"] = "AF Zoom-Nikkor 28-80mm f/3.5-5.6D"; + lenses["61 44 5E 86 34 3C 67 02"] = "AF Zoom-Nikkor 75-240mm f/4.5-5.6D"; + lenses["63 48 2B 44 24 24 68 02"] = "AF-S Nikkor 17-35mm f/2.8D IF-ED"; + lenses["64 00 62 62 24 24 6A 02"] = "PC Micro-Nikkor 85mm f/2.8D"; + lenses["65 44 60 98 34 3C 6B 0A"] = "AF VR Zoom-Nikkor 80-400mm f/4.5-5.6D ED"; + lenses["66 40 2D 44 2C 34 6C 02"] = "AF Zoom-Nikkor 18-35mm f/3.5-4.5D IF-ED"; + lenses["67 48 37 62 24 30 6D 02"] = "AF Zoom-Nikkor 24-85mm f/2.8-4D IF"; + lenses["67 54 37 5C 24 24 1C 02"] = "Sigma 24-70mm F2.8 EX DG Macro"; + lenses["68 42 3C 60 2A 3C 6E 06"] = "AF Zoom-Nikkor 28-80mm f/3.3-5.6G"; + lenses["69 48 5C 8E 30 3C 6F 02"] = "Tamron AF70-300mm f/4-5.6 LD Macro 1:2"; + lenses["69 48 5C 8E 30 3C 6F 06"] = "AF Zoom-Nikkor 70-300mm f/4-5.6G"; + lenses["6A 48 8E 8E 30 30 70 02"] = "AF-S Nikkor 300mm f/4D IF-ED"; + lenses["6B 48 24 24 24 24 71 02"] = "AF Nikkor ED 14mm f/2.8D"; + lenses["6D 48 8E 8E 24 24 73 02"] = "AF-S Nikkor 300mm f/2.8D IF-ED II"; + lenses["6E 48 98 98 24 24 74 02"] = "AF-S Nikkor 400mm f/2.8D IF-ED II"; + lenses["6F 3C A0 A0 30 30 75 02"] = "AF-S Nikkor 500mm f/4D IF-ED II"; + lenses["70 3C A6 A6 30 30 76 02"] = "AF-S Nikkor 600mm f/4D IF-ED II"; + lenses["72 48 4C 4C 24 24 77 00"] = "Nikkor 45mm f/2.8 P"; + lenses["74 40 37 62 2C 34 78 06"] = "AF-S Zoom-Nikkor 24-85mm f/3.5-4.5G IF-ED"; + lenses["75 40 3C 68 2C 3C 79 06"] = "AF Zoom-Nikkor 28-100mm f/3.5-5.6G"; + lenses["76 58 50 50 14 14 7A 02"] = "AF Nikkor 50mm f/1.8D"; + lenses["77 44 61 98 34 3C 7B 0E"] = "Sigma 80-400mm f4.5-5.6 EX OS"; + lenses["77 48 5C 80 24 24 7B 0E"] = "AF-S VR Zoom-Nikkor 70-200mm f/2.8G IF-ED"; + lenses["78 40 37 6E 2C 3C 7C 0E"] = "AF-S VR Zoom-Nikkor 24-120mm f/3.5-5.6G IF-ED"; + lenses["79 40 11 11 2C 2C 1C 06"] = "Sigma 8mm F3.5 EX"; + lenses["79 40 3C 80 2C 3C 7F 06"] = "AF Zoom-Nikkor 28-200mm f/3.5-5.6G IF-ED"; + lenses["79 48 5C 5C 24 24 1C 06"] = "Sigma 70mm F2.8 EX DG Macro"; + lenses["7A 3B 53 80 30 3C 4B 06"] = "Sigma 55-200mm F4-5.6 DC HSM"; + lenses["7A 3C 1F 37 30 30 7E 06"] = "AF-S DX Zoom-Nikkor 12-24mm f/4G IF-ED"; + lenses["7A 40 2D 50 2C 3C 4B 06"] = "Sigma 18-50mm F3.5-5.6 DC HSM"; + lenses["7A 47 2B 5C 24 34 4B 06"] = "Sigma 17-70mm F2.8-4.5 DC Macro Asp. IF HSM"; + lenses["7A 47 50 76 24 24 4B 06"] = "Sigma APO 50-150mm F2.8 EX DC HSM"; + lenses["7A 48 2B 5C 24 34 4B 06"] = "Sigma 17-70mm F2.8-4.5 DC Macro Asp. IF HSM"; + lenses["7A 48 2D 50 24 24 4B 06"] = "Sigma 18-50mm F2.8 EX DC HSM"; + lenses["7A 48 5C 80 24 24 4B 06"] = "Sigma 70-200mm F2.8 EX APO DG Macro HSM II"; + lenses["7A 54 6E 8E 24 24 4B 02"] = "Sigma APO 120-300mm F2.8 EX DG HSM"; + lenses["7B 48 80 98 30 30 80 0E"] = "AF-S VR Zoom-Nikkor 200-400mm f/4G IF-ED"; + lenses["7D 48 2B 53 24 24 82 06"] = "AF-S DX Zoom-Nikkor 17-55mm f/2.8G IF-ED"; + lenses["7F 40 2D 5C 2C 34 84 06"] = "AF-S DX Zoom-Nikkor 18-70mm f/3.5-4.5G IF-ED"; + lenses["7F 48 2B 5C 24 34 1C 06"] = "Sigma 17-70mm F2.8-4.5 DC Macro Asp. IF"; + lenses["7F 48 2D 50 24 24 1C 06"] = "Sigma 18-50mm F2.8 EX DC Macro"; + lenses["80 48 1A 1A 24 24 85 06"] = "AF DX Fisheye-Nikkor 10.5mm f/2.8G ED"; + lenses["81 54 80 80 18 18 86 0E"] = "AF-S VR Nikkor 200mm f/2G IF-ED"; + lenses["82 48 8E 8E 24 24 87 0E"] = "AF-S VR Nikkor 300mm f/2.8G IF-ED"; + lenses["89 3C 53 80 30 3C 8B 06"] = "AF-S DX Zoom-Nikkor 55-200mm f/4-5.6G ED"; + lenses["8A 54 6A 6A 24 24 8C 0E"] = "AF-S VR Micro-Nikkor 105mm f/2.8G IF-ED"; + lenses["8B 40 2D 80 2C 3C 8D 0E"] = "AF-S DX VR Zoom-Nikkor 18-200mm f/3.5-5.6G IF-ED"; + lenses["8B 40 2D 80 2C 3C FD 0E"] = "AF-S DX VR Zoom-Nikkor 18-200mm f/3.5-5.6G IF-ED"; + lenses["8C 40 2D 53 2C 3C 8E 06"] = "AF-S DX Zoom-Nikkor 18-55mm f/3.5-5.6G ED"; + lenses["8D 44 5C 8E 34 3C 8F 0E"] = "AF-S VR Zoom-Nikkor 70-300mm f/4.5-5.6G IF-ED"; + lenses["8F 40 2D 72 2C 3C 91 06"] = "AF-S DX Zoom-Nikkor 18-135mm f/3.5-5.6G IF-ED"; + lenses["90 3B 53 80 30 3C 92 0E"] = "AF-S DX VR Zoom-Nikkor 55-200mm f/4-5.6G IF-ED"; + lenses["92 48 24 37 24 24 94 06"] = "AF-S Zoom-Nikkor 14-24mm f/2.8G ED"; + lenses["93 48 37 5C 24 24 95 06"] = "AF-S Zoom-Nikkor 24-70mm f/2.8G ED"; + lenses["94 40 2D 53 2C 3C 96 06"] = "AF-S DX Zoom-Nikkor 18-55mm f/3.5-5.6G ED II"; + lenses["95 00 37 37 2C 2C 97 06"] = "PC-E Nikkor 24mm f/3.5D ED"; + lenses["95 4C 37 37 2C 2C 97 02"] = "PC-E Nikkor 24mm f/3.5D ED"; + lenses["96 48 98 98 24 24 98 0E"] = "AF-S VR Nikkor 400mm f/2.8G ED"; + lenses["97 3C A0 A0 30 30 99 0E"] = "AF-S VR Nikkor 500mm f/4G ED"; + lenses["98 3C A6 A6 30 30 9A 0E"] = "AF-S VR Nikkor 600mm f/4G ED"; + lenses["99 40 29 62 2C 3C 9B 0E"] = "AF-S DX VR Zoom-Nikkor 16-85mm f/3.5-5.6G ED"; + lenses["9A 40 2D 53 2C 3C 9C 0E"] = "AF-S DX VR Zoom-Nikkor 18-55mm f/3.5-5.6G"; + lenses["9B 00 4C 4C 24 24 9D 06"] = "PC-E Micro Nikkor 45mm f/2.8D ED"; + lenses["9B 54 4C 4C 24 24 9D 02"] = "PC-E Micro Nikkor 45mm f/2.8D ED"; + lenses["9C 54 56 56 24 24 9E 06"] = "AF-S Micro Nikkor 60mm f/2.8G ED"; + lenses["9D 00 62 62 24 24 9F 06"] = "PC-E Micro Nikkor 85mm f/2.8D"; + lenses["9D 54 62 62 24 24 9F 02"] = "PC-E Micro Nikkor 85mm f/2.8D"; + lenses["9E 40 2D 6A 2C 3C A0 0E"] = "AF-S DX VR Zoom-Nikkor 18-105mm f/3.5-5.6G ED"; + lenses["9F 58 44 44 14 14 A1 06"] = "AF-S DX Nikkor 35mm f/1.8G"; + lenses["A0 54 50 50 0C 0C A2 06"] = "AF-S Nikkor 50mm f/1.4G"; + lenses["A1 40 18 37 2C 34 A3 06"] = "AF-S DX Nikkor 10-24mm f/3.5-4.5G ED"; + lenses["A1 41 19 31 2C 2C 4B 06"] = "Sigma 10-20mm F3.5 EX DC HSM"; + lenses["A2 48 5C 80 24 24 A4 0E"] = "AF-S Nikkor 70-200mm f/2.8G ED VR II"; + lenses["A5 40 2D 88 2C 40 4B 0E"] = "Sigma 18-250mm F3.5-6.3 DC OS HSM"; + lenses["A6 48 37 5C 24 24 4B 06"] = "Sigma 24-70mm F2.8 IF EX DG HSM"; + lenses["B6 48 37 56 24 24 1C 02"] = "Sigma 24-60mm F2.8 EX DG"; + lenses["CD 3D 2D 70 2E 3C 4B 0E"] = "Sigma 18-125mm F3.8-5.6 DC OS HSM"; + lenses["CE 34 76 A0 38 40 4B 0E"] = "Sigma 150-500mm F5-6.3 DG OS APO HSM"; + lenses["CF 38 6E 98 34 3C 4B 0E"] = "Sigma APO 120-400mm F4.5-5.6 DG OS HSM"; + lenses["DC 48 19 19 24 24 4B 06"] = "Sigma 10mm F2.8 EX DC HSM Fisheye"; + lenses["DE 54 50 50 0C 0C 4B 06"] = "Sigma 50mm F1.4 EX DG HSM"; + lenses["E0 3C 5C 8E 30 3C 4B 06"] = "Sigma 70-300mm F4-5.6 APO DG Macro HSM"; + lenses["E1 58 37 37 14 14 1C 02"] = "Sigma 24mm F1.8 EX DG Aspherical Macro"; + lenses["E5 54 6A 6A 24 24 35 02"] = "Sigma Macro 105mm F2.8 EX DG"; + lenses["E9 54 37 5C 24 24 1C 02"] = "Sigma 24-70mm F2.8 EX DG Macro"; + lenses["ED 40 2D 80 2C 40 4B 0E"] = "Sigma 18-200mm F3.5-6.3 DC OS HSM"; + lenses["EE 48 5C 80 24 24 4B 06"] = "Sigma 70-200mm F2.8 EX APO DG Macro HSM II"; + lenses["F0 38 1F 37 34 3C 4B 06"] = "Sigma 12-24mm F4.5-5.6 EX DG Aspherical HSM"; + lenses["F3 54 2B 50 24 24 84 0E"] = "Tamron SP AF 17-50mm F/2.8 XR Di II VC LD Aspherical (IF) (B005)"; + lenses["F4 54 56 56 18 18 84 06"] = "Tamron SP AF 60mm f/2.0 Di II Macro 1:1 (G005)"; + lenses["F5 40 2C 8A 2C 40 40 0E"] = "Tamron AF 18-270mm f/3.5-6.3 Di II VC LD Aspherical (IF) Macro (B003)"; + lenses["F5 48 76 76 24 24 4B 06"] = "Sigma 150mm F2.8 EX DG APO Macro HSM"; + lenses["F6 3F 18 37 2C 34 84 06"] = "Tamron SP AF 10-24mm f/3.5-4.5 Di II LD Aspherical (IF) (B001)"; + lenses["F7 53 5C 80 24 24 84 06"] = "Tamron SP AF 70-200mm f/2.8 Di LD (IF) Macro (A001)"; + lenses["F8 54 3E 3E 0C 0C 4B 06"] = "Sigma 30mm F1.4 EX DC HSM"; + lenses["F8 55 64 64 24 24 84 06"] = "Tamron SP AF 90mm f/2.8 Di Macro 1:1 (272NII)"; + lenses["F9 3C 19 31 30 3C 4B 06"] = "Sigma 10-20mm F4-5.6 EX DC HSM"; + lenses["F9 40 3C 8E 2C 40 40 0E"] = "Tamron AF 28-300mm f/3.5-6.3 XR Di VC LD Aspherical (IF) Macro (A20)"; + lenses["FA 54 3C 5E 24 24 84 06"] = "Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical (IF) Macro (A09NII)"; + lenses["FB 54 8E 8E 24 24 4B 02"] = "Sigma APO 300mm F2.8 EX DG HSM"; + lenses["FD 47 50 76 24 24 4B 06"] = "Sigma 50-150mm F2.8 EX APO DC HSM II"; + lenses["FE 47 00 00 24 24 4B 06"] = "Sigma 4.5mm F2.8 EX DC Circular Fisheye HSM"; + } + virtual std::string toString (Tag* t) { + + static const unsigned char xlat[2][256] = { + { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d, + 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d, + 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f, + 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f, + 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1, + 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17, + 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89, + 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f, + 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b, + 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb, + 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3, + 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f, + 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35, + 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43, + 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5, + 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 }, + { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c, + 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34, + 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad, + 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05, + 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee, + 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d, + 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b, + 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b, + 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc, + 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33, + 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8, + 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6, + 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c, + 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49, + 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb, + 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } }; + + int ver = (t->toInt (0, BYTE) - '0') * 1000 + (t->toInt (1, BYTE) - '0') * 100 + (t->toInt (2, BYTE) - '0') * 10 + (t->toInt (3, BYTE) - '0'); + + std::ostringstream ld; + ld << "Version = " << ver << std::endl; + + int lenstype = t->getParent()->getTag(0x0083)->toInt(0,BYTE); + + std::ostringstream lid; + lid.setf (std::ios_base::hex, std::ios_base::basefield); + lid.setf (std::ios_base::uppercase); + + std::string model = t->getParent()->getParent()->getParent()->getTag(0x0110)->valueToString(); + int lidoffs = 7; + bool d100 = false; + if (model.substr(0,10)=="NIKON D100" || model.substr(0,9)=="NIKON D1X") { + lidoffs = 0; + d100 = true; + } + + unsigned char buffer[15]; + if (d100) + memcpy (buffer, t->getValue()+6, 7); + else + memcpy (buffer, t->getValue()+4, 15); + + if (ver>=201) { + const unsigned char* serval = t->getParent()->getTag(0x001d)->getValue (); + int serial = 0; + for (int i=0; serval[i]; i++) + serial = serial*10 + (isdigit(serval[i]) ? serval[i] - '0' : serval[i] % 10); + const unsigned char* scval = t->getParent()->getTag(0x00a7)->getValue (); + int key = 0; + for (int i=0; i<4; i++) + key ^= scval[i]; + + unsigned char ci = xlat[0][serial & 0xff]; + unsigned char cj = xlat[1][key]; + unsigned char ck = 0x60; + for (int i=0; i < 15; i++) + buffer[i] ^= (cj += ci * ck++); + } + + if (!d100) { + ld << "ExitPupilPosition = " << (int) buffer[0] << std::endl; + ld << "AFAperture = " << (int) buffer[1] << std::endl; + ld << "FocusPosition = " << (int) buffer[4] << std::endl; + ld << "FocusDistance = " << (int) buffer[5] << std::endl; + ld << "FocalLength = " << (int) buffer[6] << std::endl; + ld << "EffectiveMaxAperture = " << (int) buffer[14] << std::endl; + } + + for (int i=0; i<7; i++) + lid << std::setw(2) << std::setfill('0') << (int)buffer[lidoffs+i] << ' '; + lid << std::setw(2) << std::setfill('0') << lenstype; + + std::map::iterator r = lenses.find (lid.str()); + if (r!=lenses.end()) + ld << "Lens = " << r->second; + else + ld << "Lens = Unknown, ID=" << lid.str(); + + return ld.str(); + } + +}; +NALensDataInterpreter naLensDataInterpreter; + +const TagAttrib nikon2Attribs[] = { + 0, 1, 0, 0, 0x0002, "Unknown", &stdInterpreter, + 0, 1, 0, 0, 0x0003, "Quality", &stdInterpreter, + 0, 1, 0, 0, 0x0004, "ColorMode", &stdInterpreter, + 0, 1, 0, 0, 0x0005, "ImageAdjustment", &stdInterpreter, + 0, 1, 0, 0, 0x0006, "ISOSpeed", &naISOInterpreter, + 0, 1, 0, 0, 0x0007, "WhiteBalance", &stdInterpreter, + 0, 1, 0, 0, 0x0008, "Focus", &stdInterpreter, + 0, 1, 0, 0, 0x0009, "Unknown", &stdInterpreter, + 0, 1, 0, 0, 0x000a, "DigitalZoom", &stdInterpreter, + 0, 1, 0, 0, 0x000b, "AuxiliaryLens", &stdInterpreter, + 0, 1, 0, 0, 0x0f00, "Unknown", &stdInterpreter, + -1, 0, 0, 0, 0, "", NULL}; + +const TagAttrib nikon3Attribs[] = { + 0, 1, 0, 0, 0x0001, "MakerNoteVersion", &stdInterpreter, + 0, 1, 0, 0, 0x0002, "ISOSpeed", &naISOInterpreter, + 0, 1, 0, 0, 0x0003, "ColorMode", &stdInterpreter, + 0, 1, 0, 0, 0x0004, "Quality", &stdInterpreter, + 0, 1, 0, 0, 0x0005, "WhiteBalance", &stdInterpreter, + 0, 1, 0, 0, 0x0006, "Sharpness", &stdInterpreter, + 0, 1, 0, 0, 0x0007, "FocusMode", &stdInterpreter, + 0, 1, 0, 0, 0x0008, "FlashSetting", &stdInterpreter, + 0, 1, 0, 0, 0x0009, "FlashType", &stdInterpreter, + 0, 1, 0, 0, 0x000b, "WhiteBalanceFineTune", &stdInterpreter, + 0, 3, 0, 0, 0x000c, "ColorBalance1", &stdInterpreter, + 0, 1, 0, 0, 0x000d, "ProgramShift", &stdInterpreter, + 0, 1, 0, 0, 0x000e, "ExposureDifference", &stdInterpreter, + 0, 1, 0, 0, 0x000f, "ISOSelection", &naISOInterpreter, + 0, 1, 0, 0, 0x0010, "DataDump", &stdInterpreter, + 1, 1, 0, 0, 0x0011, "NikonPreview", &stdInterpreter, + 0, 1, 0, 0, 0x0012, "FlashExposureComp", &stdInterpreter, + 0, 1, 0, 0, 0x0013, "ISOSetting", &stdInterpreter, + 0, 1, 0, 0, 0x0016, "ImageBoundary", &stdInterpreter, + 0, 1, 0, 0, 0x0018, "FlashExposureBracketValue", &stdInterpreter, + 0, 1, 0, 0, 0x0019, "ExposureBracketValue", &stdInterpreter, + 0, 1, 0, 0, 0x001a, "ImageProcessing", &stdInterpreter, + 0, 1, 0, 0, 0x001b, "CropHiSpeed", &stdInterpreter, + 0, 1, 0, 0, 0x001d, "SerialNumber", &stdInterpreter, + 0, 1, 0, 0, 0x001e, "ColorSpace", &stdInterpreter, + 0, 1, 0, 0, 0x0020, "ImageAuthentication", &stdInterpreter, + 0, 1, 0, 0, 0x0080, "ImageAdjustment", &stdInterpreter, + 0, 1, 0, 0, 0x0081, "ToneComp", &stdInterpreter, + 0, 1, 0, 0, 0x0082, "AuxiliaryLens", &stdInterpreter, + 0, 1, 0, 0, 0x0083, "LensType", &naLensTypeInterpreter, + 0, 1, 0, 0, 0x0084, "Lens", &stdInterpreter, + 0, 1, 0, 0, 0x0085, "ManualFocusDistance", &stdInterpreter, + 0, 1, 0, 0, 0x0086, "DigitalZoom", &stdInterpreter, + 0, 1, 0, 0, 0x0087, "FlashMode", &naFlashModeInterpreter, + 0, 1, 0, 0, 0x0088, "AFInfo", &naAFInfoInterpreter, + 0, 1, 0, 0, 0x0089, "ShootingMode", &naShootingModeInterpreter, + 0, 1, 0, 0, 0x008a, "AutoBracketRelease", &stdInterpreter, + 0, 1, 0, 0, 0x008b, "LensFStops", &stdInterpreter, + 0, 1, 0, 0, 0x008c, "NEFCurve1", &stdInterpreter, + 0, 1, 0, 0, 0x008d, "ColorHue", &stdInterpreter, + 0, 1, 0, 0, 0x008f, "SceneMode", &stdInterpreter, + 0, 1, 0, 0, 0x0090, "LightSource", &stdInterpreter, + 0, 1, 0, 0, 0x0091, "ShotInfo", &stdInterpreter, + 0, 1, 0, 0, 0x0092, "HueAdjustment", &stdInterpreter, + 0, 1, 0, 0, 0x0094, "Saturation", &stdInterpreter, + 0, 1, 0, 0, 0x0095, "NoiseReduction", &stdInterpreter, + 0, 1, 0, 0, 0x0096, "NEFCurve2", &stdInterpreter, + 0, 3, 0, 0, 0x0097, "ColorBalance", &stdInterpreter, + 0, 1, 0, 0, 0x0098, "LensData", &naLensDataInterpreter, + 0, 1, 0, 0, 0x0099, "RawImageCenter", &stdInterpreter, + 0, 1, 0, 0, 0x009a, "SensorPixelSize", &stdInterpreter, + 0, 1, 0, 0, 0x00a0, "SerialNumber", &stdInterpreter, + 0, 1, 0, 0, 0x00a2, "ImageDataSize", &stdInterpreter, + 0, 1, 0, 0, 0x00a5, "ImageCount", &stdInterpreter, + 0, 1, 0, 0, 0x00a6, "DeletedImageCount", &stdInterpreter, + 0, 1, 0, 0, 0x00a7, "ShutterCount", &stdInterpreter, + 0, 1, 0, 0, 0x00a9, "ImageOptimization", &stdInterpreter, + 0, 1, 0, 0, 0x00aa, "Saturation", &stdInterpreter, + 0, 1, 0, 0, 0x00ab, "VariProgram", &stdInterpreter, + 0, 1, 0, 0, 0x00ac, "ImageStabilization", &stdInterpreter, + 0, 1, 0, 0, 0x00ad, "AFResponse", &stdInterpreter, + 0, 1, 0, 0, 0x00b0, "MultiExposure", &stdInterpreter, + 0, 1, 0, 0, 0x00b1, "HighISONoiseReduction", &naHiISONRInterpreter, + 0, 1, 0, 0, 0x0e00, "PrintIM", &stdInterpreter, + 0, 0, 0, 0, 0x0e01, "NikonCaptureData", &stdInterpreter, + 0, 0, 0, 0, 0x0e09, "NikonCaptureVersion", &stdInterpreter, + 0, 0, 0, 0, 0x0e0e, "NikonCaptureOffsets", &stdInterpreter, + 0, 0, 0, 0, 0x0e10, "NikonScanIFD", &stdInterpreter, + -1, 0, 0, 0, 0, "", NULL}; + +} +#endif + diff --git a/rtexif/olympusattribs.cc b/rtexif/olympusattribs.cc new file mode 100644 index 000000000..079c8c259 --- /dev/null +++ b/rtexif/olympusattribs.cc @@ -0,0 +1,673 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _OLYMPUSATTRIBS_ +#define _OLYMPUSATTRIBS_ + +#include +#include +#include +#include +#include +#include + +namespace rtexif { + +class OLOnOffInterpreter : public Interpreter { + public: + OLOnOffInterpreter () {} + virtual std::string toString (Tag* t) { + if (t->toInt()==0) + return "Off"; + else + return "On"; + } +}; +OLOnOffInterpreter olOnOffInterpreter; + +class OLYesNoInterpreter : public Interpreter { + public: + OLYesNoInterpreter () {} + virtual std::string toString (Tag* t) { + if (t->toInt()==0) + return "No"; + else + return "Yes"; + } +}; +OLYesNoInterpreter olYesNoInterpreter; + +class OLApertureInterpreter : public Interpreter { + public: + OLApertureInterpreter () {} + virtual std::string toString (Tag* t) { + std::ostringstream str; + str.precision(2); + str << pow(2, t->toInt() / 512.0); + return str.str(); + } +}; +OLApertureInterpreter olApertureInterpreter; + +class OLLensTypeInterpreter : public Interpreter { + std::map lenses; + public: + OLLensTypeInterpreter () { + lenses[1] = "Zuiko Digital ED 50mm F2.0 Macro"; + lenses[1 +65536] = "Zuiko Digital 40-150mm F3.5-4.5"; + lenses[2] = "Zuiko Digital ED 150mm F2.0"; + lenses[3] = "Zuiko Digital ED 300mm F2.8"; + lenses[5] = "Zuiko Digital 14-54mm F2.8-3.5"; + lenses[5 +65536] = "Zuiko Digital Pro ED 90-250mm F2.8"; + lenses[6] = "Zuiko Digital ED 50-200mm F2.8-3.5"; + lenses[6 +65536] = "Zuiko Digital ED 8mm F3.5 Fisheye"; + lenses[7] = "Zuiko Digital 11-22mm F2.8-3.5"; + lenses[7 +65536] = "Zuiko Digital 18-180mm F3.5-6.3"; + lenses[8] = "Zuiko Digital 70-300mm F4.0-5.6"; + lenses[21] = "Zuiko Digital ED 7-14mm F4.0"; + lenses[23] = "Zuiko Digital Pro ED 35-100mm F2.0"; + lenses[24] = "Zuiko Digital 14-45mm F3.5-5.6"; + lenses[32] = "Zuiko Digital 35mm F3.5 Macro"; + lenses[34] = "Zuiko Digital 17.5-45mm F3.5-5.6"; + lenses[35] = "Zuiko Digital ED 14-42mm F3.5-5.6"; + lenses[36] = "Zuiko Digital ED 40-150mm F4.0-5.6"; + lenses[48] = "Zuiko Digital ED 50-200mm SWD F2.8-3.5"; + lenses[49] = "Zuiko Digital ED 12-60mm SWD F2.8-4.0"; + lenses[256+ 1] = "18-50mm F3.5-5.6"; + lenses[256+ 2] = "55-200mm F4.0-5.6 DC"; + lenses[256+ 3] = "18-125mm F3.5-5.6 DC"; + lenses[256+ 4] = "18-125mm F3.5-5.6"; + lenses[256+ 5] = "30mm F1.4"; + lenses[256+ 6] = "50-500mm F4.0-6.3 EX DG APO HSM RF"; + lenses[256+ 7] = "105mm F2.8 DG"; + lenses[256+ 8] = "150mm F2.8 DG HSM"; + lenses[256+ 17] = "135-400mm F4.5-5.6 DG ASP APO RF"; + lenses[256+ 18] = "300-800mm F5.6 EX DG APO"; + lenses[512+ 1] = "D Vario Elmarit 14-50mm, F2.8-3.5 Asph."; + lenses[512+ 2] = "D Summilux 25mm, F1.4 Asph."; + lenses[512+ 4] = "Vario Elmar 14-150mm f3.5-5.6"; + lenses[768+ 1] = "D Vario Elmarit 14-50mm, F2.8-3.5 Asph."; + lenses[768+ 2] = "D Summilux 25mm, F1.4 Asph."; + } + virtual std::string toString (Tag* t) { + int make = t->toInt(0); + int model = t->toInt(2); + int add = 0; + if (make==0 && (model==1 || model==5 || model==7 || model==6)) + add += 65536 * t->toInt(3); + return lenses [256 * make + model + add]; + } +}; +OLLensTypeInterpreter olLensTypeInterpreter; + +class OLFlashTypeInterpreter : public ChoiceInterpreter { + public: + OLFlashTypeInterpreter () { + choices[0] = "None"; + choices[2] = "Simple E-System"; + choices[3] = "E-System"; + } +}; +OLFlashTypeInterpreter olFlashTypeInterpreter; + +class OLExposureModeInterpreter : public ChoiceInterpreter { + public: + OLExposureModeInterpreter () { + choices[1] = "Manual"; + choices[2] = "Program"; + choices[3] = "Aperture-priority AE"; + choices[4] = "Shutter speed priority AE"; + choices[5] = "Program-shift"; + } +}; +OLExposureModeInterpreter olExposureModeInterpreter; + +class OLMeteringModeInterpreter : public ChoiceInterpreter { + public: + OLMeteringModeInterpreter () { + choices[2] = "Center-weighted average"; + choices[3] = "Spot"; + choices[5] = "ESP"; + choices[261] = "Pattern+AF"; + choices[515] = "Spot+Highlight control"; + choices[1027] = "Spot+Shadow control"; + } +}; +OLMeteringModeInterpreter olMeteringModeInterpreter; + +class OLFocusModeInterpreter : public ChoiceInterpreter { + public: + OLFocusModeInterpreter () { + choices[0] = "Single AF"; + choices[1] = "Sequential shooting AF"; + choices[2] = "Continuous AF"; + choices[3] = "Multi AF"; + choices[10] = "MF"; + } +}; +OLFocusModeInterpreter olFocusModeInterpreter; + +class OLWhitebalance2Interpreter : public ChoiceInterpreter { + public: + OLWhitebalance2Interpreter () { + choices[0] = "Auto"; + choices[16] = "7500K (Fine Weather with Shade)"; + choices[17] = "6000K (Cloudy)"; + choices[18] = "5300K (Fine Weather)"; + choices[20] = "3000K (Tungsten light)"; + choices[21] = "3600K (Tungsten light-like)"; + choices[33] = "6600K (Daylight fluorescent)"; + choices[34] = "4500K (Neutral white fluorescent)"; + choices[35] = "4000K (Cool white fluorescent)"; + choices[48] = "3600K (Tungsten light-like)"; + choices[256] = "Custom WB 1"; + choices[257] = "Custom WB 2"; + choices[258] = "Custom WB 3"; + choices[259] = "Custom WB 4"; + choices[512] = "Custom WB 5400K"; + choices[513] = "Custom WB 2900K"; + choices[514] = "Custom WB 8000K"; + } +}; +OLWhitebalance2Interpreter olWhitebalance2Interpreter; + +class OLSceneModeInterpreter : public ChoiceInterpreter { + public: + OLSceneModeInterpreter () { + choices[0] = "Standard"; + choices[6] = "Auto"; + choices[7] = "Sport"; + choices[8] = "Portrait"; + choices[9] = "Landscape+Portrait"; + choices[10] = "Landscape"; + choices[11] = "Night Scene"; + choices[12] = "Self Portrait"; + choices[13] = "Panorama"; + choices[14] = "2 in 1"; + choices[15] = "Movie"; + choices[16] = "Landscape+Portrait"; + choices[17] = "Night+Portrait"; + choices[18] = "Indoor"; + choices[19] = "Fireworks"; + choices[20] = "Sunset"; + choices[22] = "Macro"; + choices[23] = "Super Macro"; + choices[24] = "Food"; + choices[25] = "Documents"; + choices[26] = "Museum"; + choices[27] = "Shoot & Select"; + choices[28] = "Beach & Snow"; + choices[29] = "Self Protrait+Timer"; + choices[30] = "Candle"; + choices[31] = "Available Light"; + choices[32] = "Behind Glass"; + choices[33] = "My Mode"; + choices[34] = "Pet"; + choices[35] = "Underwater Wide1"; + choices[36] = "Underwater Macro"; + choices[37] = "Shoot & Select1"; + choices[38] = "Shoot & Select2"; + choices[39] = "High Key"; + choices[40] = "Digital Image Stabilization"; + choices[41] = "Auction"; + choices[42] = "Beach"; + choices[43] = "Snow"; + choices[44] = "Underwater Wide2"; + choices[45] = "Low Key"; + choices[46] = "Children"; + choices[47] = "Vivid"; + choices[48] = "Nature Macro"; + choices[49] = "Underwater Snapshot"; + choices[50] = "Shooting Guide"; + } +}; +OLSceneModeInterpreter olSceneModeInterpreter; + +class OLPictureModeBWFilterInterpreter : public ChoiceInterpreter { + public: + OLPictureModeBWFilterInterpreter () { + choices[0] = "n/a"; + choices[1] = "Neutral"; + choices[2] = "Yellow"; + choices[3] = "Orange"; + choices[4] = "Red"; + choices[5] = "Green"; + } +}; +OLPictureModeBWFilterInterpreter olPictureModeBWFilterInterpreter; + +class OLPictureModeToneInterpreter : public ChoiceInterpreter { + public: + OLPictureModeToneInterpreter () { + choices[0] = "n/a"; + choices[1] = "Neutral"; + choices[2] = "Sepia"; + choices[3] = "Blue"; + choices[4] = "Purple"; + choices[5] = "Green"; + } +}; +OLPictureModeToneInterpreter olPictureModeToneInterpreter; + +class OLImageQuality2Interpreter : public ChoiceInterpreter { + public: + OLImageQuality2Interpreter () { + choices[1] = "SQ"; + choices[2] = "HQ"; + choices[3] = "SHQ"; + choices[4] = "RAW"; + } +}; +OLImageQuality2Interpreter olImageQuality2Interpreter; + +class OLDevEngineInterpreter : public ChoiceInterpreter { + public: + OLDevEngineInterpreter () { + choices[0] = "High Speed"; + choices[1] = "High Function"; + choices[2] = "Advanced High Speed"; + choices[3] = "Advanced High Function"; + } +}; +OLDevEngineInterpreter olDevEngineInterpreter; + +class OLPictureModeInterpreter : public ChoiceInterpreter { + public: + OLPictureModeInterpreter () { + choices[1] = "Vivid"; + choices[2] = "Natural"; + choices[3] = "Muted"; + choices[4] = "Portrait"; + choices[256] = "Monotone"; + choices[512] = "Sepia"; + } +}; +OLPictureModeInterpreter olPictureModeInterpreter; + +class OLColorSpaceInterpreter : public ChoiceInterpreter { + public: + OLColorSpaceInterpreter () { + choices[0] = "sRGB"; + choices[1] = "Adobe RGB"; + choices[2] = "Pro Photo RGB"; + } +}; +OLColorSpaceInterpreter olColorSpaceInterpreter; + +class OLNoiseFilterInterpreter : public Interpreter { + public: + OLNoiseFilterInterpreter () {} + virtual std::string toString (Tag* t) { + int a = t->toInt (0); + int b = t->toInt (2); + int c = t->toInt (4); + if (a==-1 && b==-2 && c==1) + return "Low"; + else if (a==-2 && b==-2 && c==1) + return "Off"; + else if (a==0 && b==-2 && c==1) + return "Standard"; + else if (a==1 && b==-2 && c==1) + return "High"; + else return "Unknown"; + } +}; +OLNoiseFilterInterpreter olNoiseFilterInterpreter; + +class OLFlashModeInterpreter : public Interpreter { + public: + OLFlashModeInterpreter () {} + virtual std::string toString (Tag* t) { + std::ostringstream str; + int a = t->toInt (); + str << "Flash Used = " << ((a&1) ? "Yes" : "No") << std::endl; + str << "Fill-in = " << ((a&2) ? "On" : "Off") << std::endl; + str << "Red-eye = " << ((a&4) ? "On" : "Off") << std::endl; + str << "Slow-sync = " << ((a&8) ? "On" : "Off") << std::endl; + str << "Forced On = " << ((a&16) ? "On" : "Off") << std::endl; + str << "2nd Curtain = " << ((a&32) ? "On" : "Off"); + return str.str(); + } +}; +OLFlashModeInterpreter olFlashModeInterpreter; + +class OLNoiseReductionInterpreter : public Interpreter { + public: + OLNoiseReductionInterpreter () {} + virtual std::string toString (Tag* t) { + std::ostringstream str; + int a = t->toInt (); + str << "Noise Reduction = " << ((a&1) ? "On" : "Off") << std::endl; + str << "Noise Filter = " << ((a&2) ? "On" : "Off") << std::endl; + str << "Noise Filter (ISO Boost) = " << ((a&4) ? "On" : "Off"); + return str.str(); + } +}; +OLNoiseReductionInterpreter olNoiseReductionInterpreter; + +class OLFlashModelInterpreter : public ChoiceInterpreter { + public: + OLFlashModelInterpreter () { + choices[0] = "None"; + choices[1] = "FL-20"; + choices[2] = "FL-50"; + choices[3] = "RF-11"; + choices[4] = "TF-22"; + choices[5] = "FL-36"; + choices[6] = "FL-50R"; + choices[7] = "FL-36R"; + } +}; +OLFlashModelInterpreter olFlashModelInterpreter; + +const TagAttrib olyFocusInfoAttribs[] = { + 0, 1, 0, 0, 0x0000, "FocusInfoVersion", &stdInterpreter, + 0, 1, 0, 0, 0x0209, "AutoFocus", &olOnOffInterpreter, + 0, 1, 0, 0, 0x0210, "SceneDetect", &stdInterpreter, + 0, 1, 0, 0, 0x0211, "SceneArea", &stdInterpreter, + 0, 1, 0, 0, 0x0212, "SceneDetectData", &stdInterpreter, + 0, 1, 0, 0, 0x0300, "ZoomStepCount", &stdInterpreter, + 0, 1, 0, 0, 0x0301, "FocusStepCount", &stdInterpreter, + 0, 1, 0, 0, 0x0303, "FocusStepInfinity", &stdInterpreter, + 0, 1, 0, 0, 0x0304, "FocusStepNear", &stdInterpreter, + 0, 1, 0, 0, 0x0305, "FocusDistance", &stdInterpreter, + 0, 1, 0, 0, 0x0308, "AFPoint", &stdInterpreter, + 0, 1, 0, 0, 0x1201, "ExternalFlash", &olOnOffInterpreter, + 0, 1, 0, 0, 0x1203, "ExternalFlashGuideNumber", &stdInterpreter, + 0, 1, 0, 0, 0x1204, "ExternalFlashBounce", &stdInterpreter, + 0, 1, 0, 0, 0x1205, "ExternalFlashZoom", &stdInterpreter, + 0, 1, 0, 0, 0x1208, "InternalFlash", &olOnOffInterpreter, + 0, 1, 0, 0, 0x1209, "ManualFlash", &olOnOffInterpreter, + 0, 1, 0, 0, 0x1500, "SensorTemperature", &stdInterpreter, + 0, 1, 0, 0, 0x1600, "ImageStabilization", &stdInterpreter, +-1, 0, 0, 0, 0, "", NULL}; + +const TagAttrib olyImageProcessingAttribs[] = { + 0, 1, 0, 0, 0x0000, "ImageProcessingVersion", &stdInterpreter, + 0, 1, 0, 0, 0x0100, "WB_RBLevels", &stdInterpreter, + 0, 1, 0, 0, 0x0102, "WB_RBLevels3000K", &stdInterpreter, + 0, 1, 0, 0, 0x0103, "WB_RBLevels3300K", &stdInterpreter, + 0, 1, 0, 0, 0x0104, "WB_RBLevels3600K", &stdInterpreter, + 0, 1, 0, 0, 0x0105, "WB_RBLevels3900K", &stdInterpreter, + 0, 1, 0, 0, 0x0106, "WB_RBLevels4000K", &stdInterpreter, + 0, 1, 0, 0, 0x0107, "WB_RBLevels4300K", &stdInterpreter, + 0, 1, 0, 0, 0x0108, "WB_RBLevels4500K", &stdInterpreter, + 0, 1, 0, 0, 0x0109, "WB_RBLevels4800K", &stdInterpreter, + 0, 1, 0, 0, 0x010a, "WB_RBLevels5300K", &stdInterpreter, + 0, 1, 0, 0, 0x010b, "WB_RBLevels6000K", &stdInterpreter, + 0, 1, 0, 0, 0x010c, "WB_RBLevels6600K", &stdInterpreter, + 0, 1, 0, 0, 0x010d, "WB_RBLevels7500K", &stdInterpreter, + 0, 1, 0, 0, 0x010e, "WB_RBLevelsCWB1", &stdInterpreter, + 0, 1, 0, 0, 0x010f, "WB_RBLevelsCWB2", &stdInterpreter, + 0, 1, 0, 0, 0x0110, "WB_RBLevelsCWB3", &stdInterpreter, + 0, 1, 0, 0, 0x0111, "WB_RBLevelsCWB4", &stdInterpreter, + 0, 1, 0, 0, 0x0113, "WB_GLevel3000K", &stdInterpreter, + 0, 1, 0, 0, 0x0114, "WB_GLevel3300K", &stdInterpreter, + 0, 1, 0, 0, 0x0115, "WB_GLevel3600K", &stdInterpreter, + 0, 1, 0, 0, 0x0116, "WB_GLevel3900K", &stdInterpreter, + 0, 1, 0, 0, 0x0117, "WB_GLevel4000K", &stdInterpreter, + 0, 1, 0, 0, 0x0118, "WB_GLevel4300K", &stdInterpreter, + 0, 1, 0, 0, 0x0119, "WB_GLevel4500K", &stdInterpreter, + 0, 1, 0, 0, 0x011a, "WB_GLevel4800K", &stdInterpreter, + 0, 1, 0, 0, 0x011b, "WB_GLevel5300K", &stdInterpreter, + 0, 1, 0, 0, 0x011c, "WB_GLevel6000K", &stdInterpreter, + 0, 1, 0, 0, 0x011d, "WB_GLevel6600K", &stdInterpreter, + 0, 1, 0, 0, 0x011e, "WB_GLevel7500K", &stdInterpreter, + 0, 1, 0, 0, 0x011f, "WB_GLevel", &stdInterpreter, + 0, 1, 0, 0, 0x0200, "ColorMatrix", &stdInterpreter, + 0, 1, 0, 0, 0x0300, "Enhancer", &stdInterpreter, + 0, 1, 0, 0, 0x0301, "EnhancerValues", &stdInterpreter, + 0, 1, 0, 0, 0x0310, "CoringFilter", &stdInterpreter, + 0, 1, 0, 0, 0x0311, "CoringValues", &stdInterpreter, + 0, 1, 0, 0, 0x0600, "BlackLevel2", &stdInterpreter, + 0, 1, 0, 0, 0x0610, "GainBase", &stdInterpreter, + 0, 1, 0, 0, 0x0611, "ValidBits", &stdInterpreter, + 0, 1, 0, 0, 0x0612, "CropLeft", &stdInterpreter, + 0, 1, 0, 0, 0x0613, "CropTop", &stdInterpreter, + 0, 1, 0, 0, 0x0614, "CropWidth", &stdInterpreter, + 0, 1, 0, 0, 0x0615, "CropHeight", &stdInterpreter, + 0, 1, 0, 0, 0x1010, "NoiseReduction2", &stdInterpreter, + 0, 1, 0, 0, 0x1011, "DistortionCorrection2", &olOnOffInterpreter, + 0, 1, 0, 0, 0x1012, "ShadingCompensation2", &olOnOffInterpreter, + 1, 1, 0, 0, 0x1103, "UnknownBlock", &stdInterpreter, + 0, 1, 0, 0, 0x1200, "FaceDetect", &olOnOffInterpreter, + 0, 1, 0, 0, 0x1201, "FaceDetectArea", &stdInterpreter, +-1, 0, 0, 0, 0, "", NULL}; + +const TagAttrib olyRawDevelopmentAttribs[] = { + 0, 1, 0, 0, 0x0000, "RawDevVersion", &stdInterpreter, + 0, 1, 0, 0, 0x0100, "RawDevExposureBiasValue", &stdInterpreter, + 0, 1, 0, 0, 0x0101, "RawDevWhiteBalanceValue", &stdInterpreter, + 0, 1, 0, 0, 0x0102, "RawDevWBFineAdjustment", &stdInterpreter, + 0, 1, 0, 0, 0x0103, "RawDevGrayPoint", &stdInterpreter, + 0, 1, 0, 0, 0x0104, "RawDevSaturationEmphasis", &stdInterpreter, + 0, 1, 0, 0, 0x0105, "RawDevMemoryColorEmphasis", &stdInterpreter, + 0, 1, 0, 0, 0x0106, "RawDevContrastValue", &stdInterpreter, + 0, 1, 0, 0, 0x0107, "RawDevSharpnessValue", &stdInterpreter, + 0, 1, 0, 0, 0x0108, "RawDevColorSpace", &olColorSpaceInterpreter, + 0, 1, 0, 0, 0x0109, "RawDevEngine", &olDevEngineInterpreter, + 0, 1, 0, 0, 0x010a, "RawDevNoiseReduction", &olNoiseReductionInterpreter, + 0, 1, 0, 0, 0x010b, "RawDevEditStatus", &stdInterpreter, + 0, 1, 0, 0, 0x010c, "RawDevSettings", &stdInterpreter, +-1, 0, 0, 0, 0, "", NULL}; + +const TagAttrib olyRawDevelopment2Attribs[] = { + 0, 1, 0, 0, 0x0000, "RawDevVersion", &stdInterpreter, + 0, 1, 0, 0, 0x0100, "RawDevExposureBiasValue", &stdInterpreter, + 0, 1, 0, 0, 0x0101, "RawDevWhiteBalance", &stdInterpreter, + 0, 1, 0, 0, 0x0102, "RawDevWhiteBalanceValue", &stdInterpreter, + 0, 1, 0, 0, 0x0103, "RawDevWBFineAdjustment", &stdInterpreter, + 0, 1, 0, 0, 0x0104, "RawDevGrayPoint", &stdInterpreter, + 0, 1, 0, 0, 0x0105, "RawDevContrastValue", &stdInterpreter, + 0, 1, 0, 0, 0x0106, "RawDevSharpnessValue", &stdInterpreter, + 0, 1, 0, 0, 0x0107, "RawDevSaturationEmphasis", &stdInterpreter, + 0, 1, 0, 0, 0x0108, "RawDevMemoryColorEmphasis", &stdInterpreter, + 0, 1, 0, 0, 0x0109, "RawDevColorSpace", &olColorSpaceInterpreter, + 0, 1, 0, 0, 0x010a, "RawDevNoiseReduction", &olNoiseReductionInterpreter, + 0, 1, 0, 0, 0x010b, "RawDevEngine", &olDevEngineInterpreter, + 0, 1, 0, 0, 0x010c, "RawDevPictureMode", &olPictureModeInterpreter, + 0, 1, 0, 0, 0x010d, "RawDevPMSaturation", &stdInterpreter, + 0, 1, 0, 0, 0x010e, "RawDevPMContrast", &stdInterpreter, + 0, 1, 0, 0, 0x010f, "RawDevPMSharpness", &stdInterpreter, + 0, 1, 0, 0, 0x0110, "RawDevPM_BWFilter", &olPictureModeBWFilterInterpreter, + 0, 1, 0, 0, 0x0111, "RawDevPMPictureTone", &olPictureModeToneInterpreter, + 0, 1, 0, 0, 0x0112, "RawDevGradation", &stdInterpreter, + 0, 1, 0, 0, 0x0113, "RawDevSaturation3", &stdInterpreter, + 0, 1, 0, 0, 0x0119, "RawDevAutoGradation", &olOnOffInterpreter, + 0, 1, 0, 0, 0x0120, "RawDevPMNoiseFilter", &stdInterpreter, +-1, 0, 0, 0, 0, "", NULL}; + +const TagAttrib olyCameraSettingsAttribs[] = { + 0, 1, 0, 0, 0x0000, "CameraSettingsVersion", &stdInterpreter, + 1, 1, 0, 0, 0x0100, "PreviewImageValid", &olYesNoInterpreter, + 1, 1, 0, 0, 0x0101, "PreviewImageStart", &stdInterpreter, + 1, 1, 0, 0, 0x0102, "PreviewImageLength", &stdInterpreter, + 0, 1, 0, 0, 0x0200, "ExposureMode", &olExposureModeInterpreter, + 0, 1, 0, 0, 0x0201, "AELock", &olOnOffInterpreter, + 0, 1, 0, 0, 0x0202, "MeteringMode", &olMeteringModeInterpreter, + 0, 1, 0, 0, 0x0300, "MacroMode", &olOnOffInterpreter, + 0, 1, 0, 0, 0x0301, "FocusMode", &olFocusModeInterpreter, + 0, 1, 0, 0, 0x0302, "FocusProcess", &stdInterpreter, + 0, 1, 0, 0, 0x0303, "AFSearch", &stdInterpreter, + 0, 1, 0, 0, 0x0304, "AFAreas", &stdInterpreter, + 0, 1, 0, 0, 0x0400, "FlashMode", &stdInterpreter, + 0, 1, 0, 0, 0x0401, "FlashExposureComp", &stdInterpreter, + 0, 1, 0, 0, 0x0500, "WhiteBalance2", &olWhitebalance2Interpreter, + 0, 1, 0, 0, 0x0501, "WhiteBalanceTemperature", &stdInterpreter, + 0, 1, 0, 0, 0x0502, "WhiteBalanceBracket", &stdInterpreter, + 0, 1, 0, 0, 0x0503, "CustomSaturation", &stdInterpreter, + 0, 1, 0, 0, 0x0504, "ModifiedSaturation", &stdInterpreter, + 0, 1, 0, 0, 0x0505, "ContrastSetting", &stdInterpreter, + 0, 1, 0, 0, 0x0506, "SharpnessSetting", &stdInterpreter, + 0, 1, 0, 0, 0x0507, "ColorSpace", &olColorSpaceInterpreter, + 0, 1, 0, 0, 0x0509, "SceneMode", &olSceneModeInterpreter, + 0, 1, 0, 0, 0x050a, "NoiseReduction", &olNoiseReductionInterpreter, + 0, 1, 0, 0, 0x050b, "DistortionCorrection", &olOnOffInterpreter, + 0, 1, 0, 0, 0x050c, "ShadingCompensation", &olOnOffInterpreter, + 0, 1, 0, 0, 0x050d, "CompressionFactor", &stdInterpreter, + 0, 1, 0, 0, 0x050f, "Gradation", &stdInterpreter, + 0, 1, 0, 0, 0x0520, "PictureMode", &olPictureModeInterpreter, + 0, 1, 0, 0, 0x0521, "PictureModeSaturation", &stdInterpreter, + 0, 1, 0, 0, 0x0522, "PictureModeHue", &stdInterpreter, + 0, 1, 0, 0, 0x0523, "PictureModeContrast", &stdInterpreter, + 0, 1, 0, 0, 0x0524, "PictureModeSharpness", &stdInterpreter, + 0, 1, 0, 0, 0x0525, "PictureModeBWFilter", &olPictureModeBWFilterInterpreter, + 0, 1, 0, 0, 0x0526, "PictureModeTone", &olPictureModeToneInterpreter, + 0, 1, 0, 0, 0x0527, "NoiseFilter", &olNoiseFilterInterpreter, + 0, 1, 0, 0, 0x0600, "DriveMode", &stdInterpreter, + 0, 1, 0, 0, 0x0601, "PanoramaMode", &stdInterpreter, + 0, 1, 0, 0, 0x0603, "ImageQuality2", &olImageQuality2Interpreter, + 0, 1, 0, 0, 0x0900, "ManometerPressure", &stdInterpreter, + 0, 1, 0, 0, 0x0901, "ManometerReading", &stdInterpreter, + 0, 1, 0, 0, 0x0902, "ExtendedWBDetect", &olOnOffInterpreter, + -1, 0, 0, 0, 0, "", NULL}; + +const TagAttrib olyEquipmentAttribs[] = { + 0, 1, 0, 0, 0x0000, "EquipmentVersion", &stdInterpreter, + 0, 1, 0, 0, 0x0100, "CameraType2", &stdInterpreter, + 0, 1, 0, 0, 0x0101, "SerialNumber", &stdInterpreter, + 0, 1, 0, 0, 0x0102, "InternalSerialNumber", &stdInterpreter, + 0, 1, 0, 0, 0x0103, "FocalPlaneDiagonal", &stdInterpreter, + 0, 1, 0, 0, 0x0104, "BodyFirmwareVersion", &stdInterpreter, + 0, 1, 0, 0, 0x0201, "LensType", &olLensTypeInterpreter, + 0, 1, 0, 0, 0x0202, "LensSerialNumber", &stdInterpreter, + 0, 1, 0, 0, 0x0204, "LensFirmwareVersion", &stdInterpreter, + 0, 1, 0, 0, 0x0205, "MaxApertureAtMinFocal", &olApertureInterpreter, + 0, 1, 0, 0, 0x0206, "MaxApertureAtMaxFocal", &olApertureInterpreter, + 0, 1, 0, 0, 0x0207, "MinFocalLength", &stdInterpreter, + 0, 1, 0, 0, 0x0208, "MaxFocalLength", &stdInterpreter, + 0, 1, 0, 0, 0x020a, "MaxApertureAtCurrentFocal", &olApertureInterpreter, + 0, 1, 0, 0, 0x020b, "LensProperties", &stdInterpreter, + 0, 1, 0, 0, 0x0301, "Extender", &stdInterpreter, + 0, 1, 0, 0, 0x0302, "ExtenderSerialNumber", &stdInterpreter, + 0, 1, 0, 0, 0x0303, "ExtenderModel", &stdInterpreter, + 0, 1, 0, 0, 0x0304, "ExtenderFirmwareVersion", &stdInterpreter, + 0, 1, 0, 0, 0x1000, "FlashType", &olFlashTypeInterpreter, + 0, 1, 0, 0, 0x1001, "FlashModel", &olFlashModelInterpreter, + 0, 1, 0, 0, 0x1002, "FlashFirmwareVersion", &stdInterpreter, + 0, 1, 0, 0, 0x1003, "FlashSerialNumber", &stdInterpreter, + -1, 0, 0, 0, 0, "", NULL}; + +const TagAttrib olympusAttribs[] = { + 0, 1, 0, 0, 0x0104, "BodyFirmwareVersion", &stdInterpreter, + 0, 1, 0, 0, 0x0200, "SpecialMode", &stdInterpreter, + 0, 1, 0, 0, 0x0201, "Quality", &stdInterpreter, + 0, 1, 0, 0, 0x0202, "Macro", &olOnOffInterpreter, + 0, 1, 0, 0, 0x0203, "BWMode", &olOnOffInterpreter, + 0, 1, 0, 0, 0x0204, "DigitalZoom", &stdInterpreter, + 0, 1, 0, 0, 0x0205, "FocalPlaneDiagonal", &stdInterpreter, + 0, 1, 0, 0, 0x0206, "LensDistortionParams", &stdInterpreter, + 0, 1, 0, 0, 0x0207, "CameraType", &stdInterpreter, + 1, 1, 0, 0, 0x0208, "TextInfo", &stdInterpreter, + 0, 1, 0, 0, 0x0209, "CameraID", &stdInterpreter, + 0, 1, 0, 0, 0x020b, "EpsonImageWidth", &stdInterpreter, + 0, 1, 0, 0, 0x020c, "EpsonImageHeight", &stdInterpreter, + 0, 1, 0, 0, 0x020d, "EpsonSoftware", &stdInterpreter, + 0, 2, 0, 0, 0x0280, "PreviewImage", &stdInterpreter, + 0, 1, 0, 0, 0x0300, "PreCaptureFrames", &stdInterpreter, + 0, 1, 0, 0, 0x0301, "WhiteBoard", &stdInterpreter, + 0, 1, 0, 0, 0x0302, "OneTouchWB", &olOnOffInterpreter, + 0, 1, 0, 0, 0x0303, "WhiteBalanceBracket", &stdInterpreter, + 0, 1, 0, 0, 0x0304, "WhiteBalanceBias", &stdInterpreter, + 0, 1, 0, 0, 0x0403, "SceneMode", &stdInterpreter, + 0, 1, 0, 0, 0x0404, "SerialNumber", &stdInterpreter, + 0, 1, 0, 0, 0x0405, "Firmware", &stdInterpreter, + 1, 1, 0, 0, 0x0e00, "PrintIM", &stdInterpreter, + 0, 1, 0, 0, 0x0f00, "DataDump", &stdInterpreter, + 0, 1, 0, 0, 0x0f01, "DataDump2", &stdInterpreter, + 0, 1, 0, 0, 0x1000, "ShutterSpeedValue", &stdInterpreter, + 0, 1, 0, 0, 0x1001, "ISOValue", &stdInterpreter, + 0, 1, 0, 0, 0x1002, "ApertureValue", &stdInterpreter, + 0, 1, 0, 0, 0x1003, "BrightnessValue", &stdInterpreter, + 0, 1, 0, 0, 0x1004, "FlashMode", &stdInterpreter, + 0, 1, 0, 0, 0x1005, "FlashDevice", &stdInterpreter, + 0, 1, 0, 0, 0x1006, "ExposureCompensation", &stdInterpreter, + 0, 1, 0, 0, 0x1007, "SensorTemperature", &stdInterpreter, + 0, 1, 0, 0, 0x1008, "LensTemperature", &stdInterpreter, + 0, 1, 0, 0, 0x1009, "LightCondition", &stdInterpreter, + 0, 1, 0, 0, 0x100a, "FocusRange", &stdInterpreter, + 0, 1, 0, 0, 0x100b, "FocusMode", &stdInterpreter, + 0, 1, 0, 0, 0x100c, "ManualFocusDistance", &stdInterpreter, + 0, 1, 0, 0, 0x100d, "ZoomStepCount", &stdInterpreter, + 0, 1, 0, 0, 0x100e, "FocusStepCount", &stdInterpreter, + 0, 1, 0, 0, 0x100f, "Sharpness", &stdInterpreter, + 0, 1, 0, 0, 0x1010, "FlashChargeLevel", &stdInterpreter, + 0, 1, 0, 0, 0x1011, "ColorMatrix", &stdInterpreter, + 0, 1, 0, 0, 0x1012, "BlackLevel", &stdInterpreter, + 0, 1, 0, 0, 0x1013, "ColorTemperatureBG", &stdInterpreter, + 0, 1, 0, 0, 0x1014, "ColorTemperatureRG", &stdInterpreter, + 0, 1, 0, 0, 0x1015, "WBMode", &stdInterpreter, + 0, 1, 0, 0, 0x1017, "RedBalance", &stdInterpreter, + 0, 1, 0, 0, 0x1018, "BlueBalance", &stdInterpreter, + 0, 1, 0, 0, 0x1019, "ColorMatrixNumber", &stdInterpreter, + 0, 1, 0, 0, 0x101a, "SerialNumber", &stdInterpreter, + 0, 1, 0, 0, 0x101b, "ExternalFlashAE1_0", &stdInterpreter, + 0, 1, 0, 0, 0x101c, "ExternalFlashAE2_0", &stdInterpreter, + 0, 1, 0, 0, 0x101d, "InternalFlashAE1_0", &stdInterpreter, + 0, 1, 0, 0, 0x101e, "InternalFlashAE2_0", &stdInterpreter, + 0, 1, 0, 0, 0x101f, "ExternalFlashAE1", &stdInterpreter, + 0, 1, 0, 0, 0x1020, "ExternalFlashAE2", &stdInterpreter, + 0, 1, 0, 0, 0x1021, "InternalFlashAE1", &stdInterpreter, + 0, 1, 0, 0, 0x1022, "InternalFlashAE2", &stdInterpreter, + 0, 1, 0, 0, 0x1023, "FlashExposureComp", &stdInterpreter, + 0, 1, 0, 0, 0x1024, "InternalFlashTable", &stdInterpreter, + 0, 1, 0, 0, 0x1025, "ExternalFlashGValue", &stdInterpreter, + 0, 1, 0, 0, 0x1026, "ExternalFlashBounce", &olYesNoInterpreter, + 0, 1, 0, 0, 0x1027, "ExternalFlashZoom", &stdInterpreter, + 0, 1, 0, 0, 0x1028, "ExternalFlashMode", &stdInterpreter, + 0, 1, 0, 0, 0x1029, "Contrast", &stdInterpreter, + 0, 1, 0, 0, 0x102a, "SharpnessFactor", &stdInterpreter, + 0, 1, 0, 0, 0x102b, "ColorControl", &stdInterpreter, + 0, 1, 0, 0, 0x102c, "ValidBits", &stdInterpreter, + 0, 1, 0, 0, 0x102d, "CoringFilter", &stdInterpreter, + 0, 1, 0, 0, 0x102e, "OlympusImageWidth", &stdInterpreter, + 0, 1, 0, 0, 0x102f, "OlympusImageHeight", &stdInterpreter, + 0, 1, 0, 0, 0x1030, "SceneDetect", &stdInterpreter, + 0, 1, 0, 0, 0x1031, "SceneArea", &stdInterpreter, + 0, 1, 0, 0, 0x1033, "SceneDetectData", &stdInterpreter, + 0, 1, 0, 0, 0x1034, "CompressionRatio", &stdInterpreter, + 1, 1, 0, 0, 0x1035, "PreviewImageValid", &olYesNoInterpreter, + 1, 1, 0, 0, 0x1036, "PreviewImageStart", &stdInterpreter, + 1, 1, 0, 0, 0x1037, "PreviewImageLength", &stdInterpreter, + 0, 1, 0, 0, 0x1038, "AFResult", &stdInterpreter, + 0, 1, 0, 0, 0x1039, "CCDScanMode", &stdInterpreter, + 0, 1, 0, 0, 0x103a, "NoiseReduction", &olOnOffInterpreter, + 0, 1, 0, 0, 0x103b, "InfinityLensStep", &stdInterpreter, + 0, 1, 0, 0, 0x103c, "NearLensStep", &stdInterpreter, + 0, 1, 0, 0, 0x103d, "LightValueCenter", &stdInterpreter, + 0, 1, 0, 0, 0x103e, "LightValuePeriphery", &stdInterpreter, + 0, 1, 0, 0, 0x103f, "FieldCount", &stdInterpreter, + 0, 1, 0, olyEquipmentAttribs, 0x2010, "Equipment", &stdInterpreter, + 0, 1, 0, olyCameraSettingsAttribs, 0x2020, "CameraSettings", &stdInterpreter, + 0, 1, 0, olyRawDevelopmentAttribs, 0x2030, "RawDevelopment", &stdInterpreter, + 0, 1, 0, olyRawDevelopment2Attribs, 0x2031, "RawDev2", &stdInterpreter, + 0, 1, 0, olyImageProcessingAttribs, 0x2040, "ImageProcessing", &stdInterpreter, + 0, 1, 0, olyFocusInfoAttribs, 0x2050, "FocusInfo", &stdInterpreter, + 1, 1, 0, 0, 0x2100, "Olympus2100", &stdInterpreter, + 1, 1, 0, 0, 0x2300, "Olympus2300", &stdInterpreter, + 1, 1, 0, 0, 0x2400, "Olympus2400", &stdInterpreter, + 1, 1, 0, 0, 0x2500, "Olympus2500", &stdInterpreter, + 1, 1, 0, 0, 0x2600, "Olympus2600", &stdInterpreter, + 1, 1, 0, 0, 0x2700, "Olympus2700", &stdInterpreter, + 1, 1, 0, 0, 0x2800, "Olympus2800", &stdInterpreter, + 1, 1, 0, 0, 0x2900, "Olympus2900", &stdInterpreter, + 0, 1, 0, 0, 0x3000, "RawInfo", &stdInterpreter, + -1, 0, 0, 0, 0, "", NULL}; +}; + #endif + diff --git a/rtexif/pentaxattribs.cc b/rtexif/pentaxattribs.cc new file mode 100644 index 000000000..5c86d637f --- /dev/null +++ b/rtexif/pentaxattribs.cc @@ -0,0 +1,585 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _PENTAXATTRIBS_ +#define _PENTAXATTRIBS_ + +#include +#include +#include +#include +#include +#include + +namespace rtexif { + + +class PAQualityInterpreter : public ChoiceInterpreter { + public: + PAQualityInterpreter () { + choices[0] = "Good"; + choices[1] = "Better"; + choices[2] = "Best"; + choices[3] = "TIFF"; + choices[4] = "RAW"; + choices[5] = "Premium"; + } +}; +PAQualityInterpreter paQualityInterpreter; + +class PAOnOffInterpreter : public ChoiceInterpreter { + public: + PAOnOffInterpreter () { + choices[0] = "Off"; + choices[1] = "On"; + } +}; +PAOnOffInterpreter paOnOffInterpreter; + +class PAPictureModeInterpreter : public ChoiceInterpreter { + public: + PAPictureModeInterpreter () { + choices[0] = "Program"; + choices[1] = "Shutter Speed Priority"; + choices[2] = "Program AE"; + choices[3] = "Manual"; + choices[5] = "Portrait"; + choices[6] = "Landscape"; + choices[8] = "Sport"; + choices[9] = "Night Scene"; + choices[11] = "Soft"; + choices[12] = "Surf & Snow"; + choices[13] = "Candlelight"; + choices[14] = "Autumn"; + choices[15] = "Macro"; + choices[17] = "Fireworks"; + choices[18] = "Text"; + choices[19] = "Panorama"; + choices[30] = "Self Portrait"; + choices[31] = "Illustrations"; + choices[33] = "Digital Filter"; + choices[35] = "Night Scene Portrait"; + choices[37] = "Museum"; + choices[38] = "Food"; + choices[39] = "Underwater"; + choices[40] = "Green Mode"; + choices[49] = "Light Pet"; + choices[50] = "Dark Pet"; + choices[51] = "Medium Pet"; + choices[53] = "Underwater"; + choices[54] = "Candlelight"; + choices[55] = "Natural Skin Tone"; + choices[56] = "Synchro Sound Record"; + choices[58] = "Frame Composite"; + choices[59] = "Report"; + choices[60] = "Kids"; + choices[61] = "Blur Reduction"; + choices[65] = "Half-length Portrait"; + } +}; +PAPictureModeInterpreter paPictureModeInterpreter; + +class PAFlashModeInterpreter : public ChoiceInterpreter { + public: + PAFlashModeInterpreter () { + choices[0x0] = "Auto, Did not fire"; + choices[0x1] = "Off"; + choices[0x2] = "On, Did not fire"; + choices[0x3] = "Auto, Did not fire, Red-eye reduction"; + choices[0x100] = "Auto, Fired"; + choices[0x102] = "On"; + choices[0x103] = "Auto, Fired, Red-eye reduction"; + choices[0x104] = "On, Red-eye reduction"; + choices[0x105] = "On, Wireless (Master)"; + choices[0x106] = "On, Wireless (Control)"; + choices[0x108] = "On, Soft"; + choices[0x109] = "On, Slow-sync"; + choices[0x10a] = "On, Slow-sync, Red-eye reduction"; + choices[0x10b] = "On, Trailing-curtain Sync"; + } +}; +PAFlashModeInterpreter paFlashModeInterpreter; + +class PAFocusModeInterpreter : public ChoiceInterpreter { + public: + PAFocusModeInterpreter () { + choices[0] = "Normal"; + choices[1] = "Macro"; + choices[2] = "Infinity"; + choices[3] = "Manual"; + choices[4] = "Super Macro"; + choices[5] = "Pan Focus"; + choices[16] = "AF-S"; + choices[17] = "AF-C"; + choices[18] = "AF-A"; + } +}; +PAFocusModeInterpreter paFocusModeInterpreter; + +class PAAFPointInterpreter : public ChoiceInterpreter { + public: + PAAFPointInterpreter () { + choices[1] = "Upper-left"; + choices[2] = "Top"; + choices[3] = "Upper-right"; + choices[4] = "Left"; + choices[5] = "Mid-left"; + choices[6] = "Center"; + choices[7] = "Mid-right"; + choices[8] = "Right"; + choices[9] = "Lower-left"; + choices[10] = "Bottom"; + choices[11] = "Lower-right"; + choices[65532] = "Face Recognition AF"; + choices[65533] = "Automatic Tracking AF"; + choices[65534] = "Fixed Center"; + choices[65535] = "Auto"; + } +}; +PAAFPointInterpreter paAFPointInterpreter; + +class PAAFFocusInterpreter : public ChoiceInterpreter { + public: + PAAFFocusInterpreter () { + choices[0x0] = "Fixed Center or Multiple"; + choices[0x1] = "Top-left"; + choices[0x2] = "Top-center"; + choices[0x3] = "Top-right"; + choices[0x4] = "Left"; + choices[0x5] = "Center"; + choices[0x6] = "Right"; + choices[0x7] = "Bottom-left"; + choices[0x8] = "Bottom-center"; + choices[0x9] = "Bottom-right"; + choices[0xffff] = "None"; + } +}; +PAAFFocusInterpreter paAFFocusInterpreter; + +class PAISOInterpreter : public ChoiceInterpreter { + public: + PAISOInterpreter () { + choices[3] = "50"; + choices[4] = "64"; + choices[5] = "80"; + choices[6] = "100"; + choices[7] = "125"; + choices[8] = "160"; + choices[9] = "200"; + choices[10] = "250"; + choices[11] = "320"; + choices[12] = "400"; + choices[13] = "500"; + choices[14] = "640"; + choices[15] = "800"; + choices[16] = "1000"; + choices[17] = "1250"; + choices[18] = "1600"; + choices[19] = "2000"; + choices[20] = "2500"; + choices[21] = "3200"; + choices[50] = "50"; + choices[100] = "100"; + choices[200] = "200"; + choices[258] = "50"; + choices[259] = "70"; + choices[260] = "100"; + choices[261] = "140"; + choices[262] = "200"; + choices[263] = "280"; + choices[264] = "400"; + choices[265] = "560"; + choices[266] = "800"; + choices[267] = "1100"; + choices[268] = "1600"; + choices[269] = "2200"; + choices[270] = "3200"; + choices[400] = "400"; + choices[800] = "800"; + choices[1600] = "1600"; + choices[3200] = "320"; + } +}; +PAISOInterpreter paISOInterpreter; + +class PAMeteringModeInterpreter : public ChoiceInterpreter { + public: + PAMeteringModeInterpreter () { + choices[0] = "Multi-segment"; + choices[1] = "Center-weighted average"; + choices[2] = "Spot"; + } +}; +PAMeteringModeInterpreter paMeteringModeInterpreter; + +class PAWhiteBalanceInterpreter : public ChoiceInterpreter { + public: + PAWhiteBalanceInterpreter () { + choices[0] = "Auto"; + choices[1] = "Daylight"; + choices[2] = "Shade"; + choices[3] = "Fluorescent"; + choices[4] = "Tungsten"; + choices[5] = "Manual"; + choices[6] = "DaylightFluorescent"; + choices[7] = "DaywhiteFluorescent"; + choices[8] = "WhiteFluorescent"; + choices[9] = "Flash"; + choices[10] = "Cloudy"; + choices[17] = "Kelvin"; + choices[65534] = "Unknown"; + choices[65535] = "User Selected"; + } +}; +PAWhiteBalanceInterpreter paWhiteBalanceInterpreter; + +class PAWhiteBalanceModeInterpreter : public ChoiceInterpreter { + public: + PAWhiteBalanceModeInterpreter () { + choices[1] = "Auto (Daylight)"; + choices[2] = "Auto (Shade)"; + choices[3] = "Auto (Flash)"; + choices[4] = "Auto (Tungsten)"; + choices[6] = "Auto (DaylightFluorescent)"; + choices[7] = "Auto (DaywhiteFluorescent)"; + choices[8] = "Auto (WhiteFluorescent)"; + choices[10] = "Auto (Cloudy)"; + choices[65534] = "Preset (Fireworks?)"; + choices[65535] = "User-Selected"; + } +}; +PAWhiteBalanceModeInterpreter paWhiteBalanceModeInterpreter; + +class PASaturationInterpreter : public ChoiceInterpreter { + public: + PASaturationInterpreter () { + choices[0] = "Low"; + choices[1] = "Normal"; + choices[2] = "High"; + choices[3] = "Med Low"; + choices[4] = "Med High"; + choices[5] = "Very Low"; + choices[6] = "Very High"; + } +}; +PASaturationInterpreter paSaturationInterpreter; + +class PAContrastInterpreter : public ChoiceInterpreter { + public: + PAContrastInterpreter () { + choices[0] = "Low"; + choices[1] = "Normal"; + choices[2] = "High"; + choices[3] = "Med Low"; + choices[4] = "Med High"; + choices[5] = "Very Low"; + choices[6] = "Very High"; + } +}; +PAContrastInterpreter paContrastInterpreter; + +class PASharpnessInterpreter : public ChoiceInterpreter { + public: + PASharpnessInterpreter () { + choices[0] = "Soft"; + choices[1] = "Normal"; + choices[2] = "Hard"; + choices[3] = "Med Soft"; + choices[4] = "Med Hard"; + choices[5] = "Very Soft"; + choices[6] = "Very Hard"; + } +}; +PASharpnessInterpreter paSharpnessInterpreter; + +class PALensTypeInterpreter : public ChoiceInterpreter { + public: + PALensTypeInterpreter () { + choices[256*0+ 0] = "M-42 or No Lens"; + choices[256*1+ 0] = "K,M Lens"; + choices[256*2+ 0] = "A Series Lens"; + choices[256*3+ 0] = "SIGMA"; + choices[256*3+ 17] = "smc PENTAX-FA SOFT 85mm F2.8"; + choices[256*3+ 18] = "smc PENTAX-F 1.7X AF ADAPTER"; + choices[256*3+ 19] = "smc PENTAX-F 24-50mm F4"; + choices[256*3+ 20] = "smc PENTAX-F 35-80mm F4-5.6"; + choices[256*3+ 21] = "smc PENTAX-F 80-200mm F4.7-5.6"; + choices[256*3+ 22] = "smc PENTAX-F FISH-EYE 17-28mm F3.5-4.5"; + choices[256*3+ 23] = "smc PENTAX-F 100-300mm F4.5-5.6"; + choices[256*3+ 24] = "smc PENTAX-F 35-135mm F3.5-4.5"; + choices[256*3+ 25] = "smc PENTAX-F 35-105mm F4-5.6 or SIGMA or Tokina"; + choices[256*3+ 26] = "smc PENTAX-F* 250-600mm F5.6 ED[IF]"; + choices[256*3+ 27] = "smc PENTAX-F 28-80mm F3.5-4.5"; + choices[256*3+ 28] = "smc PENTAX-F 35-70mm F3.5-4.5"; + choices[256*3+ 29] = "PENTAX-F 28-80mm F3.5-4.5 or SIGMA AF 18-125mm F3.5-5.6 DC"; + choices[256*3+ 30] = "PENTAX-F 70-200mm F4-5.6"; + choices[256*3+ 31] = "smc PENTAX-F 70-210mm F4-5.6"; + choices[256*3+ 32] = "smc PENTAX-F 50mm F1.4"; + choices[256*3+ 33] = "smc PENTAX-F 50mm F1.7"; + choices[256*3+ 34] = "smc PENTAX-F 135mm F2.8 [IF]"; + choices[256*3+ 35] = "smc PENTAX-F 28mm F2.8"; + choices[256*3+ 36] = "SIGMA 20mm F1.8 EX DG ASPHERICAL RF"; + choices[256*3+ 38] = "smc PENTAX-F* 300mm F4.5 ED[IF]"; + choices[256*3+ 39] = "smc PENTAX-F* 600mm F4 ED[IF]"; + choices[256*3+ 40] = "smc PENTAX-F MACRO 100mm F2.8"; + choices[256*3+ 41] = "smc PENTAX-F MACRO 50mm F2.8 or Sigma 50mm F2,8 MACRO"; + choices[256*3+ 44] = "Tamron 35-90mm F4 AF or various SIGMA models"; + choices[256*3+ 46] = "SIGMA APO 70-200mm F2.8 EX"; + choices[256*3+ 50] = "smc PENTAX-FA 28-70 F4 AL"; + choices[256*3+ 51] = "SIGMA 28mm F1.8 EX DG ASPHERICAL MACRO"; + choices[256*3+ 52] = "smc PENTAX-FA 28-200mm F3.8-5.6 AL[IF]"; + choices[256*3+ 53] = "smc PENTAX-FA 28-80mm F3.5-5.6 AL"; + choices[256*3+ 247] = "smc PENTAX-DA FISH-EYE 10-17mm F3.5-4.5 ED[IF]"; + choices[256*3+ 248] = "smc PENTAX-DA 12-24mm F4 ED AL[IF]"; + choices[256*3+ 250] = "smc PENTAX-DA 50-200mm F4-5.6 ED"; + choices[256*3+ 251] = "smc PENTAX-DA 40mm F2.8 Limited"; + choices[256*3+ 252] = "smc PENTAX-DA 18-55mm F3.5-5.6 AL"; + choices[256*3+ 253] = "smc PENTAX-DA 14mm F2.8 ED[IF]"; + choices[256*3+ 254] = "smc PENTAX-DA 16-45mm F4 ED AL"; + choices[256*3+ 255] = "SIGMA"; + choices[256*4+ 1] = "smc PENTAX-FA SOFT 28mm F2.8"; + choices[256*4+ 2] = "smc PENTAX-FA 80-320mm F4.5-5.6"; + choices[256*4+ 3] = "smc PENTAX-FA 43mm F1.9 Limited"; + choices[256*4+ 6] = "smc PENTAX-FA 35-80mm F4-5.6"; + choices[256*4+ 12] = "smc PENTAX-FA 50mm F1.4"; + choices[256*4+ 15] = "smc PENTAX-FA 28-105mm F4-5.6 [IF]"; + choices[256*4+ 16] = "TAMRON AF 80-210mm F4-5.6 (178D)"; + choices[256*4+ 19] = "TAMRON SP AF 90mm F2.8 (172E)"; + choices[256*4+ 20] = "smc PENTAX-FA 28-80mm F3.5-5.6"; + choices[256*4+ 21] = "Cosina AF 100-300mm F5.6-6.7"; + choices[256*4+ 22] = "TOKINA 28-80mm F3.5-5.6"; + choices[256*4+ 23] = "smc PENTAX-FA 20-35mm F4 AL"; + choices[256*4+ 24] = "smc PENTAX-FA 77mm F1.8 Limited"; + choices[256*4+ 25] = "TAMRON SP AF 14mm F2.8"; + choices[256*4+ 26] = "smc PENTAX-FA MACRO 100mm F3.5"; + choices[256*4+ 27] = "TAMRON AF28-300mm F/3.5-6.3 LD Aspherical[IF] MACRO (285D)"; + choices[256*4+ 28] = "smc PENTAX-FA 35mm F2 AL"; + choices[256*4+ 29] = "TAMRON AF 28-200mm F/3.8-5.6 LD Super II MACRO (371D)"; + choices[256*4+ 34] = "smc PENTAX-FA 24-90mm F3.5-4.5 AL[IF]"; + choices[256*4+ 35] = "smc PENTAX-FA 100-300mm F4.7-5.8"; + choices[256*4+ 36] = "TAMRON AF70-300mm F/4-5.6 LD MACRO"; + choices[256*4+ 37] = "TAMRON SP AF 24-135mm F3.5-5.6 AD AL (190D)"; + choices[256*4+ 38] = "smc PENTAX-FA 28-105mm F3.2-4.5 AL[IF]"; + choices[256*4+ 39] = "smc PENTAX-FA 31mm F1.8AL Limited"; + choices[256*4+ 41] = "TAMRON AF 28-200mm Super Zoom F3.8-5.6 Aspherical XR [IF] MACRO (A03)"; + choices[256*4+ 43] = "smc PENTAX-FA 28-90mm F3.5-5.6"; + choices[256*4+ 44] = "smc PENTAX-FA J 75-300mm F4.5-5.8 AL"; + choices[256*4+ 45] = "TAMRON 28-300mm F3.5-6.3 Ultra zoom XR"; + choices[256*4+ 46] = "smc PENTAX-FA J 28-80mm F3.5-5.6 AL"; + choices[256*4+ 47] = "smc PENTAX-FA J 18-35mm F4-5.6 AL"; + choices[256*4+ 49] = "TAMRON SP AF 28-75mm F2.8 XR Di (A09)"; + choices[256*4+ 51] = "smc PENTAX-D FA 50mm F2.8 MACRO"; + choices[256*4+ 52] = "smc PENTAX-D FA 100mm F2.8 MACRO"; + choices[256*4+ 75] = "TAMRON SP AF 70-200 F2.8 Di LD [IF] Macro (A001)"; + choices[256*4+ 229] = "smc PENTAX-DA 18-55mm F3.5-5.6 AL II"; + choices[256*4+ 230] = "TAMRON SP AF 17-50mm F2.8 XR Di II"; + choices[256*4+ 231] = "smc PENTAX-DA 18-250mm F3.5-6.3 ED AL [IF]"; + choices[256*4+ 237] = "Samsung/Schneider D-XENOGON 10-17mm F3.5-4.5"; + choices[256*4+ 239] = "Samsung D-XENON 12-24mm F4 ED AL [IF]"; + choices[256*4+ 243] = "smc PENTAX-DA 70mm F2.4 Limited"; + choices[256*4+ 244] = "smc PENTAX-DA 21mm F3.2 AL Limited"; + choices[256*4+ 245] = "Schneider D-XENON 50-200mm"; + choices[256*4+ 246] = "Schneider D-XENON 18-55mm"; + choices[256*4+ 247] = "smc PENTAX-DA 10-17mm F3.5-4.5 ED [IF] Fisheye zoom"; + choices[256*4+ 248] = "smc PENTAX-DA 12-24mm F4 ED AL [IF]"; + choices[256*4+ 249] = "TAMRON XR DiII 18-200mm F3.5-6.3 (A14)"; + choices[256*4+ 250] = "smc PENTAX-DA 50-200mm F4-5.6 ED"; + choices[256*4+ 251] = "smc PENTAX-DA 40mm F2.8 Limited"; + choices[256*4+ 252] = "smc PENTAX-DA 18-55mm F3.5-5.6 AL"; + choices[256*4+ 253] = "smc PENTAX-DA 14mm F2.8 ED[IF]"; + choices[256*4+ 254] = "smc PENTAX-DA 16-45mm F4 ED AL"; + choices[256*5+ 1] = "smc PENTAX-FA* 24mm F2 AL[IF]"; + choices[256*5+ 2] = "smc PENTAX-FA 28mm F2.8 AL"; + choices[256*5+ 3] = "smc PENTAX-FA 50mm F1.7"; + choices[256*5+ 4] = "smc PENTAX-FA 50mm F1.4"; + choices[256*5+ 5] = "smc PENTAX-FA* 600mm F4 ED[IF]"; + choices[256*5+ 6] = "smc PENTAX-FA* 300mm F4.5 ED[IF]"; + choices[256*5+ 7] = "smc PENTAX-FA 135mm F2.8 [IF]"; + choices[256*5+ 8] = "smc PENTAX-FA MACRO 50mm F2.8"; + choices[256*5+ 9] = "smc PENTAX-FA MACRO 100mm F2.8"; + choices[256*5+ 10] = "smc PENTAX-FA* 85mm F1.4 [IF]"; + choices[256*5+ 11] = "smc PENTAX-FA* 200mm F2.8 ED[IF]"; + choices[256*5+ 12] = "smc PENTAX-FA 28-80mm F3.5-4.7"; + choices[256*5+ 13] = "smc PENTAX-FA 70-200mm F4-5.6"; + choices[256*5+ 14] = "smc PENTAX-FA* 250-600mm F5.6 ED[IF]"; + choices[256*5+ 15] = "smc PENTAX-FA 28-105mm F4-5.6"; + choices[256*5+ 16] = "smc PENTAX-FA 100-300mm F4.5-5.6"; + choices[256*5+ 98] = "smc PENTAX-FA 100-300mm F4.5-5.6"; + choices[256*6+ 1] = "smc PENTAX-FA* 85mm F1.4 [IF]"; + choices[256*6+ 2] = "smc PENTAX-FA* 200mm F2.8 ED[IF]"; + choices[256*6+ 3] = "smc PENTAX-FA* 300mm F2.8 ED[IF]"; + choices[256*6+ 4] = "smc PENTAX-FA* 28-70mm F2.8 AL"; + choices[256*6+ 5] = "smc PENTAX-FA* 80-200mm F2.8 ED[IF]"; + choices[256*6+ 6] = "smc PENTAX-FA* 28-70mm F2.8 AL"; + choices[256*6+ 7] = "smc PENTAX-FA* 80-200mm F2.8 ED[IF]"; + choices[256*6+ 8] = "smc PENTAX-FA 28-70mm F4AL"; + choices[256*6+ 9] = "smc PENTAX-FA 20mm F2.8"; + choices[256*6+ 10] = "smc PENTAX-FA* 400mm F5.6 ED[IF]"; + choices[256*6+ 13] = "smc PENTAX-FA* 400mm F5.6 ED[IF]"; + choices[256*6+ 14] = "smc PENTAX-FA* MACRO 200mm F4 ED[IF]"; + choices[256*7+ 0] = "smc PENTAX-DA 21mm F3.2 AL Limited"; + choices[256*7+ 75] = "TAMRON SP AF 70-200mm F2.8 Di LD [IF] Macro (A001)"; + choices[256*7+ 217] = "smc PENTAX-DA 50-200mm F4-5.6 ED WR"; + choices[256*7+ 218] = "smc PENTAX-DA 18-55mm F3.5-5.6 AL WR"; + choices[256*7+ 220] = "TAMRON SP AF 10-24mm F3.5-4.5 Di II LD Aspherical [IF]"; + choices[256*7+ 222] = "smc PENTAX-DA 18-55mm F3.5-5.6 AL II"; + choices[256*7+ 223] = "Samsung D-XENON 18-55mm F3.5-5.6 II"; + choices[256*7+ 224] = "smc PENTAX-DA 15mm F4 ED AL Limited"; + choices[256*7+ 225] = "Samsung D-XENON 18-250mm F3.5-6.3"; + choices[256*7+ 229] = "smc PENTAX-DA 18-55mm F3.5-5.6 AL II"; + choices[256*7+ 230] = "TAMRON AF 17-50mm F2.8 XR Di-II LD (Model A16)"; + choices[256*7+ 231] = "smc PENTAX-DA 18-250mm F3.5-6.3 ED AL [IF]"; + choices[256*7+ 233] = "smc PENTAX-DA 35mm F2.8 Macro Limited"; + choices[256*7+ 234] = "smc PENTAX-DA* 300mm F4 ED [IF] SDM (SDM unused)"; + choices[256*7+ 235] = "smc PENTAX-DA* 200mm F2.8 ED [IF] SDM (SDM unused)"; + choices[256*7+ 236] = "smc PENTAX-DA 55-300mm F4-5.8 ED"; + choices[256*7+ 238] = "TAMRON AF 18-250mm F3.5-6.3 Di II LD Aspherical [IF] MACRO"; + choices[256*7+ 241] = "smc PENTAX-DA* 50-135mm F2.8 ED [IF] SDM (SDM unused)"; + choices[256*7+ 242] = "smc PENTAX-DA* 16-50mm F2.8 ED AL [IF] SDM (SDM unused)"; + choices[256*7+ 243] = "smc PENTAX-DA 70mm F2.4 Limited"; + choices[256*7+ 244] = "smc PENTAX-DA 21mm F3.2 AL Limited"; + choices[256*8+ 226] = "smc PENTAX-DA* 55mm F1.4 SDM"; + choices[256*8+ 227] = "smc PENTAX DA* 60-250mm F4 [IF] SDM"; + choices[256*8+ 232] = "smc PENTAX-DA 17-70mm F4 AL [IF] SDM"; + choices[256*8+ 234] = "smc PENTAX-DA* 300mm F4 ED [IF] SDM"; + choices[256*8+ 235] = "smc PENTAX-DA* 200mm F2.8 ED [IF] SDM"; + choices[256*8+ 241] = "smc PENTAX-DA* 50-135mm F2.8 ED [IF] SDM"; + choices[256*8+ 242] = "smc PENTAX-DA* 16-50mm F2.8 ED AL [IF] SDM"; + choices[256*8+ 255] = "Sigma 70-200mm F2.8 EX DG Macro HSM II or 150-500mm F5-6.3 DG OS"; + } + virtual std::string toString (Tag* t) { + return choices[256*t->toInt(0,BYTE) + t->toInt(1,BYTE)]; + } +}; +PALensTypeInterpreter paLensTypeInterpreter; + +class PASRInfoInterpreter : public Interpreter { + public: + PASRInfoInterpreter () { } + + virtual std::string toString (Tag* t) { + std::ostringstream str; + int b = t->toInt(0,BYTE); + if (!b) + str << "SRResult = Not stabilized" << std::endl; + else if (b & 1) + str << "SRResult = Stabilized" << std::endl; + b = t->toInt(1,BYTE); + if (!b) + str << "ShakeReduction = Off" << std::endl; + else + str << "ShakeReduction = On" << std::endl; + str << "SRHalfPressTime = " << t->toInt(2,BYTE) << std::endl; + str << "SRFocalLength = " << t->toInt(3,BYTE); + return str.str(); + } +}; +PASRInfoInterpreter paSRInfoInterpreter; + + +const TagAttrib pentaxAttribs[] = { + 0, 1, 0, 0, 0x0001, "PentaxVersion", &stdInterpreter, + 0, 1, 0, 0, 0x0001, "PentaxModelType", &stdInterpreter, + 0, 2, 0, 0, 0x0002, "PreviewImageSize", &stdInterpreter, + 0, 2, 0, 0, 0x0003, "PreviewImageLength", &stdInterpreter, + 0, 2, 0, 0, 0x0004, "PreviewImageStart", &stdInterpreter, + 0, 1, 0, 0, 0x0005, "PentaxModelID", &stdInterpreter, + 0, 1, 0, 0, 0x0006, "Date", &stdInterpreter, + 0, 1, 0, 0, 0x0007, "Time", &stdInterpreter, + 0, 1, 0, 0, 0x0008, "Quality", &paQualityInterpreter, + 0, 1, 0, 0, 0x0009, "PentaxImageSize", &stdInterpreter, + 0, 1, 0, 0, 0x000b, "PictureMode", &paPictureModeInterpreter, + 0, 1, 0, 0, 0x000c, "FlashMode", &paFlashModeInterpreter, + 0, 1, 0, 0, 0x000d, "FocusMode", &paFocusModeInterpreter, + 0, 1, 0, 0, 0x000e, "AFPointSelected", &paAFPointInterpreter, + 0, 1, 0, 0, 0x000f, "AFPointsInFocus", &paAFFocusInterpreter, + 0, 1, 0, 0, 0x0010, "FocusPosition", &stdInterpreter, + 0, 1, 0, 0, 0x0012, "ExposureTime", &stdInterpreter, + 0, 1, 0, 0, 0x0013, "FNumber", &stdInterpreter, + 0, 1, 0, 0, 0x0014, "ISO", &paISOInterpreter, + 0, 1, 0, 0, 0x0015, "LightReading", &stdInterpreter, + 0, 1, 0, 0, 0x0016, "ExposureCompensation", &stdInterpreter, + 0, 1, 0, 0, 0x0017, "MeteringMode", &paMeteringModeInterpreter, + 0, 1, 0, 0, 0x0018, "AutoBracketing", &stdInterpreter, + 0, 1, 0, 0, 0x0019, "WhiteBalance", &paWhiteBalanceInterpreter, + 0, 1, 0, 0, 0x001a, "WhiteBalanceMode", &paWhiteBalanceModeInterpreter, + 0, 1, 0, 0, 0x001b, "BlueBalance", &stdInterpreter, + 0, 1, 0, 0, 0x001c, "RedBalance", &stdInterpreter, + 0, 1, 0, 0, 0x001d, "FocalLength", &stdInterpreter, + 0, 1, 0, 0, 0x001e, "DigitalZoom", &stdInterpreter, + 0, 1, 0, 0, 0x001f, "Saturation", &paSaturationInterpreter, + 0, 1, 0, 0, 0x0020, "Contrast", &paContrastInterpreter, + 0, 1, 0, 0, 0x0021, "Sharpness", &paSharpnessInterpreter, + 0, 1, 0, 0, 0x0022, "WorldTimeLocation", &stdInterpreter, + 0, 1, 0, 0, 0x0023, "HometownCity", &stdInterpreter, + 0, 3, 0, 0, 0x0024, "DestinationCity", &stdInterpreter, + 0, 3, 0, 0, 0x0025, "HometownDST", &stdInterpreter, + 0, 1, 0, 0, 0x0026, "DestinationDST", &stdInterpreter, + 0, 1, 0, 0, 0x0027, "DSPFirmwareVersion", &stdInterpreter, + 0, 1, 0, 0, 0x0028, "CPUFirmwareVersion", &stdInterpreter, + 0, 1, 0, 0, 0x0029, "FrameNumber", &stdInterpreter, + 0, 1, 0, 0, 0x002d, "EffectiveLV", &stdInterpreter, + 0, 1, 0, 0, 0x0032, "ImageProcessing", &stdInterpreter, + 0, 1, 0, 0, 0x0033, "PictureMode", &stdInterpreter, + 0, 1, 0, 0, 0x0034, "DriveMode", &stdInterpreter, + 0, 1, 0, 0, 0x0037, "ColorSpace", &stdInterpreter, + 0, 1, 0, 0, 0x0038, "ImageAreaOffset", &stdInterpreter, + 0, 1, 0, 0, 0x0039, "RawImageSize", &stdInterpreter, + 0, 1, 0, 0, 0x003c, "AFPointsInFocus", &stdInterpreter, + 0, 1, 0, 0, 0x003e, "PreviewImageBorders", &stdInterpreter, + 0, 1, 0, 0, 0x003f, "LensType", &paLensTypeInterpreter, + 0, 1, 0, 0, 0x0040, "SensitivityAdjust", &stdInterpreter, + 0, 1, 0, 0, 0x0041, "ImageProcessingCount", &stdInterpreter, + 0, 1, 0, 0, 0x0047, "CameraTemperature", &stdInterpreter, + 0, 1, 0, 0, 0x0048, "AELock", &paOnOffInterpreter, + 0, 1, 0, 0, 0x0049, "NoiseReduction", &paOnOffInterpreter, + 0, 1, 0, 0, 0x004d, "FlashExposureComp", &stdInterpreter, + 0, 1, 0, 0, 0x004f, "ImageTone", &stdInterpreter, + 0, 1, 0, 0, 0x0050, "ColorTemperature", &stdInterpreter, + 0, 1, 0, 0, 0x005c, "ShakeReductionInfo", &paSRInfoInterpreter, + 0, 1, 0, 0, 0x005d, "ShutterCount", &stdInterpreter, + 0, 1, 0, 0, 0x0200, "BlackPoint", &stdInterpreter, + 0, 1, 0, 0, 0x0201, "WhitePoint", &stdInterpreter, + 0, 1, 0, 0, 0x0205, "ShotInfo", &stdInterpreter, + 0, 1, 0, 0, 0x0206, "AEInfo", &stdInterpreter, + 0, 1, 0, 0, 0x0207, "LensInfo", &stdInterpreter, + 0, 1, 0, 0, 0x0208, "FlashInfo", &stdInterpreter, + 0, 1, 0, 0, 0x0209, "AEMeteringSegments", &stdInterpreter, + 0, 1, 0, 0, 0x020a, "FlashADump", &stdInterpreter, + 0, 1, 0, 0, 0x020b, "FlashBDump", &stdInterpreter, + 0, 1, 0, 0, 0x020d, "WB_RGGBLevelsDaylight", &stdInterpreter, + 0, 1, 0, 0, 0x020e, "WB_RGGBLevelsShade", &stdInterpreter, + 0, 1, 0, 0, 0x020f, "WB_RGGBLevelsCloudy", &stdInterpreter, + 0, 1, 0, 0, 0x0210, "WB_RGGBLevelsTungsten", &stdInterpreter, + 0, 1, 0, 0, 0x0211, "WB_RGGBLevelsFluorescentD", &stdInterpreter, + 0, 1, 0, 0, 0x0212, "WB_RGGBLevelsFluorescentN", &stdInterpreter, + 0, 1, 0, 0, 0x0213, "WB_RGGBLevelsFluorescentW", &stdInterpreter, + 0, 1, 0, 0, 0x0214, "WB_RGGBLevelsFlash", &stdInterpreter, + 0, 1, 0, 0, 0x0215, "CameraInfo", &stdInterpreter, + 0, 1, 0, 0, 0x0216, "BatteryInfo", &stdInterpreter, + 0, 1, 0, 0, 0x021f, "AFInfo", &stdInterpreter, + 0, 1, 0, 0, 0x0222, "ColorInfo", &stdInterpreter, + 0, 1, 0, 0, 0x03fe, "DataDump", &stdInterpreter, + 0, 1, 0, 0, 0x03ff, "UnknownInfo", &stdInterpreter, + 0, 1, 0, 0, 0x0402, "ToneCurve", &stdInterpreter, + 0, 1, 0, 0, 0x0403, "ToneCurves", &stdInterpreter, + 0, 1, 0, 0, 0x0e00, "PrintIM", &stdInterpreter, + -1, 0, 0, 0, 0, "", NULL}; +}; + #endif + diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc new file mode 100644 index 000000000..a61f3050d --- /dev/null +++ b/rtexif/rtexif.cc @@ -0,0 +1,1434 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * Some parts of the source code (e.g. ciff support) are taken from dcraw + * that is copyrighted by Dave Coffin + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include + +namespace rtexif { + +StdInterpreter stdInterpreter; + +//--------------- class TagDirectory ------------------------------------------ +// this class is a collection (an array) of tags +//----------------------------------------------------------------------------- + +#define TAG_SUBFILETYPE 0x00fe + +TagDirectory::TagDirectory () + : attribs(ifdAttribs), parent(NULL), order(INTEL) {} + +TagDirectory::TagDirectory (TagDirectory* p, const TagAttrib* ta, ByteOrder border) + : attribs(ta), order(border), parent(p) {} + +TagDirectory::TagDirectory (TagDirectory* p, FILE* f, int base, const TagAttrib* ta, ByteOrder border) { + + attribs = ta; + order = border; + parent = p; + + int numOfTags = get2 (f, order); + if (numOfTags<=0 || numOfTags>200) + return; + + bool thumbdescr = false; + for (int i=0; igetType()==0) { + delete newTag; + continue; + } + + int id = newTag->getID(); + + // detect and possibly ignore tags of directories belonging to the embedded thumbnail image + if (attribs==ifdAttribs && id==TAG_SUBFILETYPE && newTag->toInt()!=0) + thumbdescr = true; + + const TagAttrib* attrib = getAttrib (id); + + if (!attrib || attrib->ignore==1 || (thumbdescr && attrib->ignore==2)) + delete newTag; + else + addTag (newTag); + } +} + +TagDirectory::~TagDirectory () { + + for (int i=0; igetID() < b->getID(); + } +}; + +void TagDirectory::sort () { + + std::sort (tags.begin(), tags.end(), CompareTags()); + for (int i=0; iisDirectory()) + for (int j=0; tags[i]->getDirectory(j); j++) + tags[i]->getDirectory(j)->sort (); +} + +const TagAttrib* TagDirectory::getAttrib (int id) { + + if (attribs) + for (int i=0; attribs[i].ignore!=-1; i++) + if (attribs[i].ID==id) + return &attribs[i]; + + return NULL; +} + +const TagAttrib* TagDirectory::getAttrib (const char* name) { + + if (attribs) + for (int i=0; attribs[i].ignore!=-1; i++) + if (!strcmp (attribs[i].name, name)) + return &attribs[i]; + + return NULL; +} + +void TagDirectory::printAll () const { + + for (int i=0; inameToString (); + if (tags[i]->isDirectory()) + for (int j=0; tags[i]->getDirectory(j); j++) { + printf ("==== DIRECTORY %s[%d]: ====\n", name.c_str(), j); + tags[i]->getDirectory(j)->printAll (); + printf ("==== END OF DIRECTORY %s[%d] ====\n", name.c_str(), j); + } + else { + std::string value = tags[i]->valueToString (); + printf ("%s: %s\n", name.c_str(), value.c_str()); + } + } +} + +void TagDirectory::addTag (Tag* tag) { + + // look up if it already exists: + if (getTag (tag->getID())) + delete tag; + else + tags.push_back (tag); +} + +void TagDirectory::addTagFront (Tag* tag) { + + // look up if it already exists: + if (getTag (tag->getID())) + delete tag; + else + tags.insert (tags.begin(), tag); +} + +void TagDirectory::replaceTag (Tag* tag) { + + // look up if it already exists: + for (int i=0; igetID()==tag->getID()) { + delete tags[i]; + tags[i] = tag; + return; + } + tags.push_back (tag); +} + +Tag* TagDirectory::getTag (int ID) { + + for (int i=0; igetID()==ID) + return tags[i]; + return NULL; +} + +Tag* TagDirectory::getTag (const char* name) { + + if (attribs) { + for (int i=0; attribs[i].ignore!=-1; i++) + if (!strcmp (attribs[i].name, name)) + return getTag (attribs[i].ID); + } + return NULL; +} + +int TagDirectory::calculateSize () { + + int size = 2; // space to store the number of tags + for (int i=0; igetKeep()) + size += 12 + tags[i]->calculateSize (); + + size += 4; // next ifd pointer + return size; +} + +TagDirectory* TagDirectory::clone (TagDirectory* parent) { + + TagDirectory* td = new TagDirectory (parent, attribs, order); + for (int i=0; itags.push_back (tags[i]->clone (td)); + return td; +} + +int TagDirectory::write (int start, unsigned char* buffer) { + + int size = calculateSize (); + int tagnum = 0; + int nondirspace = 0; + for (int i=0; igetKeep()) { + tagnum++; + if (!tags[i]->isDirectory()) + nondirspace += tags[i]->calculateSize(); + } + int nextValOffs = start + 2 + tagnum * 12 + 4; + int nextDirOffs = nextValOffs + nondirspace; + int pos = start; + sset2 (tagnum, buffer+start, order); + pos += 2; + int maxPos = start + size; + for (int i=0; igetKeep()) { + if (!tags[i]->isDirectory()) + nextValOffs = tags[i]->write (pos, nextValOffs, buffer); // pos: where to put the tag, dataoffset: the place where the value can be put. return: next data offset + else + nextDirOffs = tags[i]->write (pos, nextDirOffs, buffer); // pos: where to put the tag, dataoffset: the place where the value can be put. return: next data offset + + pos += 12; + } + } + sset4 (0, buffer+pos, order); + return maxPos; +} + +void TagDirectory::applyChange (std::string name, std::string value) { + + std::string::size_type dp = name.find_first_of ('.'); + std::string fseg = name.substr (0,dp); + // this is a final segment: apply change + if (dp==std::string::npos) { + + Tag* t = NULL; + for (int i=0; inameToString()==fseg) { + t = tags[i]; + break; + } + + if (value=="#keep" && t) + t->setKeep (true); + else if (value=="#delete" && t) + t->setKeep (false); + else if (t && !t->isDirectory()) + t->valueFromString (value); + else { + const TagAttrib* attrib = NULL; + for (int i=0; attribs[i].ignore!=-1; i++) + if (!strcmp (attribs[i].name, fseg.c_str())) { + attrib = &attribs[i]; + break; + } + if (attrib) { + Tag* nt = new Tag (this, attrib); + nt->initString (value.c_str()); + addTag (nt); + } + } + } + // this is a subdirectory + else { + // try to find it + std::string::size_type dp1 = fseg.find_first_of ('['); + std::string::size_type dp2 = fseg.find_first_of (']'); + std::string basename = fseg.substr (0,dp1); + Tag* t = NULL; + int dirnum = -1; + for (int i=0; iisDirectory()) { + for (int j=0; tags[i]->getDirectory(j); j++) { + if (tags[i]->nameToString(j) == fseg) { + t = tags[i]; + dirnum = j; + break; + } + } + if (!t && tags[i]->nameToString() == basename) { // found it, but that directory index does not exist + t = tags[i]; + dirnum = -1; + } + } + if (!t && value!="#keep" && value!="#delete") { + const TagAttrib* attrib = NULL; + for (int i=0; attribs[i].ignore!=-1; i++) + if (!strcmp (attribs[i].name, fseg.c_str())) { + attrib = &attribs[i]; + break; + } + if (attrib && attrib->subdirAttribs) { + t = new Tag (this, attrib); + t->initSubDir (); + addTag (t); + } + dirnum = 0; + } + if (t && dirnum>=0) + t->getDirectory(dirnum)->applyChange (name.substr (dp+1, std::string::npos), value); + } +} + +//--------------- class Tag --------------------------------------------------- +// this class represents a tag stored in the directory +//----------------------------------------------------------------------------- + +Tag::Tag (TagDirectory* p, FILE* f, int base) + : parent(p), value(NULL), directory(NULL), count(0), attrib(NULL), type(INVALID) { + + tag = get2 (f, getOrder()); + type = (TagType)get2 (f, getOrder()); + count = get4 (f, getOrder()); + + makerNoteKind = NOMK; + keep = false; + + // filter out invalid tags + if ((int)type<1 || (int)type>14 || count>900000 || count<0) { + type = INVALID; + return; + } + + // save file position + int save = ftell(f) + 4; + + // load value field (possibly seek before) + valuesize = count * ("11124811248484"[type<14?type:0]-'0'); + + if (valuesize > 4) + fseek (f, get4(f, getOrder()) + base, SEEK_SET); + + attrib = parent->getAttrib (tag); + + if (attrib && (attrib->action==1 || attrib->action==3)) + keep = true; + + // if this tag is the makernote, it needs special treatment (brand specific parsing) + if (tag==0x927C && attrib && !strcmp (attrib->name, "MakerNote")) { + value = NULL; + // select format of makernote + char make[128], model[128]; + Tag* tmake = parent->getParent()->getTag ("Make"); + if (tmake) + tmake->toString (make); + else + make[0] = 0; + Tag* tmodel = parent->getParent()->getTag ("Model"); + if (tmodel) + tmodel->toString (model); + else + model[0] = 0; + if (!strncmp(make, "NIKON", 5)) { + if (!strncmp(model, "NIKON E700",10)||!strncmp(model, "NIKON E800",10)||!strncmp(model, "NIKON E900",10)||!strncmp(model, "NIKON E900S",11)||!strncmp(model, "NIKON E910", 10)||!strncmp(model, "NIKON E950", 10)) { + makerNoteKind = HEADERIFD; + valuesize = 8; + value = new unsigned char[8]; + fread (value, 1, 8, f); + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, base, nikon2Attribs, getOrder()); + directory[1] = NULL; + } + else if (!strncmp(model, "NIKON E990",10)||(!strncmp(model, "NIKON D1",8) && model[8]!='0')) { + makerNoteKind = IFD; + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, base, nikon3Attribs, getOrder()); + directory[1] = NULL; + } + else { + // needs refinement! (embedded tiff header parsing) + makerNoteKind = NIKON3; + valuesize = 18; + value = new unsigned char[18]; + int basepos = ftell (f); + fread (value, 1, 18, f); + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, basepos+10, nikon3Attribs, getOrder()); + directory[1] = NULL; + } + } + else if (!strncmp(make, "Canon", 5)) { + makerNoteKind = IFD; + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, base, canonAttribs, getOrder()); + directory[1] = NULL; + } + else if (!strncmp(make, "PENTAX", 6)) { + makerNoteKind = HEADERIFD; + valuesize = 6; + value = new unsigned char[6]; + fread (value, 1, 6, f); + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, base, pentaxAttribs, getOrder()); + directory[1] = NULL; + } + else if (!strncmp(make, "FUJIFILM", 8)) { + makerNoteKind = FUJI; + valuesize = 12; + value = new unsigned char[12]; + fread (value, 1, 12, f); + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, ftell(f)-12, fujiAttribs, INTEL); + directory[1] = NULL; + } + else if (!strncmp(make, "KONICA MINOLTA", 14) || !strncmp(make, "Minolta", 7)) { + makerNoteKind = IFD; + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, base, minoltaAttribs, getOrder()); + directory[1] = NULL; + } + else if (!strncmp(make, "SONY", 4)) { + valuesize = 12; + value = new unsigned char[12]; + fread (value, 1, 12, f); + if (!strncmp((char*)value, "SONY DSC", 8)) + makerNoteKind = HEADERIFD; + else { + makerNoteKind = IFD; + fseek (f, -12, SEEK_CUR); + } + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, base, sonyAttribs, getOrder()); + directory[1] = NULL; + } + else if (!strncmp(make, "OLYMPUS", 7)) { + makerNoteKind = HEADERIFD; + valuesize = 8; + value = new unsigned char[12]; + fread (value, 1, 8, f); + directory = new TagDirectory*[2]; + directory[1] = NULL; + if (!strncmp((char*)value, "OLYMPUS", 7)) { + makerNoteKind = OLYMPUS2; + fread (value+8, 1, 4, f); + valuesize = 12; + directory[0] = new TagDirectory (parent, f, ftell(f)-12, olympusAttribs, value[8]=='I' ? INTEL : MOTOROLA); + } + else + directory[0] = new TagDirectory (parent, f, base, olympusAttribs, getOrder()); + } + else { + type = INVALID; + fseek (f, save, SEEK_SET); + return; + } + } + else if (type==UNDEFINED && attrib && attrib->subdirAttribs) { + count = 1; + type = LONG; + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, base, attrib->subdirAttribs, getOrder()); + directory[1] = NULL; + } + else { + // read value + value = new unsigned char [valuesize]; + fread (value, 1, valuesize, f); + + // if it is a subdirectory, load it (there may be several directories if count>1) + if (attrib && attrib->subdirAttribs) { + int pos = ftell (f); + // count the number of valid subdirs + int sdcount = count; + if (sdcount>0) { + if (parent->getAttribTable()==olympusAttribs) + sdcount = 1; + // allocate space + directory = new TagDirectory*[sdcount+1]; + // load directories + for (int j=0,i=0; jsubdirAttribs, getOrder()); + fseek (f, pos, SEEK_SET); + } + // set the terminating NULL + directory[sdcount] = NULL; + } + else + type = INVALID; + } + } + // seek back to the saved position + fseek (f, save, SEEK_SET); +} + +Tag* Tag::clone (TagDirectory* parent) { + + Tag* t = new Tag (parent, attrib); + + t->tag = tag; + t->type = type; + t->count = count; + t->keep = keep; + t->valuesize = valuesize; + if (value) { + t->value = new unsigned char [valuesize]; + memcpy (t->value, value, valuesize); + } + else + value = NULL; + t->makerNoteKind = makerNoteKind; + if (directory) { + int ds = 0; + for (; directory[ds]; ds++); + t->directory = new TagDirectory*[ds+1]; + for (int i=0; idirectory[i] = directory[i]->clone (parent); + t->directory[ds] = NULL; + } + else + t->directory = NULL; + return t; +} + +Tag::~Tag () { + + // delete value + if (value) + delete [] value; + + // if there are directories behind the tag, delete them + int i = 0; + if (directory) { + while (directory[i]) + delete directory[i++]; + delete [] directory; + } +} + +void Tag::setInt (int v, int ofs, TagType astype) { + + if (astype==SHORT) + sset2 (v, value+ofs, getOrder()); + else if (astype==RATIONAL) { + sset4 (v, value+ofs, getOrder()); + sset4 (1, value+ofs+4, getOrder()); + } + else + sset4 (v, value+ofs, getOrder()); +} + +void Tag::fromInt (int v) { + + if (type==SHORT) + sset2 (v, value, getOrder()); + else + sset4 (v, value, getOrder()); +} + +void Tag::fromString (const char* v, int size) { + + delete value; + if (size<0) + valuesize = strlen (v) + 1; + else + valuesize = size; + count = valuesize; + value = new unsigned char [valuesize]; + memcpy ((char*)value, v, valuesize); +} + +int Tag::toInt (int ofs, TagType astype) { + + int a; + if (astype == INVALID) + astype = type; + switch (astype) { + case BYTE: return value[ofs]; + case ASCII: return 0; + case SSHORT:return (int)int2_to_signed(sget2 (value+ofs, getOrder())); + case SHORT: return (int)sget2 (value+ofs, getOrder()); + case SLONG: + case LONG: return (int)sget4 (value+ofs, getOrder()); + case SRATIONAL: + case RATIONAL: a = (int)sget4 (value+ofs+4, getOrder()); return a==0 ? 0 : (int)sget4 (value+ofs, getOrder()) / a; + case FLOAT: return (int)((float) sget4 (value+ofs, getOrder())); + case UNDEFINED: return 0; + } +} + +double Tag::toDouble (int ofs) { + + double ud, dd; + switch (type) { + case BYTE: return (double)((int)value[ofs]); + case ASCII: return 0.0; + case SSHORT:return (double)int2_to_signed(sget2 (value+ofs, getOrder())); + case SHORT: return (double)((int)sget2 (value+ofs, getOrder())); + case SLONG: + case LONG: return (double)((int)sget4 (value+ofs, getOrder())); + case SRATIONAL: + case RATIONAL: ud = (int)sget4 (value+ofs, getOrder()); dd = (int)sget4 (value+ofs+4, getOrder()); return dd==0 ? 0 : (double)ud / (double)dd; + case FLOAT: return (float) sget4 (value+ofs, getOrder()); + case UNDEFINED: return 0; + } +} + +void Tag::toRational (int& num, int& denom, int ofs) { + + switch (type) { + case BYTE: num = (int)value[ofs]; denom = 1; break; + case ASCII: num = 0; denom = 0; break; + case SSHORT: + case SHORT: num = (int)sget2 (value+ofs, getOrder()); denom = 1; break; + case SLONG: + case LONG: num = (int)sget4 (value+ofs, getOrder()); denom = 1; break; + case SRATIONAL: + case RATIONAL: num = (int)sget4 (value+ofs, getOrder()); denom = (int)sget4 (value+ofs+4, getOrder()); break; + case FLOAT: num = 0; denom = 0; break; + case UNDEFINED: num = 0; denom = 0; break; + } +} + +void Tag::toString (char* buffer, int ofs) { + + if (type==UNDEFINED && !directory) { + bool isstring = true; + int i=0; + for (i=0; i+ofs126) + isstring = false; + if (isstring) { + int j = 0; + for (i=0; i+ofs') + buffer[j++] = '\\'; + buffer[j++] = value[i+ofs]; + } + buffer[j++] = 0; + return; + } + } + else if (type==ASCII) { + sprintf (buffer, "%s", value+ofs); + return; + } + + int maxcount = 4; + if (count<4) + maxcount = count; + + strcpy (buffer, ""); + for (int i=0; i0) + strcat (buffer, ", "); + char* b = buffer + strlen(buffer); + + switch (type) { + case UNDEFINED: + case BYTE: sprintf (b, "%d", value[i+ofs]); break; + case SSHORT: + case SHORT: sprintf (b, "%d", toInt(2*i+ofs)); break; + case SLONG: + case LONG: sprintf (b, "%d", toInt(4*i+ofs)); break; + case SRATIONAL: + case RATIONAL: sprintf (b, "%d/%d", (int)sget4 (value+8*i+ofs, getOrder()), (int)sget4 (value+8*i+ofs+4, getOrder())); break; + case FLOAT: sprintf (b, "%g", toDouble(8*i+ofs)); break; + } + } + if (count > maxcount) + strcat (buffer, "..."); +} + +std::string Tag::nameToString (int i) { + + static char buffer[1024]; + if (attrib) + strcpy (buffer, attrib->name); + else + sprintf (buffer, "0x%x", tag); + if (i>0) + sprintf (buffer+strlen(buffer)-1, "[%d]", i); + return buffer; +} + +std::string Tag::valueToString () { + + static char buffer[1024]; + if (attrib && attrib->interpreter) + return attrib->interpreter->toString (this); + else { + toString (buffer); + return buffer; + } +} + +void Tag::valueFromString (const std::string& value) { + + if (attrib && attrib->interpreter) + attrib->interpreter->fromString (this, value); +} + +int Tag::calculateSize () { + int size = 0; + + if (directory) { + int j; + for (j=0; directory[j]; j++) + size += directory[j]->calculateSize (); + if (j>1) + size += 4*j; + } + else if (valuesize > 4) + size += valuesize + (valuesize%2); // we align tags to even byte positions + + if (makerNoteKind!=NOMK) + count = directory[0]->calculateSize (); + + if (makerNoteKind==NIKON3 || makerNoteKind==OLYMPUS2 || makerNoteKind==FUJI) + size += valuesize; + else if (makerNoteKind==HEADERIFD) + size += valuesize; + + return size; +} + +int Tag::write (int offs, int dataOffs, unsigned char* buffer) { + + if ((int)type==0 || offs>65500) + return dataOffs; + + sset2 (tag, buffer+offs, parent->getOrder()); + offs += 2; + unsigned short typ = type; + sset2 (typ, buffer+offs, parent->getOrder()); + offs += 2; + sset4 (count, buffer+offs, parent->getOrder()); + offs += 4; + if (!directory) { + if (valuesize>4) { + sset4 (dataOffs, buffer+offs, parent->getOrder()); + memcpy (buffer+dataOffs, value, valuesize); + if (valuesize%2) + buffer[dataOffs+valuesize] = 0; // zero padding required by the exif standard + return dataOffs + valuesize + (valuesize%2); + } + else { + memcpy (buffer+offs, value, valuesize); + return dataOffs; + } + } + else { + if (makerNoteKind==NIKON3) { + sset4 (dataOffs, buffer+offs, parent->getOrder()); + memcpy (buffer+dataOffs, value, 18); + dataOffs += 10; + dataOffs += directory[0]->write (8, buffer+dataOffs); + return dataOffs; + } + else if (makerNoteKind==OLYMPUS2 || makerNoteKind==FUJI) { + sset4 (dataOffs, buffer+offs, parent->getOrder()); + memcpy (buffer+dataOffs, value, valuesize); + dataOffs += valuesize + directory[0]->write (valuesize, buffer+dataOffs); + return dataOffs; + } + else if (makerNoteKind==HEADERIFD) { + sset4 (dataOffs, buffer+offs, parent->getOrder()); + memcpy (buffer+dataOffs, value, valuesize); + dataOffs += valuesize; + dataOffs += directory[0]->write (dataOffs, buffer); + return dataOffs; + } + else if (!directory[1]) { + sset4 (dataOffs, buffer+offs, parent->getOrder()); + return directory[0]->write (dataOffs, buffer); + } + else { + sset4 (dataOffs, buffer+offs, parent->getOrder()); + int linkOffs = dataOffs; + for (int i=0; directory[i]; i++) + dataOffs += 4; + for (int i=0; directory[i]; i++) { + sset4 (dataOffs, buffer+linkOffs, parent->getOrder()); + linkOffs += 4; + dataOffs = directory[i]->write (dataOffs, buffer); + } + return dataOffs; + } + } +} + +Tag::Tag (TagDirectory* p, const TagAttrib* attr) + : parent(p), attrib(attr), makerNoteKind (NOMK), directory(NULL), keep(true), tag(attr ? attr->ID : -1), count(0), valuesize(0), value(NULL), type(INVALID) { +} + +Tag::Tag (TagDirectory* p, const TagAttrib* attr, int data, TagType t) + : parent(p), attrib(attr), makerNoteKind (NOMK), directory(NULL), keep(true), tag(attr ? attr->ID : -1), count(1), valuesize(0), value(NULL), type(t) { + + initInt (data, t); +} + +Tag::Tag (TagDirectory* p, const TagAttrib* attr, const char* text) + : parent(p), attrib(attr), makerNoteKind (NOMK), directory(NULL), keep(true), tag(attr ? attr->ID : -1), count(1), valuesize(0), value(NULL), type(ASCII) { + + initString (text); +} + +void Tag::initInt (int data, TagType t, int cnt) { + + type = t; + if (t==LONG) + valuesize = 4; + else if (t==SHORT) + valuesize = 2; + else if (t==RATIONAL) + valuesize = 8; + + count = cnt; + valuesize *= count; + value = new unsigned char[valuesize]; + setInt (data, 0, t); +} + +void Tag::initString (const char* text) { + + type = ASCII; + count = strlen(text)+1; + valuesize = count; + value = new unsigned char[valuesize]; + strcpy ((char*)value, text); +} + +void Tag::initSubDir () { + type = LONG; + valuesize = 4; + count = 1; + value = new unsigned char[4]; + setInt (0); + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, attrib ? attrib->subdirAttribs : NULL, parent->getOrder()); + directory[1] = NULL; +} + +void Tag::initMakerNote (MNKind mnk, const TagAttrib* ta) { + type = UNDEFINED; + valuesize = 4; + count = 1; + value = new unsigned char[4]; + setInt (0); + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, ta, parent->getOrder()); + directory[1] = NULL; + makerNoteKind = mnk; +} + +void Tag::initUndefArray (const char* data, int len) { + type = UNDEFINED; + count = valuesize = len; + value = new unsigned char[valuesize]; + memcpy (value, data, len); +} + +void Tag::initLongArray (const char* data, int len) { + type = LONG; + count = (len+3)/4; + valuesize = count * 4; + value = new unsigned char[valuesize]; + memcpy (value, data, len); +} + +void Tag::initRational (int num, int den) { + count = 1; + valuesize = 8; + value = new unsigned char[8]; + type = RATIONAL; + setInt (num, 0); + setInt (den, 4); +} + +//--------------- class IFDParser --------------------------------------------- +// static functions to read tag directoryes from different kinds of files +//----------------------------------------------------------------------------- + + +const TagAttrib* lookupAttrib (const TagAttrib* dir, const char* field) { + + for (int i=0; dir[i].ignore!=-1; i++) + if (!strcmp (dir[i].name, field)) + return &dir[i]; +} + + +TagDirectory* ExifManager::parseCIFF (FILE* f, int base, int length) { + + TagDirectory* root = new TagDirectory (NULL, ifdAttribs, INTEL); + Tag* exif = new Tag (root, lookupAttrib(ifdAttribs,"Exif")); + exif->initSubDir (); + Tag* mn = new Tag (exif->getDirectory(), lookupAttrib(exifAttribs,"MakerNote")); + mn->initMakerNote (IFD, canonAttribs); + root->addTag (exif); + exif->getDirectory()->addTag (mn); + parseCIFF (f, base, length, root); + root->sort (); + return root; +} + +Tag* ExifManager::saveCIFFMNTag (FILE* f, TagDirectory* root, int len, const char* name) { + int s = ftell (f); + char* data = new char [len]; + fread (data, len, 1, f); + TagDirectory* mn = root->getTag ("Exif")->getDirectory()->getTag("MakerNote")->getDirectory(); + Tag* cs = new Tag (mn, lookupAttrib(canonAttribs, name)); + cs->initUndefArray (data, len); + mn->addTag (cs); + fseek (f, s, SEEK_SET); + return cs; +} + +void ExifManager::parseCIFF (FILE* f, int base, int length, TagDirectory* root) { + + static char buffer[1024]; + Tag* t; + + fseek (f, base+length-4, SEEK_SET); + + int dirStart = get4 (f, INTEL) + base; + fseek (f, dirStart, SEEK_SET); + + int numOfTags = get2 (f, INTEL); + + if (numOfTags > 100) return; + + float exptime, shutter, aperture, fnumber, ev; + exptime = fnumber = shutter = aperture = ev = -1000; + int focal_len, iso; + focal_len = iso = -1; + + TagDirectory* exif = root->getTag("Exif")->getDirectory(); + + time_t timestamp = time (NULL); + + for (int i=0; i> 8) + 8) | 8) == 0x38) + parseCIFF (f, ftell(f), len, root); // Parse a sub-table + + if (type == 0x0810) { + fread (buffer, 64, 1, f); + t = new Tag (root, lookupAttrib(ifdAttribs,"Artist")); + t->initString (buffer); + root->addTag (t); + } + if (type == 0x080a) { + fread (buffer, 64, 1, f); + t = new Tag (root, lookupAttrib(ifdAttribs,"Make")); + t->initString (buffer); + root->addTag (t); + fseek (f, strlen(buffer) - 63, SEEK_CUR); + fread (buffer, 64, 1, f); + t = new Tag (root, lookupAttrib(ifdAttribs,"Model")); + t->initString (buffer); + root->addTag (t); + } + if (type == 0x1818) { + ev = int_to_float(get4(f, INTEL)); + shutter = int_to_float(get4(f, INTEL)); + exptime = pow (2, -shutter); + aperture = int_to_float(get4(f, INTEL)); + fnumber = pow (2, aperture/2); + + } + if (type == 0x102d) { + Tag* t = saveCIFFMNTag (f, root, len, "CanonCameraSettings"); + int mm = t->toInt (34, SHORT); + Tag* nt = new Tag (exif, lookupAttrib(exifAttribs,"MeteringMode")); + switch (mm) { + case 0: nt->initInt (5, SHORT); break; + case 1: nt->initInt (3, SHORT); break; + case 2: nt->initInt (1, SHORT); break; + case 3: nt->initInt (5, SHORT); break; + case 4: nt->initInt (6, SHORT); break; + case 5: nt->initInt (2, SHORT); break; + } + exif->addTag (nt); + nt = new Tag (exif, lookupAttrib(exifAttribs,"MaxApertureValue")); + nt->initRational (t->toInt(52,SHORT), 32); + exif->addTag (nt); + int em = t->toInt(40,SHORT); + nt = new Tag (exif, lookupAttrib(exifAttribs,"ExposureProgram")); + switch (em) { + case 0: nt->initInt (2, SHORT); break; + case 1: nt->initInt (2, SHORT); break; + case 2: nt->initInt (4, SHORT); break; + case 3: nt->initInt (3, SHORT); break; + case 4: nt->initInt (1, SHORT); break; + default: nt->initInt (0, SHORT); break; + } + exif->addTag (nt); + nt = new Tag (exif, lookupAttrib(exifAttribs,"Flash")); + if (t->toInt(8,SHORT)==0) + nt->initInt (0, SHORT); + else + nt->initInt (1, SHORT); + exif->addTag (nt); + nt = new Tag (exif, lookupAttrib(exifAttribs,"MaxApertureValue")); + nt->initRational (t->toInt(52,SHORT), 32); + exif->addTag (nt); + } + if (type == 0x1029) + saveCIFFMNTag (f, root, len, "CanonFocalLength"); + if (type == 0x1031) + saveCIFFMNTag (f, root, len, "SensorInfo"); + if (type == 0x1033) + saveCIFFMNTag (f, root, len, "CustomFunctions"); + if (type == 0x1038) + saveCIFFMNTag (f, root, len, "CanonAFInfo"); + if (type == 0x1093) + saveCIFFMNTag (f, root, len, "CanonFileInfo"); + if (type == 0x10a9) + saveCIFFMNTag (f, root, len, "ColorBalance"); + if (type == 0x102a) { + saveCIFFMNTag (f, root, len, "CanonShotInfo"); + + iso = pow (2, (get4(f, INTEL),get2(f, INTEL))/32.0 - 4) * 50; + aperture = ((get2(f, INTEL),(short)get2(f, INTEL))/32.0); + fnumber = pow (2, aperture/2); + shutter = ((short)get2(f, INTEL))/32.0; + ev = ((short)get2(f, INTEL))/32.0; + fseek (f, 34, SEEK_CUR); + if (shutter > 1e6) shutter = get2 (f, INTEL) / 10.0; + exptime = pow (2,-shutter); + } + if (type == 0x5029) { + focal_len = len >> 16; + if ((len & 0xffff) == 2) focal_len /= 32; + } +// if (type == 0x5813) flash_used = int_to_float(len); + if (type == 0x580e) timestamp = len; + if (type == 0x180e) timestamp = get4 (f, INTEL); + if ((type | 0x4000) == 0x580e) + timestamp = mktime (gmtime (×tamp)); + fseek (f, nextPos, SEEK_SET); + } + if (shutter>-999) { + t = new Tag (exif, lookupAttrib(exifAttribs,"ShutterSpeedValue")); + t->initRational ((int)(shutter*10000), 10000); + exif->addTag (t); + } + if (exptime>-999) { + t = new Tag (exif, lookupAttrib(exifAttribs,"ExposureTime")); + t->initRational ((int)(exptime*10000), 10000); + exif->addTag (t); + } + if (aperture>-999) { + t = new Tag (exif, lookupAttrib(exifAttribs,"ApertureValue")); + t->initRational ((int)(aperture*10), 10); + exif->addTag (t); + } + if (fnumber>-999) { + t = new Tag (exif, lookupAttrib(exifAttribs,"FNumber")); + t->initRational ((int)(fnumber*10), 10); + exif->addTag (t); + } + if (ev>-999) { + t = new Tag (exif, lookupAttrib(exifAttribs,"ExposureBiasValue")); + t->initRational ((int)(ev*1000), 1000); + exif->addTag (t); + } + if (iso>0) { + t = new Tag (exif, lookupAttrib(exifAttribs,"ISOSpeedRatings")); + t->initInt (iso, LONG); + exif->addTag (t); + } + if (focal_len>0) { + t = new Tag (exif, lookupAttrib(exifAttribs,"FocalLength")); + t->initRational (focal_len*32, 32); + exif->addTag (t); + } + + if (timestamp!=time(NULL)) { + struct tm* tim = localtime (×tamp); + strftime (buffer, 20, "%Y:%m:%d %H:%M:%S", tim); + t = new Tag (exif, lookupAttrib(exifAttribs,"DateTimeOriginal")); + t->initString (buffer); + exif->addTag (t); + t = new Tag (exif, lookupAttrib(exifAttribs,"DateTimeDigitized")); + t->initString (buffer); + exif->addTag (t); + t = new Tag (root, lookupAttrib(ifdAttribs,"DateTime")); + t->initString (buffer); + root->addTag (t); + } +} + +TagDirectory* ExifManager::parse (FILE* f, int base) { + + // read tiff header + fseek (f, base, SEEK_SET); + unsigned short bo; + fread (&bo, 1, 2, f); + ByteOrder order = (ByteOrder)((int)bo); + get2 (f, order); + int firstifd = get4 (f, order); + + // seek to IFD0 + fseek (f, base+firstifd, SEEK_SET); + + // first read the IFD directory + TagDirectory* root = new TagDirectory (NULL, f, base, ifdAttribs, order); + + // fix ISO issue with nikon and panasonic cameras + Tag* exif = root->getTag ("Exif"); + if (exif && !exif->getDirectory()->getTag("ISOSpeedRatings")) { + Tag* make = root->getTag ("Make"); + if (make && !strncmp((char*)make->getValue(), "NIKON", 5)) { + Tag* mn = exif->getDirectory()->getTag("MakerNote"); + if (mn) { + Tag* iso = mn->getDirectory()->getTag("ISOSpeed"); + if (iso) { + std::string isov = iso->valueToString (); + Tag* niso = new Tag (exif->getDirectory(), exif->getDirectory()->getAttrib ("ISOSpeedRatings")); + niso->initInt (atoi(isov.c_str()), SHORT); + exif->getDirectory()->addTagFront (niso); + } + } + } + else if (make && (!strncmp((char*)make->getValue(), "Panasonic", 9) || !strncmp((char*)make->getValue(), "LEICA", 5))) { + Tag* iso = root->getTag("PanaISO"); + if (iso) { + std::string isov = iso->valueToString (); + Tag* niso = new Tag (exif->getDirectory(), exif->getDirectory()->getAttrib ("ISOSpeedRatings")); + niso->initInt (atoi(isov.c_str()), SHORT); + exif->getDirectory()->addTagFront (niso); + } + } + } + +// root->printAll (); + + return root; +} + +TagDirectory* ExifManager::parseJPEG (FILE* f) { + + fseek (f, 0, SEEK_SET); + unsigned char markerl = 0xff; + unsigned char c; + fread (&c, 1, 1, f); + const char exifid[] = "Exif\0\0"; + char idbuff[8]; + bool success = false; + int tiffbase = -1; + while (fread (&c, 1, 1, f)) { + if (c!=markerl) continue; + if (fread (&c, 1, 1, f) && c==0xe1) { // APP1 marker found + if (fread (idbuff, 1, 8, f)<8) + return NULL; + if (!memcmp(idbuff+2, exifid, 6)) { // Exif info found + tiffbase = ftell (f); + return parse (f, tiffbase); + } + } + } + return NULL; +} + +TagDirectory* ExifManager::parseTIFF (FILE* f) { + + return parse (f, 0); +} + +std::vector ExifManager::defTags; + +// forthis: the byte order will be taken from directory "forthis" +const std::vector& ExifManager::getDefaultTIFFTags (TagDirectory* forthis) { + + for (int i=0; i >& changeList, int W, int H, unsigned char* buffer) { + + // write tiff header + int offs = 6; + memcpy (buffer, "Exif\0\0", 6); + ByteOrder order = INTEL; + if (root) + order = root->getOrder (); + sset2 ((unsigned short)order, buffer+offs, order); offs += 2; + sset2 (42, buffer+offs, order); offs += 2; + sset4 (8, buffer+offs, order); offs += 4; + + TagDirectory* cl; + if (root) + cl = ((TagDirectory*)root)->clone (NULL); + else + cl = new TagDirectory (NULL, ifdAttribs, INTEL); + + for (int i=0; iapplyChange (changeList[i].first, changeList[i].second); + + getDefaultTIFFTags (cl); + + defTags[0]->setInt (W, 0, LONG); + defTags[1]->setInt (H, 0, LONG); + defTags[8]->setInt (8, 0, SHORT); + + for (int i=defTags.size()-1; i>=0; i--) + cl->replaceTag (defTags[i]->clone (cl)); + cl->sort (); + int size = cl->write (8, buffer+6); + + delete cl; + + return size + 6; +} + +int ExifManager::createTIFFHeader (const TagDirectory* root, const std::vector< std::pair >& changeList, int W, int H, int bps, const char* profiledata, int profilelen, const char* iptcdata, int iptclen, unsigned char* buffer) { + +// write tiff header + int offs = 0; + ByteOrder order = INTEL; + if (root) + order = root->getOrder (); + sset2 ((unsigned short)order, buffer+offs, order); offs += 2; + sset2 (42, buffer+offs, order); offs += 2; + sset4 (8, buffer+offs, order); offs += 4; + + TagDirectory* cl; + if (root) + cl = ((TagDirectory*)root)->clone (NULL); + else + cl = new TagDirectory (NULL, ifdAttribs, INTEL); + +// add tiff strip data + int rps = 8; + int strips = ceil((double)H/rps); + cl->replaceTag (new Tag (cl, lookupAttrib(ifdAttribs,"RowsPerStrip"), rps, LONG)); + Tag* stripBC = new Tag (cl, lookupAttrib(ifdAttribs,"StripByteCounts")); + stripBC->initInt (0, LONG, strips); + cl->replaceTag (stripBC); + Tag* stripOffs = new Tag (cl, lookupAttrib(ifdAttribs,"StripOffsets")); + stripOffs->initInt (0, LONG, strips); + cl->replaceTag (stripOffs); + for (int i=0; isetInt (rps*W*3*bps/8, i*4); + int remaining = (H-rps*floor((double)H/rps))*W*3*bps/8; + if (remaining) + stripBC->setInt (remaining, (strips-1)*4); + else + stripBC->setInt (rps*W*3*bps/8, (strips-1)*4); + if (profiledata) { + Tag* icc = new Tag (cl, lookupAttrib(ifdAttribs,"ICCProfile")); + icc->initUndefArray (profiledata, profilelen); + cl->replaceTag (icc); + } + if (iptcdata) { + Tag* iptc = new Tag (cl, lookupAttrib(ifdAttribs,"IPTCData")); + iptc->initLongArray (iptcdata, iptclen); + cl->replaceTag (iptc); + } + +// apply list of changes + for (int i=0; iapplyChange (changeList[i].first, changeList[i].second); + + // append default properties + getDefaultTIFFTags (cl); + + defTags[0]->setInt (W, 0, LONG); + defTags[1]->setInt (H, 0, LONG); + defTags[8]->setInt (bps, 0, SHORT); + + for (int i=defTags.size()-1; i>=0; i--) + cl->replaceTag (defTags[i]->clone (cl)); + +// calculate strip offsets + int size = cl->calculateSize (); + int byps = bps / 8; + for (int i=0; isetInt (size + 8 + i*rps*W*3*byps, i*4); + + cl->sort (); + int endOffs = cl->write (8, buffer); + +// cl->printAll(); + delete cl; + + return endOffs; +} + +//----------------------------------------------------------------------------- +// global functions to read byteorder dependent data +//----------------------------------------------------------------------------- +unsigned short sget2 (unsigned char *s, rtexif::ByteOrder order) { + + if (order == rtexif::INTEL) return s[0] | s[1] << 8; + else return s[0] << 8 | s[1]; +} + +int sget4 (unsigned char *s, rtexif::ByteOrder order) { + + if (order == rtexif::INTEL) return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; + else return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; +} + +unsigned short get2 (FILE* f, rtexif::ByteOrder order) { + + unsigned char str[2] = { 0xff,0xff }; + fread (str, 1, 2, f); + return rtexif::sget2 (str, order); +} + +int get4 (FILE* f, rtexif::ByteOrder order) { + + unsigned char str[4] = { 0xff,0xff,0xff,0xff }; + fread (str, 1, 4, f); + return rtexif::sget4 (str, order); +} + +void sset2 (unsigned short v, unsigned char *s, rtexif::ByteOrder order) { + + if (order == rtexif::INTEL) { + s[0] = v & 0xff; v >>= 8; + s[1] = v; + } + else { + s[1] = v & 0xff; v >>= 8; + s[0] = v; + } +} + +void sset4 (int v, unsigned char *s, rtexif::ByteOrder order) { + + if (order == rtexif::INTEL) { + s[0] = v & 0xff; v >>= 8; + s[1] = v & 0xff; v >>= 8; + s[2] = v & 0xff; v >>= 8; + s[3] = v; + } + else { + s[3] = v & 0xff; v >>= 8; + s[2] = v & 0xff; v >>= 8; + s[1] = v & 0xff; v >>= 8; + s[0] = v; + } +} + +float int_to_float (int i) { + union { int i; float f; } u; + u.i = i; + return u.f; +} + +short int int2_to_signed (short unsigned int i) { + union { short unsigned int i; short int s; } u; + u.i = i; + return u.s; +} + +/* Function to parse and extract focal length and aperture information from description + * @fullname must conform to the following formats + * mm f/ + * -mm f/ + * -mm f/- + * NB: no space between separator '-'; no space between focal length and 'mm' + */ +bool extractLensInfo(std::string &fullname,double &minFocal, double &maxFocal, double &maxApertureAtMinFocal, double &maxApertureAtMaxFocal) +{ + minFocal=0.0; + maxFocal=0.0; + maxApertureAtMinFocal=0.0; + maxApertureAtMaxFocal=0.0; + + int iAperture = fullname.find("f/"); + if( iAperture != std::string::npos ){ + char meno; + std::istringstream apertures( std::string(fullname,iAperture+2) ); + apertures >> maxApertureAtMinFocal; + if( !apertures.eof()) + apertures >> meno; + if( !apertures.eof()) + apertures >> maxApertureAtMaxFocal; + if(maxApertureAtMinFocal >0. && maxApertureAtMaxFocal==0.) + maxApertureAtMaxFocal= maxApertureAtMinFocal; + + int eFocal = fullname.rfind("mm",iAperture); + if( eFocal != -1 ){ + int iFocal = fullname.rfind(' ',eFocal); // find first space leading focal length + if( iFocal == std::string::npos ) + iFocal = 0; + + std::istringstream focals( std::string(fullname,iFocal,eFocal-iFocal) ); + focals >> minFocal; + if( !focals.eof()) + focals >> meno; + if( !focals.eof()) + focals >> maxFocal; + if(minFocal >0. && maxFocal==0.0) + maxFocal=minFocal; + + return true; + } + return false; + } + return false; +} + + +} diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h new file mode 100644 index 000000000..eee6f2df9 --- /dev/null +++ b/rtexif/rtexif.h @@ -0,0 +1,249 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _MEXIF3_ +#define _MEXIF3_ + +#include +#include +#include +#include +#include + +namespace rtexif { + +enum TagType {INVALID=0, BYTE=1, ASCII=2, SHORT=3, LONG=4, RATIONAL=5, UNDEFINED=7, SSHORT=8, SLONG=9, SRATIONAL=10, FLOAT=11, DOUBLE=12, OLYUNDEF=13, SUBDIR=99}; +enum ActionCode {DONTWRITE=0, WRITE=1, SYSTEM=2}; +enum ByteOrder {INTEL=0x4949, MOTOROLA=0x4D4D}; +enum MNKind {NOMK, IFD, HEADERIFD, NIKON3, OLYMPUS2, FUJI}; + +struct TIFFHeader { + + unsigned short byteOrder; + unsigned short fixed; + unsigned int ifdOffset; +}; + +class Tag; +class Interpreter; + +// structure of informations describing an exif tag +struct TagAttrib { + int ignore; // =0: never ignore, =1: always ignore, =2: ignore if the subdir type is reduced image, =-1: end of table + int action; //=0: dont write it to the output, =1: write it to the output, =2: dont write, dont show, =3: write, dont show + int editable; + const TagAttrib* subdirAttribs; // =0 ->not subdir + unsigned short ID; + const char* name; + Interpreter* interpreter; +}; + +// a directory of tags +class TagDirectory { + + protected: + std::vector tags; // tags in the directory + const TagAttrib* attribs; // descriptor table to decode the tags + ByteOrder order; // byte order + TagDirectory* parent; // parent directory (NULL if root) + + public: + TagDirectory (); + TagDirectory (TagDirectory* p, FILE* f, int base, const TagAttrib* ta, ByteOrder border); + TagDirectory (TagDirectory* p, const TagAttrib* ta, ByteOrder border); + ~TagDirectory (); + + inline ByteOrder getOrder () const { return order; } + TagDirectory* getParent () { return parent; } + inline int getCount () const { return tags.size (); } + const TagAttrib* getAttrib (int id); + const TagAttrib* getAttrib (const char* name); + const TagAttrib* getAttribTable() { return attribs; } + Tag* getTag (const char* name); + Tag* getTag (int ID); + void addTag (Tag* a); + void addTagFront (Tag* a); + void replaceTag (Tag* a); + inline Tag* getTagByIndex (int ix) { return tags[ix]; } + inline void setOrder (ByteOrder bo) { order = bo; } + + int calculateSize (); + int write (int start, unsigned char* buffer); + TagDirectory* clone (TagDirectory* parent); + void applyChange (std::string field, std::string value); + + void printAll () const; + void sort (); +}; + +// a class representing a single tag +class Tag { + + protected: + unsigned short tag; + TagType type; + unsigned int count; + unsigned char* value; + int valuesize; + bool keep; + + const TagAttrib* attrib; + TagDirectory* parent; + TagDirectory** directory; + MNKind makerNoteKind; + + public: + Tag (TagDirectory* parent, FILE* f, int base); // parse next tag from the file + Tag (TagDirectory* parent, const TagAttrib* attr); + Tag (TagDirectory* parent, const TagAttrib* attr, int data, TagType t); // create a new tag from array (used + Tag (TagDirectory* parent, const TagAttrib* attr, const char* data); // create a new tag from array (used + ~Tag (); + void initInt (int data, TagType t, int count=1); + void initString (const char* text); + void initSubDir (); + void initMakerNote (MNKind mnk, const TagAttrib* ta); + void initUndefArray (const char* data, int len); + void initLongArray (const char* data, int len); + void initRational (int num, int den); + + // get basic tag properties + int getID () const { return tag; } + int getCount () const { return count; } + TagType getType () const { return type; } + unsigned char* getValue () const { return value; } + const TagAttrib* getAttrib () const { return attrib; } + inline ByteOrder getOrder () const { return parent ? parent->getOrder() : INTEL; } + inline TagDirectory* getParent () const { return parent; } + int getValueSize () const { return valuesize; } + + // read/write value + int toInt (int ofs=0, TagType astype=INVALID); + void fromInt (int v); + double toDouble (int ofs=0); + void toRational (int& num, int& denom, int ofs=0); + void toString (char* buffer, int ofs=0); + void fromString (const char* v, int size=-1); + void setInt (int v, int ofs=0, TagType astype=LONG); + + // additional getter/setter for more confortable use + std::string valueToString (); + std::string nameToString (int i=0); + void valueFromString (const std::string& value); + + // functions for writing + int calculateSize (); + int write (int offs, int dataOffs, unsigned char* buffer); + Tag* clone (TagDirectory* parent); + + // to control if the tag shall be written + bool getKeep () { return keep; } + void setKeep (bool k) { keep = k; } + + // get subdirectory (there can be several, the last is NULL) + bool isDirectory () { return directory!=NULL; } + TagDirectory* getDirectory (int i=0) { return directory[i]; } + + MNKind getMakerNoteFormat () { return makerNoteKind; } + }; + +class ExifManager { + + static std::vector defTags; + + static Tag* saveCIFFMNTag (FILE* f, TagDirectory* root, int len, const char* name); + public: + static TagDirectory* parse (FILE*f, int base); + static TagDirectory* parseJPEG (FILE*f); + static TagDirectory* parseTIFF (FILE*f); + static TagDirectory* parseCIFF (FILE* f, int base, int length); + static void parseCIFF (FILE* f, int base, int length, TagDirectory* root); + + static const std::vector& getDefaultTIFFTags (TagDirectory* forthis); + static int createJPEGMarker (const TagDirectory* root, const std::vector< std::pair >& changeList, int W, int H, unsigned char* buffer); + static int createTIFFHeader (const TagDirectory* root, const std::vector< std::pair >& changeList, int W, int H, int bps, const char* profiledata, int profilelen, const char* iptcdata, int iptclen, unsigned char* buffer); +}; + +class Interpreter { + protected: + char buffer[1024]; + public: + Interpreter () {} + virtual std::string toString (Tag* t) { return ""; } + virtual void fromString (Tag* t, const std::string& value) {} +}; + +class StdInterpreter : public Interpreter { + public: + StdInterpreter () {} + virtual std::string toString (Tag* t) { + t->toString (buffer); + std::string s(buffer); + std::string::size_type p1 = s.find_first_not_of(' '); + if( p1 == std::string::npos ) + return s; + else + return s.substr(p1, s.find_last_not_of(' ')-p1+1); + } + virtual void fromString (Tag* t, const std::string& value) { + if (t->getType()==SHORT || t->getType()==LONG) + t->fromInt (atoi(value.c_str())); + else + t->fromString (value.c_str()); + } +}; +extern StdInterpreter stdInterpreter; +class ChoiceInterpreter : public Interpreter { + protected: + std::map choices; + public: + ChoiceInterpreter () {}; + virtual std::string toString (Tag* t) { + std::map::iterator r = choices.find (t->toInt()); + if (r!=choices.end()) + return r->second; + else { + t->toString (buffer); + return std::string (buffer); + } + } +}; + +inline unsigned short sget2 (unsigned char *s, ByteOrder order); +inline int sget4 (unsigned char *s, ByteOrder order); +inline unsigned short get2 (FILE* f, ByteOrder order); +inline int get4 (FILE* f, ByteOrder order); +inline void sset2 (unsigned short v, unsigned char *s, ByteOrder order); +inline void sset4 (int v, unsigned char *s, ByteOrder order); +inline float int_to_float (int i); +inline short int int2_to_signed (short unsigned int i); +bool extractLensInfo(std::string &fullname,double &minFocal, double &maxFocal, double &maxApertureAtMinFocal, double &maxApertureAtMaxFocal); + +extern const TagAttrib exifAttribs[]; +extern const TagAttrib gpsAttribs[]; +extern const TagAttrib iopAttribs[]; +extern const TagAttrib ifdAttribs[]; +extern const TagAttrib nikon2Attribs[]; +extern const TagAttrib nikon3Attribs[]; +extern const TagAttrib canonAttribs[]; +extern const TagAttrib pentaxAttribs[]; +extern const TagAttrib fujiAttribs[]; +extern const TagAttrib minoltaAttribs[]; +extern const TagAttrib sonyAttribs[]; +extern const TagAttrib olympusAttribs[]; +}; +#endif diff --git a/rtexif/sonyminoltaattribs.cc b/rtexif/sonyminoltaattribs.cc new file mode 100644 index 000000000..767e49996 --- /dev/null +++ b/rtexif/sonyminoltaattribs.cc @@ -0,0 +1,616 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _SONYMINOLTAATTRIBS_ +#define _SONYMINOLTAATTRIBS_ + +#include +#include +#include +#include +#include +#include + +#undef ABS +#define ABS(a) (((a) < 0) ? -(a) : (a)) + +namespace rtexif { + +class SAOnOffInterpreter : public ChoiceInterpreter { + public: + SAOnOffInterpreter () { + choices[0] = "Off"; + choices[1] = "On"; + choices[5] = "On"; + } +}; +SAOnOffInterpreter saOnOffInterpreter; + +class SASceneModeInterpreter : public ChoiceInterpreter { + public: + SASceneModeInterpreter () { + choices[0] = "Normal (P,A,S or M)"; + choices[1] = "Portrait"; + choices[2] = "Text"; + choices[3] = "Night Scene"; + choices[4] = "Sunset"; + choices[5] = "Sports"; + choices[6] = "Landscape"; + choices[8] = "Macro"; + choices[8] = "Super Macro"; + choices[16] = "Auto"; + choices[17] = "Night Portrait"; + } +}; +SASceneModeInterpreter saSceneModeInterpreter; + +class SAZoneMatchingInterpreter : public ChoiceInterpreter { + public: + SAZoneMatchingInterpreter () { + choices[0] = "ISO Setting Used"; + choices[1] = "High Key"; + choices[2] = "Low Key"; + } +}; +SAZoneMatchingInterpreter saZoneMatchingInterpreter; + +class SADynamicRangeOptimizerInterpreter : public ChoiceInterpreter { + public: + SADynamicRangeOptimizerInterpreter () { + choices[0] = "Off"; + choices[1] = "Standard"; + choices[2] = "Advanced"; + choices[3] = "Auto"; + choices[8] = "Advanced Lv1"; + choices[9] = "Advanced Lv2"; + choices[10] = "Advanced Lv3"; + choices[11] = "Advanced Lv4"; + choices[12] = "Advanced Lv5"; + } +}; +SADynamicRangeOptimizerInterpreter saDynamicRangeOptimizerInterpreter; + +class SAColorModeInterpreter : public ChoiceInterpreter { + public: + SAColorModeInterpreter () { + choices[0] = "Standard"; + choices[1] = "Vivid"; + choices[2] = "Portrait"; + choices[3] = "Landscape"; + choices[4] = "Sunset"; + choices[5] = "Night Scene"; + choices[6] = "B&W"; + choices[7] = "Adobe RGB"; + choices[12] = "Neutral"; + choices[100]= "Neutral"; + choices[101]= "Clear"; + choices[102]= "Deep"; + choices[103]= "Light"; + choices[104]= "Night View"; + choices[105]= "Autumn Leaves"; + } +}; +SAColorModeInterpreter saColorModeInterpreter; + +class SAExposureModeInterpreter : public ChoiceInterpreter { + public: + SAExposureModeInterpreter () { + choices[0] = "Auto"; + choices[5] = "Landscape"; + choices[6] = "Program"; + choices[7] = "Aperture Priority"; + choices[8] = "Shutter Priority"; + choices[9] = "Night Scene"; + choices[15] = "Manual"; + choices[34] = "Panorama"; + choices[35] = "Handheld Twilight"; + choices[36] = "Anti Motion Blur"; + } +}; +SAExposureModeInterpreter saExposureModeInterpreter; + +class SAQualityInterpreter : public ChoiceInterpreter { + public: + SAQualityInterpreter () { + choices[0] = "Normal"; + choices[1] = "Fine"; + } +}; +SAQualityInterpreter saQualityInterpreter; + +class SAAntiBlurInterpreter : public ChoiceInterpreter { + public: + SAAntiBlurInterpreter () { + choices[0] = "Off"; + choices[1] = "On (Continuous)"; + choices[2] = "On (Shooting)"; + choices[65535] = "n/a"; + } +}; +SAAntiBlurInterpreter saAntiBlurInterpreter; + +class SALensIDInterpreter : public Interpreter { + typedef std::multimap container_t; + typedef std::pair p_t; + protected: + container_t choices; + public: + SALensIDInterpreter () { + choices.insert(p_t(0, "Minolta AF 28-85mm f/3.5-4.5")); + choices.insert(p_t(1, "Minolta AF 80-200mm f/2.8 HS-APO G")); + choices.insert(p_t(2, "Minolta AF 28-70mm f/2.8 G")); + choices.insert(p_t(3, "Minolta AF 28-80mm f/4-5.6")); + choices.insert(p_t(5, "Minolta AF 35-70mm f/3.5-4.5")); + choices.insert(p_t(6, "Minolta AF 24-85mm f/3.5-4.5 [New]")); + choices.insert(p_t(7, "Minolta AF 100-300mm f/4.5-5.6 APO [New]")); + choices.insert(p_t(7, "Sigma AF 100-300mm f/4 EX DG IF")); + choices.insert(p_t(8, "Minolta AF 70-210mm f/4.5-5.6")); + choices.insert(p_t(9, "Minolta AF 50mm f/3.5 Macro")); + choices.insert(p_t(10, "Minolta AF 28-105mm f/3.5-4.5 [New]")); + choices.insert(p_t(11, "Minolta AF 300mm f/4 HS-APO G")); + choices.insert(p_t(12, "Minolta AF 100mm f/2.8 Soft Focus")); + choices.insert(p_t(13, "Minolta AF 75-300mm f/4.5-5.6")); + choices.insert(p_t(14, "Minolta AF 100-400mm f/4.5-6.7 APO")); + choices.insert(p_t(15, "Minolta AF 400mm f/4.5 HS-APO G")); + choices.insert(p_t(16, "Minolta AF 17-35mm f/3.5 G")); + choices.insert(p_t(17, "Minolta AF 20-35mm f/3.5-4.5")); + choices.insert(p_t(18, "Minolta AF 28-80mm f/3.5-5.6 II")); + choices.insert(p_t(19, "Minolta AF 35mm f/1.4")); + choices.insert(p_t(20, "Minolta/Sony STF 135mm F2.8 [T4.5]")); + choices.insert(p_t(22, "Minolta AF 35-80mm f/4-5.6")); + choices.insert(p_t(23, "Minolta AF 200mm f/4 G APO Macro")); + choices.insert(p_t(24, "Minolta/Sony AF 24-105mm f/3.5-4.5 (D)")); + choices.insert(p_t(24, "Sigma 18-50mm f/2.8 EX DC Macro")); + choices.insert(p_t(24, "Sigma 17-70mm f/2.8-4.5 DC Macro")); + choices.insert(p_t(24, "Sigma 20-40mm f/2.8 EX DG Aspherical IF")); + choices.insert(p_t(24, "Sigma 18-200mm f/3.5-6.3 DC")); + choices.insert(p_t(24, "Tamron SP AF 28-75mm f/2.8 XR Di (IF) Macro")); + choices.insert(p_t(25, "Minolta AF 100-300mm f/4.5-5.6 APO D")); + choices.insert(p_t(25, "Sigma 100-300mm f/4 EX DG APO")); + choices.insert(p_t(25, "Sigma 70mm f/2.8 EX DG Macro")); + choices.insert(p_t(25, "Sigma 20mm f/1.8 EX DG Aspherical RF")); + choices.insert(p_t(25, "Sigma 30mm f/1.4 EX DG")); + choices.insert(p_t(27, "Minolta AF 85mm f71.4 G")); + choices.insert(p_t(28, "Minolta AF 100mm f/2.8 Macro (D)")); + choices.insert(p_t(28, "Tamron SP AF 90mm f/2.8 Di Macro ")); + choices.insert(p_t(29, "Minolta AF 75-300mm f/4.5-5.6 (D)")); + choices.insert(p_t(30, "Minolta AF 28-80mm f/3.5-5.6 (D)")); + choices.insert(p_t(30, "Sigma 10-20mm f/4-5.6 EX DC")); + choices.insert(p_t(30, "Sigma 12-24mm f/4.5-5.6 EX DG")); + choices.insert(p_t(30, "Sigma 28-70mm f/2.8 EX DG")); + choices.insert(p_t(30, "Sigma 55-200mm f/4-5.6 DC")); + choices.insert(p_t(31, "Minolta/Sony AF 50mm f/2.8 Macro (D)")); + choices.insert(p_t(32, "Minolta AF 300mm f/2.8 G")); + choices.insert(p_t(33, "Minolta/Sony AF 70-200mm f/2.8 G (D) SSM")); + choices.insert(p_t(35, "Minolta AF 85mm f/1.4 G (D) Limited")); + choices.insert(p_t(36, "Minolta AF 28-100mm f/3.5-5.6 (D)")); + choices.insert(p_t(38, "Minolta AF 17-35mm f/2.8-4 (D)")); + choices.insert(p_t(39, "Minolta AF 28-75mm f/2.8 (D)")); + choices.insert(p_t(40, "Minolta/Sony AF DT 18-70mm f/3.5-5.6 (D)")); + choices.insert(p_t(41, "Minolta/Sony AF DT 11-18mm f/4.5-5.6 (D)")); + choices.insert(p_t(42, "Minolta AF DT 18-200mm f/3.5-6.3 (D)")); + choices.insert(p_t(43, "Minolta AF 35mm f/1.4 G")); + choices.insert(p_t(44, "Sony AF 50mm f/1.4")); + choices.insert(p_t(45, "Carl Zeiss Planar T* 85mm f/1.4 ZA")); + choices.insert(p_t(46, "Carl Zeiss Vario-Sonnar T* DT 16-80mm f/3.5-4.5 ZA")); + choices.insert(p_t(47, "Carl Zeiss Sonnar T* 135mm F1.8 ZA")); + choices.insert(p_t(48, "Carl Zeiss Vario-Sonnar T* 24-70mm f/2.8 ZA SSM")); + choices.insert(p_t(49, "Sony AF DT 55-200mm f/4-5.6")); + choices.insert(p_t(50, "Sony AF DT 18-250mm f/3.5-6.3")); + choices.insert(p_t(51, "Sony AF DT 16-105mm f/3.5-5.6 or 55-200mm f/4-5.5")); + choices.insert(p_t(52, "Sony AF 70-300mm f/4.5-5.6 G SSM")); + choices.insert(p_t(53, "Sony AF 70-400mm f/4.5-5.6 G SSM")); + choices.insert(p_t(54, "Carl Zeiss Vario-Sonnar T* 16-35mm f/2.8 ZA SSM")); + choices.insert(p_t(55, "Sony DT 18-55mm f/3.5-5.6 SAM")); + choices.insert(p_t(56, "Sony AF DT 55-200mm f/4-5.6 SAM")); + choices.insert(p_t(57, "Sony AF DT 50mm f/1.8 SAM")); + choices.insert(p_t(58, "Sony AF DT 30mm f/2.8 SAM Macro")); + choices.insert(p_t(59, "Sony AF 28-75mm f/2.8 SAM")); + choices.insert(p_t(128, "Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF)")); + choices.insert(p_t(128, "Tamron AF 28-300mm f/3.5-6.3")); + choices.insert(p_t(128, "Tamron AF 28-200mm f/3.8-5.6 XR Di Aspherical (IF) Macro ")); + choices.insert(p_t(128, "Tamron SP AF 17-35mm f/2.8-4 Di LD Aspherical IF")); + choices.insert(p_t(128, "Sigma 10-20mm f/3.5 EX DC")); + choices.insert(p_t(128, "Sigma 70-200mm f/2.8 II EX DG APO Macro")); + choices.insert(p_t(129, "Tamron 200-400mm f/5.6 LD (IF)")); + choices.insert(p_t(129, "Tamron 70-300mm f/4-5.6 LD")); + choices.insert(p_t(135, "Vivitar 28-210mm f/3.5-5.6")); + choices.insert(p_t(136, "Tokina EMZ M100 AF 100mm f/3.5")); + choices.insert(p_t(137, "Cosina 70-210mm f/2.8-4 AF")); + choices.insert(p_t(138, "Soligor 19-35mm f/3.5-4.5")); + choices.insert(p_t(142, "Voigtlander 70-300mm f/4.5-5.6")); + choices.insert(p_t(146, "Voigtlander Macro APO-Lanthar 125mm f/2.5 SL")); + choices.insert(p_t(255, "Tamron SP AF 17-50mm f/2.8 XR Di II LD Aspherical")); + choices.insert(p_t(255, "Tamron AF 18-250mm f/3.5-6.3 XR Di II LD")); + choices.insert(p_t(255, "Tamron AF 55-200mm f/4-5.6 Di II")); + choices.insert(p_t(255, "Tamron AF 70-300mm f/4-5.6 Di LD Macro 1:2")); + choices.insert(p_t(255, "Tamron SP AF 200-500mm f/5.0-6.3 Di LD (IF)")); + choices.insert(p_t(255, "Tamron SP AF 10-24mm f/3.5-4.5 Di II LD Aspherical (IF)")); + choices.insert(p_t(255, "Tamron SP AF 70-200mm f/2.8 Di LD Macro (IF)")); + choices.insert(p_t(255, "Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical (IF)")); + choices.insert(p_t(2550, "Minolta AF 50mm f/1.7")); + choices.insert(p_t(2551, "Minolta AF 35-70mm f/4")); + choices.insert(p_t(2551, "Sigma UC AF 28-70mm f/3.5-4.5")); + choices.insert(p_t(2551, "Sigma AF 28-70mm f/2.8")); + choices.insert(p_t(2551, "Sigma M-AF 70-200mm f/2.8 EX Aspherical")); + choices.insert(p_t(2551, "Quantaray M-AF 35-80mm f/4-5.6")); + choices.insert(p_t(2552, "Minolta AF 28-85mm f/3.5-4.5 [New]")); + choices.insert(p_t(2552, "Tokina 19-35mm f/3.5-4.5")); + choices.insert(p_t(2552, "Tokina 28-70mm f/2.8 AT-X")); + choices.insert(p_t(2552, "Tokina 80-400mm f/4.5-5.6 AT-X AF II 840")); + choices.insert(p_t(2552, "Tokina AF PRO 28-80mm f/2.8 AT-X 280")); + choices.insert(p_t(2552, "Tokina AT-X PRO II AF 28-70mm f/2.6-2.8 270")); + choices.insert(p_t(2552, "Tamron AF 19-35mm f/3.5-4.5")); + choices.insert(p_t(2552, "Angenieux AF 28-70mm f/2.6")); + choices.insert(p_t(2553, "Minolta AF 28-135mm f/4-4.5")); + choices.insert(p_t(2553, "Sigma ZOOM-alpha 35-135mm f/3.5-4.5")); + choices.insert(p_t(2553, "Sigma 28-105mm f/2.8-4 Aspherical")); + choices.insert(p_t(2554, "Minolta AF 35-105mm f/3.5-4.5")); + choices.insert(p_t(2555, "Minolta AF 70-210mm f/4 Macro")); + choices.insert(p_t(2555, "Sigma 70-210mm f/4-5.6 APO")); + choices.insert(p_t(2555, "Sigma M-AF 70-200mm f/2.8 EX APO")); + choices.insert(p_t(2555, "Sigma 75-200mm f/2.8-3.5")); + choices.insert(p_t(2556, "Minolta AF 135mm f/2.8")); + choices.insert(p_t(2557, "Minolta AF 28mm f/2.8")); + choices.insert(p_t(2558, "Minolta AF 24-50mm f/4")); + choices.insert(p_t(2560, "Minolta AF 100-200mm f/4.5")); + choices.insert(p_t(2561, "Minolta AF 75-300mm f/4.5-5.6")); + choices.insert(p_t(2561, "Sigma 70-300mm f/4-5.6 DL Macro")); + choices.insert(p_t(2561, "Sigma 300mm f/4 APO Macro")); + choices.insert(p_t(2561, "Sigma AF 500mm f/4.5 APO")); + choices.insert(p_t(2561, "Sigma AF 170-500mm f/5-6.3 APO Aspherical")); + choices.insert(p_t(2561, "Tokina AT-X AF 300mm f/4")); + choices.insert(p_t(2561, "Tokina AT-X AF 400mm f/5.6 SD")); + choices.insert(p_t(2561, "Tokina AF 730 II 75-300mm f/4.5-5.6")); + choices.insert(p_t(2562, "Minolta/Sony AF 50mm f/1.4 [New]")); + choices.insert(p_t(2563, "Minolta AF 300mm f/2.8 G")); + choices.insert(p_t(2563, "Sigma AF 50-500mm f/4-6.3 EX DG APO")); + choices.insert(p_t(2563, "Sigma AF 170-500mm f/5-6.3 APO Aspherical")); + choices.insert(p_t(2563, "Sigma AF 500mm f/4.5 EX DG APO")); + choices.insert(p_t(2563, "Sigma 400mm f/5.6 APO")); + choices.insert(p_t(2564, "Minolta AF 50mm f/2.8 Macro")); + choices.insert(p_t(2564, "Sigma 50mm f/2.8 EX Macro")); + choices.insert(p_t(2565, "Minolta AF 600mm f/4")); + choices.insert(p_t(2566, "Minolta AF 24mm f/2.8")); + choices.insert(p_t(2572, "Minolta/Sony AF 500mm f/8 Reflex")); + choices.insert(p_t(2578, "Minolta AF 16mm f/2.8 Fisheye")); + choices.insert(p_t(2578, "Sigma 8mm f/4 EX DG Fisheye")); + choices.insert(p_t(2578, "Sigma 14mm f/3.5")); + choices.insert(p_t(2578, "Sigma 15mm f/2.8 Fisheye")); + choices.insert(p_t(2579, "Minolta AF 20mm f/2.8")); + choices.insert(p_t(2581, "Minolta/Sony AF 100mm f/2.8 Macro")); + choices.insert(p_t(2581, "Sigma AF 90mm f/2.8 Macro")); + choices.insert(p_t(2581, "Sigma AF 105mm f/2.8 EX DG Macro")); + choices.insert(p_t(2581, "Sigma 180mm f/5.6 Macro")); + choices.insert(p_t(2581, "Tamron AF 90mm f/2.8 Macro")); + choices.insert(p_t(2585, "Minolta AF 35-105mm f/3.5-4.5 New")); + choices.insert(p_t(2585, "Tamron AF 24-135mm f/3.5-5.6")); + choices.insert(p_t(2588, "Minolta AF 70-210mm f/3.5-4.5")); + choices.insert(p_t(2589, "Minolta AF 80-200 f/2.8 APO")); + choices.insert(p_t(2589, "Tokina 80-200mm f/2.8")); + choices.insert(p_t(2591, "Minolta AF 35mm f/1.4")); + choices.insert(p_t(2592, "Minolta AF 85mm f/1.4 G (D)")); + choices.insert(p_t(2593, "Minolta AF 200mm f/2.8 G APO")); + choices.insert(p_t(2594, "Minolta AF 3x-1x f/1.7-2.8 Macro")); + choices.insert(p_t(2596, "Minolta AF 28mm f/2")); + choices.insert(p_t(2597, "Minolta AF 35mm f/2")); + choices.insert(p_t(2598, "Minolta AF 100mm f/2")); + choices.insert(p_t(2604, "Minolta AF 80-200mm f/4.5-5.6")); + choices.insert(p_t(2605, "Minolta AF 35-80mm f/4-5.6")); + choices.insert(p_t(2606, "Minolta AF 100-300mm f/4.5-5.6 (D)")); + choices.insert(p_t(2607, "Minolta AF 35-80mm f/4-5.6")); + choices.insert(p_t(2608, "Minolta AF 300mm f/2.8 G")); + choices.insert(p_t(2609, "Minolta AF 600mm f/4 HS-APO G")); + choices.insert(p_t(2612, "Minolta AF 200mm f/2.8 G HS-APO")); + choices.insert(p_t(2613, "Minolta AF 50mm f/1.7 New")); + choices.insert(p_t(2615, "Minolta AF 28-105mm f/3.5-4.5 Power Zoom")); + choices.insert(p_t(2616, "Minolta AF 35-200mm f/4.5-5.6 Power Zoom")); + choices.insert(p_t(2618, "Minolta AF 28-80mm f/4-5.6 Power Zoom")); + choices.insert(p_t(2619, "Minolta AF 80-200mm f/4.5-5.6 Power Zoom")); + choices.insert(p_t(2620, "Minolta AF 28-70mm f/2.8 G")); + choices.insert(p_t(2621, "Minolta AF 100-300mm f/4.5-5.6 Power Zoom")); + choices.insert(p_t(2624, "Minolta AF 35-80mm f/4-5.6 Power Zoom")); + choices.insert(p_t(2628, "Minolta AF 80-200mm f/2.8 G")); + choices.insert(p_t(2629, "Minolta AF 85mm f/1.4 New")); + choices.insert(p_t(2631, "Minolta/Sony AF 100-300mm f/4.5-5.6 APO")); + choices.insert(p_t(2632, "Minolta AF 24-50mm f/4 New")); + choices.insert(p_t(2638, "Minolta AF 50mm f/2.8 Macro New")); + choices.insert(p_t(2639, "Minolta AF 100mm f/2.8 Macro")); + choices.insert(p_t(2641, "Minolta AF 20mm f/2.8 New")); + choices.insert(p_t(2642, "Minolta AF 24mm f/2.8 New")); + choices.insert(p_t(2644, "Minolta AF 100-400mm f/4.5-6.7 APO")); + choices.insert(p_t(2662, "Minolta AF 50mm f/1.4 New")); + choices.insert(p_t(2667, "Minolta AF 35mm f/2 New")); + choices.insert(p_t(2668, "Minolta AF 28mm f/2 New")); + choices.insert(p_t(2672, "Minolta AF 24-105mm f/3.5-4.5 (D)")); + choices.insert(p_t(4574, "Minolta AF 200mm f/2.8 G x2")); + choices.insert(p_t(4575, "1.4 x Teleconverter")); + choices.insert(p_t(4585, "Tamron SP AF 300mm f/2.8 LD IF")); + choices.insert(p_t(6553, "Arax MC 35mm f/2.8 Tilt+Shift")); + choices.insert(p_t(6553, "Arax MC 80mm f/2.8 Tilt+Shift")); + choices.insert(p_t(6553, "Zenitar MF 16mm f/2.8 Fisheye M42")); + choices.insert(p_t(6553, "Samyang 500mm Mirror f/8")); + choices.insert(p_t(6553, "Pentacon Auto 135mm f/2.8")); + choices.insert(p_t(6553, "Pentacon Auto 29mm f/2.8")); + choices.insert(p_t(6553, "Helios 44-2 58mm f/2")); + choices.insert(p_t(25501, "Minolta AF 50mm f/1.7")); + choices.insert(p_t(25511, "Minolta AF 35-70mm f/4")); + choices.insert(p_t(25511, "Sigma UC AF 28-70mm f/3.5-4.5")); + choices.insert(p_t(25511, "Sigma AF 28-70mm f/2.8")); + choices.insert(p_t(25511, "Sigma M-AF 70-200mm f/2.8 EX Aspherical")); + choices.insert(p_t(25511, "Quantaray M-AF 35-80mm f/4-5.6")); + choices.insert(p_t(25521, "Minolta AF 28-85mm f/3.5-4.5 [New]")); + choices.insert(p_t(25521, "Tokina 19-35mm f/3.5-4.5")); + choices.insert(p_t(25521, "Tokina 28-70mm f/2.8 AT-X")); + choices.insert(p_t(25521, "Tokina 80-400mm f/4.5-5.6 AT-X AF II 840")); + choices.insert(p_t(25521, "Tokina AF PRO 28-80mm f/2.8 AT-X 280")); + choices.insert(p_t(25521, "Tokina AT-X PRO II AF 28-70mm f/2.6-2.8 270")); + choices.insert(p_t(25521, "Tamron AF 19-35mm f/3.5-4.5")); + choices.insert(p_t(25521, "Angenieux AF 28-70mm f/2.6")); + choices.insert(p_t(25531, "Minolta AF 28-135mm f/4-4.5")); + choices.insert(p_t(25531, "Sigma ZOOM-alpha 35-135mm f/3.5-4.5")); + choices.insert(p_t(25531, "Sigma 28-105mm f/2.8-4 Aspherical")); + choices.insert(p_t(25541, "Minolta AF 35-105mm f/3.5-4.5")); + choices.insert(p_t(25551, "Minolta AF 70-210mm f/4 Macro")); + choices.insert(p_t(25551, "Sigma 70-210mm f/4-5.6 APO")); + choices.insert(p_t(25551, "Sigma M-AF 70-200mm f/2.8 EX APO")); + choices.insert(p_t(25551, "Sigma 75-200mm f/2.8-3.5")); + choices.insert(p_t(25561, "Minolta AF 135mm f/2.8")); + choices.insert(p_t(25571, "Minolta AF 28mm f/2.8")); + choices.insert(p_t(25581, "Minolta AF 24-50mm f/4")); + choices.insert(p_t(25601, "Minolta AF 100-200mm f/4.5")); + choices.insert(p_t(25611, "Minolta AF 75-300mm f/4.5-5.6")); + choices.insert(p_t(25611, "Sigma 70-300mm f/4-5.6 DL Macro")); + choices.insert(p_t(25611, "Sigma 300mm f/4 APO Macro")); + choices.insert(p_t(25611, "Sigma AF 500mm f/4.5 APO")); + choices.insert(p_t(25611, "Sigma AF 170-500mm f/5-6.3 APO Aspherical")); + choices.insert(p_t(25611, "Tokina AT-X AF 300mm f/4")); + choices.insert(p_t(25611, "Tokina AT-X AF 400mm f/5.6 SD")); + choices.insert(p_t(25611, "Tokina AF 730 II 75-300mm f/4.5-5.6")); + choices.insert(p_t(25621, "Minolta AF 50mm f/1.4")); + choices.insert(p_t(25631, "Minolta AF 300mm f/2.8 G")); + choices.insert(p_t(25631, "Sigma AF 50-500mm f/4-6.3 EX DG APO")); + choices.insert(p_t(25631, "Sigma AF 170-500mm f/5-6.3 APO Aspherical")); + choices.insert(p_t(25631, "Sigma AF 500mm f/4.5 EX DG APO")); + choices.insert(p_t(25631, "Sigma 400mm f/5.6 APO")); + choices.insert(p_t(25641, "Minolta AF 50mm f/2.8 Macro")); + choices.insert(p_t(25641, "Sigma AF 50mm f/2.8 Macro")); + choices.insert(p_t(25651, "Minolta AF 600mm f/4")); + choices.insert(p_t(25661, "Minolta AF 24mm f/2.8")); + choices.insert(p_t(25721, "Minolta/Sony AF 500mm f/8 Reflex")); + choices.insert(p_t(25781, "Minolta AF 16mm f/2.8 Fisheye")); + choices.insert(p_t(25781, "Sigma 8mm f/4 EX DG Fisheye")); + choices.insert(p_t(25781, "Sigma 14mm f/3.5")); + choices.insert(p_t(25781, "Sigma 15mm f/2.8 Fisheye")); + choices.insert(p_t(25791, "Minolta AF 20mm f/2.8")); + choices.insert(p_t(25811, "Minolta/Sony AF 100mm f/2.8 Macro New")); + choices.insert(p_t(25811, "Sigma AF 90mm f/2.8 Macro")); + choices.insert(p_t(25811, "Sigma AF 105mm f/2.8 EX DG Macro")); + choices.insert(p_t(25811, "Sigma 180mm f/5.6 Macro")); + choices.insert(p_t(25811, "Tamron 90mm f/2.8 Macro")); + choices.insert(p_t(25851, "Beroflex 35-135mm f/3.5-4.5")); + choices.insert(p_t(25858, "Minolta AF 35-105mm f/3.5-4.5 New")); + choices.insert(p_t(25858, "Tamron 24-135mm f/3.5-5.6")); + choices.insert(p_t(25881, "Minolta AF 70-210mm f/3.5-4.5")); + choices.insert(p_t(25891, "Minolta AF 80-200 f/2.8 APO")); + choices.insert(p_t(25891, "Tokina 80-200mm f/2.8")); + choices.insert(p_t(25911, "Minolta AF 35mm f/1.4")); + choices.insert(p_t(25921, "Minolta AF 85mm f/1.4 G (D)")); + choices.insert(p_t(25931, "Minolta AF 200mm f/2.8 G APO")); + choices.insert(p_t(25941, "Minolta AF 3x-1x f/1.7-2.8 Macro")); + choices.insert(p_t(25961, "Minolta AF 28mm f/2")); + choices.insert(p_t(25971, "Minolta AF 35mm f/2")); + choices.insert(p_t(25981, "Minolta AF 100mm f/2")); + choices.insert(p_t(26041, "Minolta AF 80-200mm f/4.5-5.6")); + choices.insert(p_t(26051, "Minolta AF 35-80mm f/4-5.6")); + choices.insert(p_t(26061, "Minolta AF 100-300mm f/4.5-5.6 (D)")); + choices.insert(p_t(26071, "Minolta AF 35-80mm f/4-5.6")); + choices.insert(p_t(26081, "Minolta AF 300mm f/2.8 HS-APO G")); + choices.insert(p_t(26091, "Minolta AF 600mm f/4 HS-APO G")); + choices.insert(p_t(26121, "Minolta AF 200mm f/2.8 HS-APO G")); + choices.insert(p_t(26131, "Minolta AF 50mm f/1.7 New")); + choices.insert(p_t(26151, "Minolta AF 28-105mm f/3.5-4.5 Power Zoom")); + choices.insert(p_t(26161, "Minolta AF 35-200mm f/4.5-5.6 Power Zoom")); + choices.insert(p_t(26181, "Minolta AF 28-80mm f/4-5.6 Power Zoom")); + choices.insert(p_t(26191, "Minolta AF 80-200mm f/4.5-5.6 Power Zoom")); + choices.insert(p_t(26201, "Minolta AF 28-70mm f/2.8 G")); + choices.insert(p_t(26211, "Minolta AF 100-300mm f/4.5-5.6 Power Zoom")); + choices.insert(p_t(26241, "Minolta AF 35-80mm f/4-5.6 Power Zoom")); + choices.insert(p_t(26281, "Minolta AF 80-200mm f/2.8 G")); + choices.insert(p_t(26291, "Minolta AF 85mm f/1.4 New")); + choices.insert(p_t(26311, "Minolta/Sony AF 100-300mm f/4.5-5.6 APO")); + choices.insert(p_t(26321, "Minolta AF 24-50mm f/4 New")); + choices.insert(p_t(26381, "Minolta AF 50mm f/2.8 Macro New")); + choices.insert(p_t(26391, "Minolta AF 100mm f/2.8 Macro")); + choices.insert(p_t(26411, "Minolta AF 20mm f/2.8 New")); + choices.insert(p_t(26421, "Minolta AF 24mm f/2.8 New")); + choices.insert(p_t(26441, "Minolta AF 100-400mm f/4.5-6.7 APO")); + choices.insert(p_t(26621, "Minolta AF 50mm f/1.4 New")); + choices.insert(p_t(26671, "Minolta AF 35mm f/2 New")); + choices.insert(p_t(26681, "Minolta AF 28mm f/2 New")); + choices.insert(p_t(26721, "Minolta AF 24-105mm f/3.5-4.5 (D)")); + choices.insert(p_t(45671, "Tokina 70-210mm f/4-5.6")); + choices.insert(p_t(45741, "Minolta AF 200mm f/2.8 G x2")); + choices.insert(p_t(45851, "Tamron SP AF 300mm f/2.8 LD IF")); + choices.insert(p_t(45871, "Tamron SP AF 70-210mm f/2.8 LD")); + choices.insert(p_t(65535, "Arax MC 35mm f/2.8 Tilt+Shift")); + choices.insert(p_t(65535, "Arax MC 80mm f/2.8 Tilt+Shift")); + choices.insert(p_t(65535, "Zenitar MF 16mm f/2.8 Fisheye M42")); + choices.insert(p_t(65535, "Samyang 500mm f/8 Mirror")); + choices.insert(p_t(65535, "Pentacon Auto 135mm f/2.8")); + choices.insert(p_t(65535, "Pentacon Auto 29mm f/2.8")); + choices.insert(p_t(65535, "Helios 44-2 58mm f/2")); + } + + + virtual std::string toString (Tag* t) + { + int lensID = t->toInt(); + size_t nFound = choices.count( lensID ); + container_t::iterator r; + switch( nFound ) + { + case 0: // lens Unknown + t->toString (buffer); + return std::string (buffer); + case 1: // lens found + r = choices.find ( lensID ); + return r->second; + default: + // More than one hit: we must guess + break; + } + + double maxApertureAtFocal = pow(2.0, t->getParent()->getParent()->getTag(0x9205)->toDouble()/2.0); // MaxApertureValue at focal Length + double focalLength = t->getParent()->getParent()->getTag(0x920A)->toDouble(); // Focal Length + double deltaMin = 1000.; + + /* Choose the best match: thanks to exiftool by Phil Harvey + * first throws for "out of focal range" and lower or upper aperture of the lens compared to MaxApertureAtFocal + * if the lens is not constant aperture, calculate aprox. aperture of the lens at focalLength + * and compare with actual aperture. + */ + std::string bestMatch("Unknown"); + std::ostringstream candidates; + for ( r = choices.lower_bound( lensID ); r != choices.upper_bound(lensID); r++ ){ + double a1,a2,f1,f2,lensAperture,dif; + + if( !extractLensInfo( r->second ,f1,f2,a1,a2) ) + continue; + if( f1 == 0. || a1 == 0.) + continue; + + if( focalLength < f1 - .5 || focalLength > f2 + 0.5 ) + continue; + if( maxApertureAtFocal < a1 - 0.15 || maxApertureAtFocal > a2 +0.15) + continue; + + if( a1 == a2 || f1 == f2) + lensAperture = a1; + else + lensAperture = exp( log(a1)+(log(a2)-log(a1))/(log(f2)-log(f1))*(log(focalLength)-log(f1)) ); + + dif = ABS(lensAperture - maxApertureAtFocal); + if( dif < deltaMin ){ + deltaMin = dif; + bestMatch = r->second; + } + if( dif < 0.15){ + if( candidates.tellp() ) + candidates << "\n or " << r->second; + else + candidates << r->second; + } + } + if( !candidates.tellp() ) + return bestMatch; + else + return candidates.str(); + } +}; +SALensIDInterpreter saLensIDInterpreter; + +class MATeleconverterInterpreter : public ChoiceInterpreter { + public: + MATeleconverterInterpreter () { + choices[0] = "None "; + choices[0x48] = "Minolta AF 2x APO (D)"; + choices[0x50] = "Minolta AF 2x APO II"; + choices[0x88] = "Minolta AF 1.4x APO (D)"; + choices[0x90] = "Minolta AF 1.4x APO II"; + } +}; +MATeleconverterInterpreter maTeleconverterInterpreter; + +class MAQualityInterpreter : public ChoiceInterpreter { + public: + MAQualityInterpreter () { + choices[0] = "Raw"; + choices[1] = "Super Fine"; + choices[2] = "Fine"; + choices[3] = "Standard"; + choices[4] = "Economy"; + choices[5] = "Extra fine"; + choices[6] = "RAW + JPEG"; + choices[7] = "cRAW"; + choices[8] = "cRAW + JPEG"; + } +}; +MAQualityInterpreter maQualityInterpreter; + +class MAImageSizeInterpreter : public ChoiceInterpreter { + public: + MAImageSizeInterpreter () { + choices[1] = "1600x1200"; + choices[2] = "1280x960"; + choices[3] = "640x480"; + choices[5] = "2560x1920"; + choices[6] = "2272x1704"; + choices[7] = "2048x1536"; + } +}; +MAImageSizeInterpreter maImageSizeInterpreter; + +const TagAttrib minoltaAttribs[] = { + 0, 1, 0, 0, 0x0000, "MakerNoteVersion", &stdInterpreter, + 0, 1, 0, 0, 0x0001, "MinoltaCameraSettingsOld", &stdInterpreter, + 0, 1, 0, 0, 0x0003, "MinoltaCameraSettings", &stdInterpreter, + 0, 1, 0, 0, 0x0004, "MinoltaCameraSettings7D", &stdInterpreter, + 0, 1, 0, 0, 0x0018, "ImageStabilization", &stdInterpreter, + 0, 1, 0, 0, 0x0040, "CompressedImageSize", &stdInterpreter, + 1, 1, 0, 0, 0x0081, "PreviewImage", &stdInterpreter, + 1, 1, 0, 0, 0x0088, "PreviewImageStart", &stdInterpreter, + 1, 1, 0, 0, 0x0089, "PreviewImageLength", &stdInterpreter, + 0, 1, 0, 0, 0x0100, "SceneMode", &saSceneModeInterpreter, + 0, 1, 0, 0, 0x0101, "ColorMode", &saColorModeInterpreter, + 0, 1, 0, 0, 0x0102, "MinoltaQuality", &maQualityInterpreter, + 0, 1, 0, 0, 0x0103, "MinoltaImageSize", &maImageSizeInterpreter, + 0, 1, 0, 0, 0x0104, "FlashExposureComp", &stdInterpreter, + 0, 1, 0, 0, 0x0105, "Teleconverter", &maTeleconverterInterpreter, + 0, 1, 0, 0, 0x0107, "ImageStabilization", &saOnOffInterpreter, + 0, 1, 0, 0, 0x010a, "ZoneMatching", &saZoneMatchingInterpreter, + 0, 1, 0, 0, 0x010b, "ColorTemperature", &stdInterpreter, + 0, 1, 0, 0, 0x010c, "LensID", &saLensIDInterpreter, + 0, 1, 0, 0, 0x0113, "ImageStabilization", &saOnOffInterpreter, + 0, 1, 0, 0, 0x0114, "MinoltaCameraSettings", &stdInterpreter, + 1, 1, 0, 0, 0x0e00, "PrintIM", &stdInterpreter, + 0, 1, 0, 0, 0x0f00, "MinoltaCameraSettings2", &stdInterpreter, + -1, 0, 0, 0, 0, "", NULL}; + +const TagAttrib sonyAttribs[] = { + 1, 1, 0, 0, 0x0e00, "PrintIM", &stdInterpreter, + 1, 1, 0, 0, 0x2001, "PreviewImage", &stdInterpreter, + 0, 1, 0, 0, 0xb020, "ColorReproduction", &stdInterpreter, + 0, 1, 0, 0, 0xb021, "ColorTemperature", &stdInterpreter, + 0, 1, 0, 0, 0xb023, "SceneMode", &saSceneModeInterpreter, + 0, 1, 0, 0, 0xb024, "ZoneMatching", &saZoneMatchingInterpreter, + 0, 1, 0, 0, 0xb025, "DynamicRangeOptimizer", &saDynamicRangeOptimizerInterpreter, + 0, 1, 0, 0, 0xb026, "ImageStabilization", &saOnOffInterpreter, + 0, 1, 0, 0, 0xb027, "LensID", &saLensIDInterpreter, + 0, 1, 0, minoltaAttribs, 0xb028, "MinoltaMakerNote", &stdInterpreter, + 0, 1, 0, 0, 0xb029, "ColorMode", &saColorModeInterpreter, + 0, 1, 0, 0, 0xb040, "Macro", &saOnOffInterpreter, + 0, 1, 0, 0, 0xb041, "ExposureMode", &saExposureModeInterpreter, + 0, 1, 0, 0, 0xb047, "Quality", &saQualityInterpreter, + 0, 1, 0, 0, 0xb04b, "AntiBlur", &saAntiBlurInterpreter, + 0, 1, 0, 0, 0xb04e, "LongExposureNoiseReduction", &saOnOffInterpreter, + -1, 0, 0, 0, 0, "", NULL}; + +}; + #endif + diff --git a/rtexif/stdattribs.cc b/rtexif/stdattribs.cc new file mode 100644 index 000000000..3fa72010d --- /dev/null +++ b/rtexif/stdattribs.cc @@ -0,0 +1,486 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _STDATTRIBS_ +#define _STDATTRIBS_ + +#include +#include +#include +#include +#include + +namespace rtexif { + +class ColorSpaceInterpreter : public ChoiceInterpreter { + + public: + ColorSpaceInterpreter () { + choices[1] = "sRGB"; + choices[0xffff] = "Uncalibrated"; + } +}; +ColorSpaceInterpreter colorSpaceInterpreter; + +class ExposureProgramInterpreter : public ChoiceInterpreter { + + public: + ExposureProgramInterpreter () { + choices[0] = "Not defined"; + choices[1] = "Manual"; + choices[2] = "Normal program"; + choices[3] = "Aperture priority"; + choices[4] = "Shutter priority"; + choices[5] = "Creative program"; + choices[6] = "Action program"; + choices[7] = "Portrait mode"; + choices[8] = "Landscape mode"; + } +}; +ExposureProgramInterpreter exposureProgramInterpreter; + +class MeteringModeInterpreter : public ChoiceInterpreter { + + public: + MeteringModeInterpreter () { + choices[0] = "Unknown"; + choices[1] = "Average"; + choices[2] = "Center weighted"; + choices[3] = "Spot"; + choices[4] = "Multispot"; + choices[5] = "Pattern"; + choices[6] = "Partial"; + choices[255] = "Other"; + } +}; +MeteringModeInterpreter meteringModeInterpreter; + +class ExposureModeInterpreter : public ChoiceInterpreter { + + public: + ExposureModeInterpreter () { + choices[0] = "Auto exposure"; + choices[1] = "Manual exposure"; + choices[2] = "Auto bracket"; + } +}; +ExposureModeInterpreter exposureModeInterpreter; + +class WhiteBalanceInterpreter : public ChoiceInterpreter { + + public: + WhiteBalanceInterpreter () { + choices[0] = "Auto white balance"; + choices[1] = "Manual white balance"; + } +}; +WhiteBalanceInterpreter whiteBalanceInterpreter; + +class SceneCaptureInterpreter : public ChoiceInterpreter { + + public: + SceneCaptureInterpreter () { + choices[0] = "Standard"; + choices[1] = "Landscape"; + choices[2] = "Portrait"; + choices[3] = "Night scene"; + } +}; +SceneCaptureInterpreter sceneCaptureInterpreter; + +class GainControlInterpreter : public ChoiceInterpreter { + + public: + GainControlInterpreter () { + choices[0] = "None"; + choices[1] = "Low gain up"; + choices[2] = "High gain up"; + choices[3] = "Low gain down"; + choices[4] = "High gain down"; + } +}; +GainControlInterpreter gainControlInterpreter; + +class ContrastInterpreter : public ChoiceInterpreter { + + public: + ContrastInterpreter () { + choices[0] = "Normal"; + choices[1] = "Soft"; + choices[2] = "Hard"; + } +}; +ContrastInterpreter contrastInterpreter; + +class SharpnessInterpreter : public ChoiceInterpreter { + + public: + SharpnessInterpreter () { + choices[0] = "Normal"; + choices[1] = "Soft"; + choices[2] = "Hard"; + } +}; +SharpnessInterpreter sharpnessInterpreter; + +class SaturationInterpreter : public ChoiceInterpreter { + + public: + SaturationInterpreter () { + choices[0] = "Normal"; + choices[1] = "Low saturation"; + choices[2] = "High saturation"; + } +}; +SaturationInterpreter saturationInterpreter; + +class FlashInterpreter : public ChoiceInterpreter { + + public: + FlashInterpreter () { + choices[0x0000] = "Flash did not fire"; + choices[0x0001] = "Flash fired"; + choices[0x0005] = "Strobe return light not detected"; + choices[0x0007] = "Strobe return light detected"; + choices[0x0009] = "Flash fired, compulsory flash mode"; + choices[0x000D] = "Flash fired, compulsory flash mode, return light not detected"; + choices[0x000F] = "Flash fired, compulsory flash mode, return light detected"; + choices[0x0010] = "Flash did not fire, compulsory flash mode"; + choices[0x0018] = "Flash did not fire, auto mode"; + choices[0x0019] = "Flash fired, auto mode"; + choices[0x001D] = "Flash fired, auto mode, return light not detected"; + choices[0x001F] = "Flash fired, auto mode, return light detected"; + choices[0x0020] = "No flash function"; + choices[0x0041] = "Flash fired, red-eye reduction mode"; + choices[0x0045] = "Flash fired, red-eye reduction mode, return light not detected"; + choices[0x0047] = "Flash fired, red-eye reduction mode, return light detected"; + choices[0x0049] = "Flash fired, compulsory flash mode, red-eye reduction mode"; + choices[0x004D] = "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected"; + choices[0x004F] = "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected"; + choices[0x0059] = "Flash fired, auto mode, red-eye reduction mode"; + choices[0x005D] = "Flash fired, auto mode, return light not detected, red-eye reduction mode"; + choices[0x005F] = "Flash fired, auto mode, return light detected, red-eye reduction mode"; + } +}; +FlashInterpreter flashInterpreter; + +class LightSourceInterpreter : public ChoiceInterpreter { + + public: + LightSourceInterpreter () { + choices[0] = "Unknown"; + choices[1] = "Daylight"; + choices[2] = "Fluorescent"; + choices[3] = "Tungsten"; + choices[4] = "Flash"; + choices[9] = "Fine weather"; + choices[10] = "Cloudy weather"; + choices[11] = "Shade"; + choices[12] = "Daylight fluorescent"; + choices[13] = "Day white fluorescent"; + choices[14] = "Cool white fluorescent"; + choices[15] = "White fluorescent"; + choices[17] = "Standard light A"; + choices[18] = "Standard light B"; + choices[19] = "Standard light C"; + choices[20] = "D55"; + choices[21] = "D65"; + choices[22] = "D75"; + choices[23] = "D50"; + choices[24] = "ISO studio tungsten"; + choices[255] = "Other light source"; + } +}; +LightSourceInterpreter lightSourceInterpreter; + +class CompressionInterpreter : public ChoiceInterpreter { + + public: + CompressionInterpreter () { + choices[1] = "Uncompressed"; + choices[6] = "JPEG Compression"; + } +}; +CompressionInterpreter compressionInterpreter; + +class PhotometricInterpreter : public ChoiceInterpreter { + + public: + PhotometricInterpreter () { + choices[2] = "RGB"; + choices[6] = "YCbCr"; + } +}; +PhotometricInterpreter photometricInterpreter; + +class PlanarConfigInterpreter : public ChoiceInterpreter { + + public: + PlanarConfigInterpreter () { + choices[1] = "Chunky format"; + choices[2] = "Planar format"; + } +}; +PlanarConfigInterpreter planarConfigInterpreter; + +class FNumberInterpreter : public Interpreter { + public: + FNumberInterpreter () {} + virtual std::string toString (Tag* t) { + sprintf (buffer, "%0.1f", t->toDouble()); + return buffer; + } +}; +FNumberInterpreter fNumberInterpreter; + +class ApertureInterpreter : public Interpreter { + public: + ApertureInterpreter () {} + virtual std::string toString (Tag* t) { + sprintf (buffer, "%0.1f", pow(2.0, t->toDouble()/2.0)); + return buffer; + } +}; +ApertureInterpreter apertureInterpreter; + +class ExposureBiasInterpreter : public Interpreter { + public: + ExposureBiasInterpreter () {} + virtual std::string toString (Tag* t) { + sprintf (buffer, "%+0.2f", t->toDouble()); + return buffer; + } +}; +ExposureBiasInterpreter exposureBiasInterpreter; + +class ShutterSpeedInterpreter : public Interpreter { + public: + ShutterSpeedInterpreter () {} + virtual std::string toString (Tag* t) { + double d = pow (2.0, -t->toDouble()); + if (d > 0.0 && d < 0.9) + sprintf (buffer, "1/%0.0f", 1.0 / d); + else + sprintf (buffer, "%0.1f", d); + return buffer; + } +}; +ShutterSpeedInterpreter shutterSpeedInterpreter; + +class ExposureTimeInterpreter : public Interpreter { + public: + ExposureTimeInterpreter () {} + virtual std::string toString (Tag* t) { + double d = t->toDouble(); + if (d > 0.0 && d < 0.9) + sprintf (buffer, "1/%0.0f", 1.0 / d); + else + sprintf (buffer, "%0.1f", d); + return buffer; + } +}; +ExposureTimeInterpreter exposureTimeInterpreter; + +class FocalLengthInterpreter : public Interpreter { + public: + FocalLengthInterpreter () {} + virtual std::string toString (Tag* t) { + sprintf (buffer, "%0.1f", t->toDouble()); + return buffer; + } +}; +FocalLengthInterpreter focalLengthInterpreter; + +class UserCommentInterpreter : public Interpreter { + public: + UserCommentInterpreter () {} + virtual std::string toString (Tag* t) { + if (!strncmp((char*)t->getValue(), "ASCII\0\0\0",8)) + strncpy (buffer, (char*)t->getValue()+8, t->getCount()-8); + else + buffer[0]=0; + return buffer; + } + virtual void fromString (Tag* t, const std::string& value) { + memcpy (buffer, "ASCII\0\0\0", 8); + strcpy (buffer+8, value.c_str()); + t->fromString (buffer, value.size() + 9); + } +}; +UserCommentInterpreter userCommentInterpreter; + +const TagAttrib exifAttribs[] = { + 0, 2, 0, 0, 0x0103, "Compression", &compressionInterpreter, + 0, 2, 0, 0, 0xA000, "FlashpixVersion", &stdInterpreter, + 0, 2, 0, 0, 0xA001, "ColorSpace", &colorSpaceInterpreter, + 0, 1, 0, 0, 0x9000, "ExifVersion", &stdInterpreter, + 0, 1, 0, 0, 0x9003, "DateTimeOriginal", &stdInterpreter, + 0, 1, 0, 0, 0x9004, "DateTimeDigitized", &stdInterpreter, + 0, 2, 0, 0, 0x9101, "ComponentsConfiguration", &stdInterpreter, + 0, 2, 0, 0, 0x9102, "CompressedBitsPerPixel", &stdInterpreter, + 0, 2, 0, 0, 0xA002, "PixelXDimension", &stdInterpreter, + 0, 2, 0, 0, 0xA003, "PixelYDimension", &stdInterpreter, + 0, 1, 0, 0, 0x927C, "MakerNote", &stdInterpreter, + 0, 1, 1, 0, 0x9286, "UserComment", &userCommentInterpreter, + 1, 0, 0, 0, 0xA004, "RelatedSoundFile", &stdInterpreter, + 0, 1, 0, 0, 0x9290, "SubSecTime", &stdInterpreter, + 0, 1, 0, 0, 0x9291, "SubSecTimeOriginal", &stdInterpreter, + 0, 1, 0, 0, 0x9292, "SubSecTimeDigitized", &stdInterpreter, + 0, 1, 0, 0, 0xA420, "ImageUniqueID", &stdInterpreter, + 0, 1, 0, 0, 0x829A, "ExposureTime", &exposureTimeInterpreter, + 0, 1, 0, 0, 0x829D, "FNumber", &fNumberInterpreter, + 0, 1, 0, 0, 0x8822, "ExposureProgram", &exposureProgramInterpreter, + 0, 1, 0, 0, 0x8824, "SpectralSensitivity", &stdInterpreter, + 0, 1, 0, 0, 0x8827, "ISOSpeedRatings", &stdInterpreter, + 0, 1, 0, 0, 0x8828, "OECF", &stdInterpreter, + 0, 1, 0, 0, 0x9201, "ShutterSpeedValue", &shutterSpeedInterpreter, + 0, 1, 0, 0, 0x9202, "ApertureValue", &apertureInterpreter, + 0, 1, 0, 0, 0x9203, "BrightnessValue", &stdInterpreter, + 0, 1, 0, 0, 0x9204, "ExposureBiasValue", &exposureBiasInterpreter, + 0, 1, 0, 0, 0x9205, "MaxApertureValue", &apertureInterpreter, + 0, 1, 0, 0, 0x9206, "SubjectDistance", &stdInterpreter, + 0, 1, 0, 0, 0x9207, "MeteringMode", &meteringModeInterpreter, + 0, 1, 0, 0, 0x9208, "LightSource", &lightSourceInterpreter, + 0, 1, 0, 0, 0x9209, "Flash", &flashInterpreter, + 0, 1, 0, 0, 0x920A, "FocalLength", &focalLengthInterpreter, + 0, 1, 0, 0, 0x9214, "SubjectArea", &stdInterpreter, + 0, 0, 0, 0, 0x9216, "TIFFEPSStandardID", &stdInterpreter, + 0, 1, 0, 0, 0x9217, "SensingMethod", &stdInterpreter, + 0, 1, 0, 0, 0xA20B, "FlashEnergy", &stdInterpreter, + 0, 1, 0, 0, 0xA20C, "SpatialFrequencyResponse", &stdInterpreter, + 0, 1, 0, 0, 0xA20E, "FocalPlaneXResolution", &stdInterpreter, + 0, 1, 0, 0, 0xA20F, "FocalPlaneYResolution", &stdInterpreter, + 0, 1, 0, 0, 0xA210, "FocalPlaneResolutionUnit", &stdInterpreter, + 0, 1, 0, 0, 0xA214, "SubjectLocation", &stdInterpreter, + 0, 1, 0, 0, 0xA215, "ExposureIndex", &stdInterpreter, + 0, 1, 0, 0, 0xA217, "SensingMethod", &stdInterpreter, + 0, 1, 0, 0, 0xA300, "FileSource", &stdInterpreter, + 0, 1, 0, 0, 0xA301, "SceneType", &stdInterpreter, + 0, 0, 0, 0, 0xA302, "CFAPattern", &stdInterpreter, + 0, 1, 0, 0, 0xA401, "CustomRendered", &stdInterpreter, + 0, 1, 0, 0, 0xA402, "ExposureMode", &exposureModeInterpreter, + 0, 1, 0, 0, 0xA403, "WhiteBalance", &whiteBalanceInterpreter, + 0, 1, 0, 0, 0xA404, "DigitalZoomRatio", &stdInterpreter, + 0, 1, 0, 0, 0xA405, "FocalLengthIn35mmFilm", &stdInterpreter, + 0, 1, 0, 0, 0xA406, "SceneCaptureType", &sceneCaptureInterpreter, + 0, 1, 0, 0, 0xA407, "GainControl", &gainControlInterpreter, + 0, 1, 0, 0, 0xA408, "Contrast", &contrastInterpreter, + 0, 1, 0, 0, 0xA409, "Saturation", &saturationInterpreter, + 0, 1, 0, 0, 0xA40A, "Sharpness", &sharpnessInterpreter, + 0, 1, 0, 0, 0xA40B, "DeviceSettingDescription", &stdInterpreter, + 0, 1, 0, 0, 0xA40C, "SubjectDistanceRange", &stdInterpreter, + 0, 0, 0, 0, 0x828d, "CFAPattern", &stdInterpreter, + 0, 0, 0, 0, 0x828e, "CFARepeatPatternDim", &stdInterpreter, +-1, 0, 0, 0, 0, "", NULL }; +// 0, 0xA005, LONG, 1, "Interoperability tag", "Interoperability IFD Pointer"}; + +const TagAttrib gpsAttribs[] = { + 0, 1, 0, 0, 0x0000, "GPSVersionID", &stdInterpreter, + 0, 1, 0, 0, 0x0001, "GPSLatitudeRef", &stdInterpreter, + 0, 1, 0, 0, 0x0002, "GPSLatitude", &stdInterpreter, + 0, 1, 0, 0, 0x0003, "GPSLongitudeRef", &stdInterpreter, + 0, 1, 0, 0, 0x0004, "GPSLongitude", &stdInterpreter, + 0, 1, 0, 0, 0x0005, "GPSAltitudeRef", &stdInterpreter, + 0, 1, 0, 0, 0x0006, "GPSAltitude", &stdInterpreter, + 0, 1, 0, 0, 0x0007, "GPSTimeStamp", &stdInterpreter, + 0, 1, 0, 0, 0x0008, "GPSSatelites", &stdInterpreter, + 0, 1, 0, 0, 0x0009, "GPSStatus", &stdInterpreter, + 0, 1, 0, 0, 0x000a, "GPSMeasureMode", &stdInterpreter, + 0, 1, 0, 0, 0x000b, "GPSDOP", &stdInterpreter, + 0, 1, 0, 0, 0x000c, "GPSSpeedRef", &stdInterpreter, + 0, 1, 0, 0, 0x000d, "GPSSpeed", &stdInterpreter, + 0, 1, 0, 0, 0x000e, "GPSTrackRef", &stdInterpreter, + 0, 1, 0, 0, 0x000f, "GPSTrack", &stdInterpreter, + 0, 1, 0, 0, 0x0010, "GPSImgDirectionRef", &stdInterpreter, + 0, 1, 0, 0, 0x0011, "GPSImgDirection", &stdInterpreter, + 0, 1, 0, 0, 0x0012, "GPSMapDatum", &stdInterpreter, + 0, 1, 0, 0, 0x0013, "GPSDestLatitudeRef", &stdInterpreter, + 0, 1, 0, 0, 0x0014, "GPSDestLatitude", &stdInterpreter, + 0, 1, 0, 0, 0x0015, "GPSDestLongitudeRef", &stdInterpreter, + 0, 1, 0, 0, 0x0016, "GPSDestLongitude", &stdInterpreter, + 0, 1, 0, 0, 0x0017, "GPSDestBearingRef", &stdInterpreter, + 0, 1, 0, 0, 0x0018, "GPSDestBearing", &stdInterpreter, + 0, 1, 0, 0, 0x0019, "GPSDestDistanceRef", &stdInterpreter, + 0, 1, 0, 0, 0x001a, "GPSDestDistance", &stdInterpreter, + 0, 1, 0, 0, 0x001b, "GPSProcessingMethod", &stdInterpreter, + 0, 1, 0, 0, 0x001c, "GPSAreaInformation", &stdInterpreter, + 0, 1, 0, 0, 0x001d, "GPSDateStamp", &stdInterpreter, + 0, 1, 0, 0, 0x001e, "GPSDifferential", &stdInterpreter, + -1, 0, 0, 0, 0, "", NULL }; + + + +const TagAttrib iopAttribs[] = { + 0, 1, 0, 0, 0x0001, "InteroperabilityIndex", &stdInterpreter, + 0, 1, 0, 0, 0x0002, "InteroperabilityVersion", &stdInterpreter, +-1, 0, 0, 0, 0, "", NULL }; + + const TagAttrib ifdAttribs[] = { + 0, 2, 0, 0, 0x0017, "PanaISO", &stdInterpreter, + 0, 2, 0, 0, 0x0100, "ImageWidth", &stdInterpreter, + 0, 2, 0, 0, 0x0101, "ImageHeight", &stdInterpreter, + 0, 2, 0, 0, 0x0102, "BitsPerSample", &stdInterpreter, + 0, 2, 0, 0, 0x0103, "Compression", &compressionInterpreter, + 0, 2, 0, 0, 0x0106, "PhotometricInterpretation", &photometricInterpreter, + 0, 2, 0, 0, 0x0112, "Orientation", &stdInterpreter, + 0, 2, 0, 0, 0x0115, "SamplesPerPixel", &stdInterpreter, + 0, 2, 0, 0, 0x011C, "PlanarConfiguration", &planarConfigInterpreter, + 0, 2, 0, 0, 0x0212, "YCbCrSubSampling", &stdInterpreter, + 0, 2, 0, 0, 0x0213, "YCbCrPositioning", &stdInterpreter, + 0, 2, 0, 0, 0x011A, "XResolution", &stdInterpreter, + 0, 2, 0, 0, 0x011B, "YResolution", &stdInterpreter, + 0, 2, 0, 0, 0x0128, "ResolutionUnit", &stdInterpreter, + 1, 0, 0, 0, 0x0111, "StripOffsets", &stdInterpreter, + 1, 0, 0, 0, 0x0116, "RowsPerStrip", &stdInterpreter, + 1, 0, 0, 0, 0x0117, "StripByteCounts", &stdInterpreter, + 0, 2, 0, 0, 0x0201, "JPEGInterchangeFormat", &stdInterpreter, + 0, 2, 0, 0, 0x0202, "JPEGInterchangeFormatLength", &stdInterpreter, + 0, 2, 0, 0, 0x012D, "TransferFunction", &stdInterpreter, + 0, 2, 0, 0, 0x013E, "WhitePoint", &stdInterpreter, + 0, 2, 0, 0, 0x013F, "PriomaryChromaticities", &stdInterpreter, + 0, 2, 0, 0, 0x0211, "YCbCrCoefficients", &stdInterpreter, + 0, 2, 0, 0, 0x0214, "ReferenceBlackWhite", &stdInterpreter, + 0, 1, 0, 0, 0x0132, "DateTime", &stdInterpreter, + 0, 1, 1, 0, 0x010E, "ImageDescription", &stdInterpreter, + 0, 1, 0, 0, 0x010F, "Make", &stdInterpreter, + 0, 1, 0, 0, 0x0110, "Model", &stdInterpreter, + 0, 2, 0, 0, 0x0131, "Software", &stdInterpreter, + 0, 1, 1, 0, 0x013B, "Artist", &stdInterpreter, + 0, 1, 1, 0, 0x8298, "Copyright", &stdInterpreter, + 0, 1, 0, exifAttribs, 0x8769, "Exif", &stdInterpreter, + 0, 2, 0, 0, 0x8773, "ICCProfile", &stdInterpreter, + 0, 2, 0, 0, 0x83BB, "IPTCData", &stdInterpreter, + 0, 1, 0, gpsAttribs, 0x8825, "GPSInfo", &stdInterpreter, + 0, 1, 0, 0, 0x9003, "DateTimeOriginal", &stdInterpreter, + 0, 1, 0, 0, 0x9004, "DateTimeDigitized", &stdInterpreter, + 0, 1, 0, iopAttribs, 0xA005, "Interoperability", &stdInterpreter, + 1, 2, 0, ifdAttribs, 0x014A, "SubIFD", &stdInterpreter, + 0, 0, 0, 0, 0xC4A5, "PrintIMInformation", &stdInterpreter, + 0, 2, 0, 0, 0x00fe, "NewSubFileType", &stdInterpreter, + -1, 0, 0, 0, 0, "", NULL}; + +}; + +/*#include +#include +#include +#include +#include +#include */ + +#endif diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt new file mode 100644 index 000000000..6bbb5736b --- /dev/null +++ b/rtgui/CMakeLists.txt @@ -0,0 +1,52 @@ + +set (BASESOURCEFILES + batchtoolpanelcoord.cc paramsedited.cc cropwindow.cc previewhandler.cc previewwindow.cc navigator.cc indclippedpanel.cc filterpanel.cc + cursormanager.cc rtwindow.cc renamedlg.cc recentbrowser.cc placesbrowser.cc filepanel.cc editorpanel.cc batchqueuepanel.cc + ilabel.cc thumbbrowserbase.cc adjuster.cc filebrowserentry.cc filebrowser.cc filethumbnailbuttonset.cc + cachemanager.cc cacheimagedata.cc shcselector.cc + clipboard.cc thumbimageupdater.cc bqentryupdater.cc + coarsepanel.cc cacorrection.cc colorshift.cc hlrec.cc chmixer.cc + colorboost.cc resize.cc icmpanel.cc crop.cc shadowshighlights.cc + colordenoise.cc + exifpanel.cc + sharpening.cc + whitebalance.cc vignetting.cc rotate.cc distortion.cc + crophandler.cc curveeditor.cc dirbrowser.cc + filecatalog.cc + histogrampanel.cc history.cc imagearea.cc + imageareapanel.cc iptcpanel.cc lcurve.cc lumadenoise.cc main.cc + multilangmgr.cc mycurve.cc options.cc + preferences.cc profilepanel.cc safegtk.cc saveasdlg.cc + saveformatpanel.cc splash.cc + thumbnail.cc tonecurve.cc toolbar.cc + guiutils.cc zoompanel.cc toolpanelcoord.cc + thumbbrowserentrybase.cc batchqueueentry.cc + batchqueue.cc lwbutton.cc lwbuttonset.cc + batchqueuebuttonset.cc browserfilter.cc exiffiltersettings.cc + profilestore.cc partialpastedlg.cc) + +if (WIN32) + set (EXTRA_SRC windirmonitor.cc myicon.o) + include_directories ( ../rtengine ${CMAKE_CURRENT_BINARY_DIR} . ../rtexif ${EXTRA_INCDIR} ${GLIB2_INCLUDE_DIRS} ${GLIBMM_INCLUDE_DIRS} + ${GTK_INCLUDE_DIRS} ${GTKMM_INCLUDE_DIRS} ${GIO_INCLUDE_DIRS} ${GIOMM_INCLUDE_DIRS}) + link_directories (. ../rtexif ${EXTRA_LIBDIR} ${GLIB2_LIBRARY_DIRS} ${GLIBMM_LIBRARY_DIRS} + ${GTK_LIBRARY_DIRS} ${GTKMM_LIBRARY_DIRS} ${GIO_LIBRARY_DIRS} ${GIOMM_LIBRARY_DIRS}) + #set_target_properties (rth PROPERTIES LINK_FLAGS "-mwindows") +else (WIN32) + include_directories (${CMAKE_CURRENT_SOURCE_DIR}/../rtengine ${CMAKE_CURRENT_BINARY_DIR} . ${CMAKE_CURRENT_SOURCE_DIR}/../rtexif ${EXTRA_INCDIR} ${GLIB2_INCLUDE_DIRS} ${GLIBMM_INCLUDE_DIRS} + ${GTK_INCLUDE_DIRS} ${GTKMM_INCLUDE_DIRS} ${GIO_INCLUDE_DIRS} ${GIOMM_INCLUDE_DIRS} ${IPTCDATA_INCLUDE_DIRS} ${LCMS_INCLUDE_DIRS} ${GTHREAD_INCLUDE_DIRS} ${GOBJECT_INCLUDE_DIRS} ) + link_directories (${CMAKE_CURRENT_SOURCE_DIR}/../rtexif ${EXTRA_LIBDIR} ${GLIB2_LIBRARY_DIRS} ${GLIBMM_LIBRARY_DIRS} + ${GTK_LIBRARY_DIRS} ${GTKMM_LIBRARY_DIRS} ${GIO_LIBRARY_DIRS} ${GIOMM_LIBRARY_DIRS} ${IPTCDATA_LIBRARY_DIRS} ${LCMS_LIBRARY_DIRS} ${GTHREAD_LIBRARY_DIRS} ${GOBJECT_LIBRARY_DIRS}) + # create config.h which defines where data are stored + configure_file (${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) +endif (WIN32) + +add_executable (rth ${EXTRA_SRC} ${BASESOURCEFILES}) + +set_target_properties (rth PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS}" OUTPUT_NAME rt) +#target_link_libraries (rth rtengine ${JPEG_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${TIFF_LIBRARIES} ${EXTRA_LIB} ${GOBJECT_LIBRARIES} ${GTHREAD_LIBRARIES} +# ${GLIB2_LIBRARIES} ${GLIBMM_LIBRARIES} ${GTK_LIBRARIES} ${GTKMM_LIBRARIES} ${GIO_LIBRARIES} ${GIOMM_LIBRARIES} ${LCMS_LIBRARIES} ${IPTCDATA_LIBRARIES}) +target_link_libraries (rth rtengine ${JPEG_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${TIFF_LIBRARIES} ${GOBJECT_LIBRARIES} ${GTHREAD_LIBRARIES} + ${GLIB2_LIBRARIES} ${GLIBMM_LIBRARIES} ${GTK_LIBRARIES} ${GTKMM_LIBRARIES} ${GIO_LIBRARIES} ${GIOMM_LIBRARIES} ${LCMS_LIBRARIES} ${IPTCDATA_LIBRARIES}) +install (TARGETS rth DESTINATION ${BINDIR}) + diff --git a/rtgui/RT.ico b/rtgui/RT.ico new file mode 100644 index 000000000..d7befa1a7 Binary files /dev/null and b/rtgui/RT.ico differ diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h new file mode 100644 index 000000000..05be8f225 --- /dev/null +++ b/rtgui/addsetids.h @@ -0,0 +1,28 @@ +#ifndef _ADDSETIDS_ +#define _ADDSETIDS_ + +#define ADDSET_TC_EXPCOMP 0 +#define ADDSET_TC_BRIGHTNESS 1 +#define ADDSET_TC_BLACKLEVEL 2 +#define ADDSET_TC_CONTRAST 3 +#define ADDSET_SH_HIGHLIGHTS 4 +#define ADDSET_SH_SHADOWS 5 +#define ADDSET_SH_LOCALCONTRAST 6 +#define ADDSET_LC_BRIGHTNESS 7 +#define ADDSET_LC_CONTRAST 8 +#define ADDSET_SHARP_AMOUNT 9 +#define ADDSET_LD_EDGETOLERANCE 10 +#define ADDSET_WB_TEMPERATURE 11 +#define ADDSET_WB_GREEN 12 +#define ADDSET_CBOOST_AMOUNT 13 +#define ADDSET_CS_BLUEYELLOW 14 +#define ADDSET_CS_GREENMAGENTA 15 +#define ADDSET_ROTATE_DEGREE 16 +#define ADDSET_DIST_AMOUNT 17 +#define ADDSET_CA_BLUE 18 +#define ADDSET_CA_RED 19 +#define ADDSET_VIGN_AMOUNT 20 + +#define ADDSET_PARAM_NUM 21 + +#endif diff --git a/rtgui/adjuster.cc b/rtgui/adjuster.cc new file mode 100644 index 000000000..8151076ee --- /dev/null +++ b/rtgui/adjuster.cc @@ -0,0 +1,274 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include + +extern Glib::ustring argv0; + +int Adjuster::delay = 1000; + +Adjuster::Adjuster (Glib::ustring vlabel, double vmin, double vmax, double vstep, double vdefault, bool editedcb) { + + adjusterListener = NULL; + afterReset = false; + + set_border_width (2); + + hbox = Gtk::manage (new Gtk::HBox ()); + + label = Gtk::manage (new Gtk::Label (vlabel, Gtk::ALIGN_LEFT)); + + if (editedcb) { + editedCheckBox = new Gtk::CheckButton (); + editedChange = editedCheckBox->signal_toggled().connect( sigc::mem_fun(*this, &Adjuster::editedToggled) ); + hbox->pack_start (*editedCheckBox); + } + else + editedCheckBox = NULL; + + hbox->pack_start (*label); + + reset = Gtk::manage (new Gtk::Button ()); + reset->add (*Gtk::manage (new Gtk::Image (argv0+"/images/undo.png"))); + reset->set_relief (Gtk::RELIEF_NONE); + reset->set_border_width (0); + reset->set_tooltip_text (M("ADJUSTER_RESET_TO_DEFAULT")); + + hbox->pack_end (*reset, Gtk::PACK_SHRINK, 0); + + spin = Gtk::manage (new Gtk::SpinButton ()); + spin->set_size_request (70, -1); + + hbox->pack_end (*spin, Gtk::PACK_SHRINK, 0); + + reset->set_size_request (-1, spin->get_height()); + + slider = Gtk::manage (new Gtk::HScale ()); + slider->set_draw_value (false); + + pack_start (*hbox, false, false); + pack_start (*slider, false, false); + + setLimits (vmin, vmax, vstep, vdefault); + + defaultVal = shapeValue (vdefault); + editedState = defEditedState = Irrelevant; + + sliderChange = slider->signal_value_changed().connect( sigc::mem_fun(*this, &Adjuster::sliderChanged) ); + spinChange = spin->signal_value_changed().connect ( sigc::mem_fun(*this, &Adjuster::spinChanged), true); + reset->signal_clicked().connect( sigc::mem_fun(*this, &Adjuster::resetPressed) ); + slider->set_update_policy (Gtk::UPDATE_CONTINUOUS); + + show_all (); +} + +Adjuster::~Adjuster () { + + sliderChange.block (true); + spinChange.block (true); + delayConnection.block (true); + adjusterListener = NULL; +} + +void Adjuster::setDefault (double def) { + + defaultVal = shapeValue (def); +} + +void Adjuster::setDefaultEditedState (EditedState eState) { + + defEditedState = eState; +} + +void Adjuster::resetPressed () { + + if (editedState!=Irrelevant) { + editedState = defEditedState; + if (editedCheckBox) { + editedChange.block (true); + editedCheckBox->set_active (defEditedState==Edited); + editedChange.block (false); + } + refreshLabelStyle (); + } + afterReset = true; + slider->set_value (defaultVal); +} + +double Adjuster::shapeValue (double a) { + + return round(a*pow(double(10), digits)) / pow(double(10), digits); +} + +void Adjuster::setLimits (double vmin, double vmax, double vstep, double vdefault) { + + sliderChange.block (true); + spinChange.block (true); + for (digits=0; fabs(vstep*pow(double(10),digits)-floor(vstep*pow(double(10),digits)))>0.000000000001; digits++); + spin->set_digits (digits); + spin->set_increments (vstep, 2.0*vstep); + spin->set_range (vmin, vmax); + spin->set_value (shapeValue(vdefault)); + slider->set_digits (digits); + slider->set_increments (vstep, 2.0*vstep); + slider->set_range (vmin, vmax); + slider->set_value (shapeValue(vdefault)); + defaultVal = shapeValue (vdefault); + sliderChange.block (false); + spinChange.block (false); +} + +void Adjuster::setAdjusterListener (AdjusterListener* alistener) { + + adjusterListener = alistener; +} + +void Adjuster::spinChanged () { + + sliderChange.block (true); + slider->set_value (spin->get_value ()); + sliderChange.block (false); + + if (delay==0) { + if (adjusterListener!=NULL) + adjusterListener->adjusterChanged (this, spin->get_value ()); + } + else + Glib::signal_idle().connect (sigc::mem_fun(*this, &Adjuster::notifyListener)); + + if (editedState==UnEdited) { + editedState = Edited; + if (editedCheckBox) { + editedChange.block (true); + editedCheckBox->set_active (true); + editedChange.block (false); + } + refreshLabelStyle (); + } + afterReset = false; +} + +void Adjuster::sliderChanged () { + + if (delayConnection.connected()) + delayConnection.disconnect (); + + spinChange.block (true); + spin->set_value (slider->get_value ()); + spinChange.block (false); + + if (delay==0) { + if (adjusterListener) + adjusterListener->adjusterChanged (this, spin->get_value ()); + } + else + delayConnection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &Adjuster::notifyListener), delay); + + if (!afterReset && editedState==UnEdited) { + editedState = Edited; + if (editedCheckBox) { + editedChange.block (true); + editedCheckBox->set_active (true); + editedChange.block (false); + } + refreshLabelStyle (); + } + afterReset = false; +} + +void Adjuster::setValue (double a) { + + spinChange.block (true); + sliderChange.block (true); + spin->set_value (shapeValue (a)); + slider->set_value (shapeValue (a)); + sliderChange.block (false); + spinChange.block (false); + afterReset = false; +} + +double Adjuster::getValue () { + + return spin->get_value (); +} + +bool Adjuster::notifyListener () { + + gdk_threads_enter(); + + if (adjusterListener!=NULL) + adjusterListener->adjusterChanged (this, spin->get_value ()); + gdk_threads_leave(); + + return false; +} + +void Adjuster::setEnabled (bool enabled) { + + spin->set_sensitive (enabled); + slider->set_sensitive (enabled); +} +void Adjuster::setEditedState (EditedState eState) { + + if (editedState!=eState) { + if (editedCheckBox) { + editedChange.block (true); + editedCheckBox->set_active (eState==Edited); + editedChange.block (false); + } + editedState = eState; + refreshLabelStyle (); + } +} + +EditedState Adjuster::getEditedState () { + + if (editedState!=Irrelevant && editedCheckBox) + editedState = editedCheckBox->get_active () ? Edited : UnEdited; + return editedState; +} + +void Adjuster::showEditedCB () { + + if (!editedCheckBox) { + editedCheckBox = new Gtk::CheckButton (); + hbox->pack_start (*editedCheckBox, Gtk::PACK_SHRINK, 2); + hbox->reorder_child (*editedCheckBox, 0); + editedChange = editedCheckBox->signal_toggled().connect( sigc::mem_fun(*this, &Adjuster::editedToggled) ); + } +} + +void Adjuster::refreshLabelStyle () { + +/* Glib::RefPtr style = label->get_style (); + Pango::FontDescription fd = style->get_font (); + fd.set_weight (editedState==Edited ? Pango::WEIGHT_BOLD : Pango::WEIGHT_NORMAL); + style->set_font (fd); + label->set_style (style); + label->queue_draw ();*/ +} + +void Adjuster::editedToggled () { + + if (adjusterListener) + adjusterListener->adjusterChanged (this, spin->get_value ()); +} diff --git a/rtgui/adjuster.h b/rtgui/adjuster.h new file mode 100644 index 000000000..c0222dde4 --- /dev/null +++ b/rtgui/adjuster.h @@ -0,0 +1,83 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _ADJUSTER_H_ +#define _ADJUSTER_H_ + +#include +#include + +class Adjuster; +class AdjusterListener { + + public: + virtual void adjusterChanged (Adjuster* a, double newval) {} +}; + + +class Adjuster : public Gtk::VBox { + + protected: + Gtk::HBox* hbox; + Gtk::Label* label; + Gtk::HScale* slider; + Gtk::SpinButton* spin; + Gtk::Button* reset; + AdjusterListener* adjusterListener; + sigc::connection delayConnection; + sigc::connection spinChange; + sigc::connection sliderChange; + sigc::connection editedChange; + bool listenerReady; + double defaultVal; + EditedState editedState; + EditedState defEditedState; + int digits; + Gtk::CheckButton* editedCheckBox; + bool afterReset; + + double shapeValue (double a); + void refreshLabelStyle (); + + public: + + static int delay; + + Adjuster (Glib::ustring label, double vmin, double vmax, double vstep, double vdefault, bool editedCheckBox=false); + virtual ~Adjuster (); + void setAdjusterListener (AdjusterListener* alistener); + + double getValue (); + void setValue (double a); + void setLimits (double vmin, double vmax, double vstep, double vdefault); + void setEnabled (bool enabled); + void setDefault (double def); + void setEditedState (EditedState eState); + EditedState getEditedState (); + void setDefaultEditedState (EditedState eState); + void showEditedCB (); + + + void spinChanged (); + void sliderChanged (); + bool notifyListener (); + void resetPressed (); + void editedToggled (); +}; + +#endif diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc new file mode 100644 index 000000000..c44bd9f2f --- /dev/null +++ b/rtgui/batchqueue.cc @@ -0,0 +1,403 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include +#include + +using namespace rtengine; + +BatchQueue::BatchQueue () : processing(NULL), listener(NULL) { + + int p = 0; + pmenu = new Gtk::Menu (); + pmenu->attach (*(cancel = new Gtk::MenuItem (M("FILEBROWSER_POPUPCANCELJOB"))), 0, 1, p, p+1); p++; + pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + pmenu->attach (*(head = new Gtk::MenuItem (M("FILEBROWSER_POPUPMOVEHEAD"))), 0, 1, p, p+1); p++; + pmenu->attach (*(tail = new Gtk::MenuItem (M("FILEBROWSER_POPUPMOVEEND"))), 0, 1, p, p+1); p++; + pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + pmenu->attach (*(selall = new Gtk::MenuItem (M("FILEBROWSER_POPUPSELECTALL"))), 0, 1, p, p+1); p++; + pmenu->show_all (); + + cancel->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &BatchQueue::cancelItems), &selected)); + head->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &BatchQueue::headItems), &selected)); + tail->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &BatchQueue::tailItems), &selected)); + selall->signal_activate().connect (sigc::mem_fun(*this, &BatchQueue::selectAll)); +} + +void BatchQueue::rightClicked (ThumbBrowserEntryBase* entry) { + + pmenu->popup (3, 0); +} + +void BatchQueue::addEntry (BatchQueueEntry* entry, bool head) { + + entry->setParent (this); + entry->resize (options.thumbSize); + + entry->selected = false; + if (!head) + fd.push_back (entry); + else { + std::vector::iterator pos; + for (pos=fd.begin(); pos!=fd.end(); pos++) + if (!(*pos)->processing) { + fd.insert (pos, entry); + break; + } + if (pos==fd.end()) + fd.push_back (entry); + } + + if (entry->thumbnail) + entry->thumbnail->imageEnqueued (); + + BatchQueueButtonSet* bqbs = new BatchQueueButtonSet (entry); + bqbs->setButtonListener (this); + entry->addButtonSet (bqbs); + + arrangeFiles (); + queue_draw (); + notifyListener (); +} + +int deleteitem (void* data) { + + gdk_threads_enter (); + delete (BatchQueueEntry*)data; + gdk_threads_leave (); + return 0; +} + +void BatchQueue::cancelItems (std::vector* items) { + + for (int i=0; isize(); i++) { + BatchQueueEntry* entry = (BatchQueueEntry*)(*items)[i]; + if (entry->processing) + continue; + std::vector::iterator pos = std::find (fd.begin(), fd.end(), entry); + if (pos!=fd.end()) { + fd.erase (pos); + rtengine::ProcessingJob::destroy (entry->job); + if (entry->thumbnail) + entry->thumbnail->imageRemovedFromQueue (); + g_idle_add (deleteitem, entry); + } + } + for (int i=0; iselected = false; + lastClicked = NULL; + selected.clear (); + redraw (); + notifyListener (); +} + +void BatchQueue::headItems (std::vector* items) { + + for (int i=items->size()-1; i>=0; i--) { + BatchQueueEntry* entry = (BatchQueueEntry*)(*items)[i]; + if (entry->processing) + continue; + std::vector::iterator pos = std::find (fd.begin(), fd.end(), entry); + if (pos!=fd.end() && pos!=fd.begin()) { + fd.erase (pos); + // find the first item that is not under processing + for (pos=fd.begin(); pos!=fd.end(); pos++) + if (!(*pos)->processing) { + fd.insert (pos, entry); + break; + } + } + } + redraw (); +} + +void BatchQueue::tailItems (std::vector* items) { + + for (int i=0; isize(); i++) { + BatchQueueEntry* entry = (BatchQueueEntry*)(*items)[i]; + if (entry->processing) + continue; + std::vector::iterator pos = std::find (fd.begin(), fd.end(), entry); + if (pos!=fd.end()) { + fd.erase (pos); + fd.push_back (entry); + } + } + redraw (); +} + +void BatchQueue::selectAll () { + + lastClicked = NULL; + selected.clear (); + for (int i=0; iprocessing) + continue; + fd[i]->selected = true; + selected.push_back (fd[i]); + } + queue_draw (); +} +void BatchQueue::startProcessing () { + + if (!processing && fd.size()>0) { + BatchQueueEntry* next = (BatchQueueEntry*)fd[0]; + // tag it as processing + next->processing = true; + processing = next; + // remove from selection + if (processing->selected) { + std::vector::iterator pos = std::find (selected.begin(), selected.end(), processing); + if (pos!=selected.end()) + selected.erase (pos); + processing->selected = false; + } + // remove button set + next->removeButtonSet (); + // start batch processing + rtengine::startBatchProcessing (next->job, this); + queue_draw (); + } +} + +rtengine::ProcessingJob* BatchQueue::imageReady (rtengine::IImage16* img) { + + gdk_threads_enter (); + // save image img + Glib::ustring fname; + SaveFormat saveFormat; + if (processing->outFileName=="") { // auto file name + fname = obtainFileName (processing->filename); + saveFormat = options.saveFormat; + } + else { // use the save-as filename with automatic completion for uniqueness + fname = autoCompleteFileName (removeExtension(processing->outFileName), getExtension(processing->outFileName)); + saveFormat = processing->saveFormat; + } + printf ("fname=%s, %s\n", fname.c_str(), removeExtension(fname).c_str()); + if (img && fname!="") { + int err = 0; + if (saveFormat.format=="tif") + err = img->saveAsTIFF (fname, saveFormat.tiffBits); + else if (saveFormat.format=="png") + err = img->saveAsPNG (fname, saveFormat.pngCompression, saveFormat.pngBits); + else if (saveFormat.format=="jpg") + err = img->saveAsJPEG (fname, saveFormat.jpegQuality); + img->free (); + if (!err && saveFormat.saveParams) + processing->params.save (removeExtension(fname) + ".pp2"); + if (processing->thumbnail) { + processing->thumbnail->imageDeveloped (); + processing->thumbnail->imageRemovedFromQueue (); + if (listener) + listener->imageProcessingReady (processing->filename); + } + } + + // delete from the queue + delete processing; + processing = NULL; + fd.erase (fd.begin()); + // return next job + if (fd.size()==0) { + if (listener) + listener->queueEmpty (); + } + else if (listener && listener->canStartNext ()) { + BatchQueueEntry* next = (BatchQueueEntry*)fd[0]; + // tag it as selected + next->processing = true; + processing = next; + // remove from selection + if (processing->selected) { + std::vector::iterator pos = std::find (selected.begin(), selected.end(), processing); + if (pos!=selected.end()) + selected.erase (pos); + processing->selected = false; + } + // remove button set + next->removeButtonSet (); + } + redraw (); + notifyListener (); + gdk_threads_leave (); + return processing ? processing->job : NULL; +} + +Glib::ustring BatchQueue::obtainFileName (const Glib::ustring& origFileName) { + + std::vector pa; + std::vector da; + + for (int i=0; i=origFileName.size()) + break; + Glib::ustring tok = ""; + while ((i=0 && origFileName[extpos]!='.'; extpos--); + for (int k=extpos-1; k>=0 && origFileName[k]!='/' && origFileName[k]!='\\'; k--) + filename = origFileName[k] + filename; + +// printf ("%d, |%s|\n", extpos, filename.c_str()); + + // constructing full output path +// printf ("path=|%s|\n", options.savePath.c_str()); + + Glib::ustring path=""; + if (options.saveUsePathTemplate) { + int ix=0; + while (options.savePathTemplate[ix]!=0) { + if (options.savePathTemplate[ix]=='%') { + ix++; + if (options.savePathTemplate[ix]=='p') { + ix++; + int i = options.savePathTemplate[ix]-'0'; + if (iredraw(); + gdk_threads_leave (); + return 0; +} + +void BatchQueue::setProgress (double p) { + + if (processing) + processing->progress = p; + + g_idle_add (bqredraw, this); +} + +void BatchQueue::buttonPressed (LWButton* button, int actionCode, void* actionData) { + + std::vector bqe; + bqe.push_back ((BatchQueueEntry*)actionData); + + if (actionCode==10) // cancel + cancelItems (&bqe); + else if (actionCode==8) // to head + headItems (&bqe); + else if (actionCode==9) // to tail + tailItems (&bqe); +} + +struct NLParams { + BatchQueueListener* listener; + int qsize; +}; + +int bqnotifylistener (void* data) { + + gdk_threads_enter (); + NLParams* params = (NLParams*)data; + params->listener->queueSizeChanged (params->qsize); + delete params; + gdk_threads_leave (); + return 0; +} + +void BatchQueue::notifyListener () { + + if (listener) { + NLParams* params = new NLParams; + params->listener = listener; + params->qsize = fd.size(); + g_idle_add (bqnotifylistener, params); + } +} + +void BatchQueue::redrawNeeded (LWButton* button) { + + queue_draw (); +} diff --git a/rtgui/batchqueue.h b/rtgui/batchqueue.h new file mode 100644 index 000000000..32c5f666a --- /dev/null +++ b/rtgui/batchqueue.h @@ -0,0 +1,84 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _BATCHQUEUE_ +#define _BATCHQUEUE_ + +#include +#include +#include +#include +#include +#include + +class BatchQueueListener { + + public: + virtual void queueSizeChanged (int qsize) =0; + virtual void imageProcessingReady (Glib::ustring fname) =0; + virtual void queueEmpty () =0; + virtual bool canStartNext () =0; +}; + +class FileCatalog; +class BatchQueue : public ThumbBrowserBase, + public rtengine::BatchProcessingListener, + public LWButtonListener { + + protected: + + BatchQueueEntry* processing; + + Glib::ustring nameTemplate; + + Gtk::MenuItem* cancel; + Gtk::MenuItem* head; + Gtk::MenuItem* tail; + Gtk::MenuItem* selall; + Gtk::Menu* pmenu; + + BatchQueueListener* listener; + + Glib::ustring obtainFileName (const Glib::ustring& origFileName); + Glib::ustring autoCompleteFileName (const Glib::ustring& fileName, const Glib::ustring& format); + + public: + BatchQueue (); + + void addEntry (BatchQueueEntry* entry, bool head=false); + + void cancelItems (std::vector* items); + void headItems (std::vector* items); + void tailItems (std::vector* items); + void selectAll (); + + void startProcessing (); + + bool hasJobs () { return fd.size()>0; } + + rtengine::ProcessingJob* imageReady (rtengine::IImage16* img); + void setProgress (double p); + void rightClicked (ThumbBrowserEntryBase* entry); + void buttonPressed (LWButton* button, int actionCode, void* actionData); + void redrawNeeded (LWButton* button); + + void setBatchQueueListener (BatchQueueListener* l) { listener = l; } + void notifyListener (); +}; + +#endif diff --git a/rtgui/batchqueuebuttonset.cc b/rtgui/batchqueuebuttonset.cc new file mode 100644 index 000000000..36ebc4363 --- /dev/null +++ b/rtgui/batchqueuebuttonset.cc @@ -0,0 +1,42 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +extern Glib::ustring argv0; + +bool BatchQueueButtonSet::iconsLoaded = false; + +Cairo::RefPtr BatchQueueButtonSet::cancelIcon; +Cairo::RefPtr BatchQueueButtonSet::headIcon; +Cairo::RefPtr BatchQueueButtonSet::tailIcon; + +BatchQueueButtonSet::BatchQueueButtonSet (BatchQueueEntry* myEntry) { + + if (!iconsLoaded) { + cancelIcon = Cairo::ImageSurface::create_from_png (argv0+"/images/deltags.png"); + headIcon = Cairo::ImageSurface::create_from_png (argv0+"/images/head.png"); + tailIcon = Cairo::ImageSurface::create_from_png (argv0+"/images/tail.png"); + iconsLoaded = true; + } + + add (new LWButton (headIcon, 8, myEntry, LWButton::Left, LWButton::Center, M("FILEBROWSER_POPUPMOVEHEAD"))); + add (new LWButton (tailIcon, 9, myEntry, LWButton::Left, LWButton::Center, M("FILEBROWSER_POPUPMOVEEND"))); + add (new LWButton (cancelIcon, 10, myEntry, LWButton::Right, LWButton::Center, M("FILEBROWSER_POPUPCANCELJOB"))); +} diff --git a/rtgui/batchqueuebuttonset.h b/rtgui/batchqueuebuttonset.h new file mode 100644 index 000000000..4b92c3d85 --- /dev/null +++ b/rtgui/batchqueuebuttonset.h @@ -0,0 +1,38 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _BATCHQUEUEBUTTONSET_ +#define _BATCHQUEUEBUTTONSET_ + +#include +#include + +class BatchQueueEntry; +class BatchQueueButtonSet : public LWButtonSet { + + static bool iconsLoaded; + + public: + static Cairo::RefPtr cancelIcon; + static Cairo::RefPtr headIcon; + static Cairo::RefPtr tailIcon; + + BatchQueueButtonSet (BatchQueueEntry* myEntry); +}; + +#endif diff --git a/rtgui/batchqueueentry.cc b/rtgui/batchqueueentry.cc new file mode 100644 index 000000000..8a74829d7 --- /dev/null +++ b/rtgui/batchqueueentry.cc @@ -0,0 +1,156 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, guint8* previmg, int prevw, int prevh, Thumbnail* thumbnail) + : job(pjob), ThumbBrowserEntryBase(fname), + opreview(previmg), origpw(prevw), origph(prevh), progress(0), thumbnail(thumbnail), + outFileName("") { + + params = pparams; + + bqih = new BatchQueueEntryIdleHelper; + bqih->bqentry = this; + bqih->destroyed = false; + bqih->pending = 0; + + if (thumbnail) + thumbnail->increaseRef (); +} + +BatchQueueEntry::~BatchQueueEntry () { + + batchQueueEntryUpdater.removeJobs (this); + delete [] opreview; + if (thumbnail) + thumbnail->decreaseRef (); + + if (bqih->pending) + bqih->destroyed = true; + else + delete bqih; +} + +void BatchQueueEntry::refreshThumbnailImage () { + + if (!opreview) + return; + + batchQueueEntryUpdater.add (opreview, origpw, origph, preh, this); + batchQueueEntryUpdater.process (); +} + +void BatchQueueEntry::calcThumbnailSize () { + + prew = preh * origpw / origph; +} + + +void BatchQueueEntry::drawProgressBar (Glib::RefPtr win, Glib::RefPtr gc, const Gdk::Color& foregr, const Gdk::Color& backgr, int x, int w, int y, int h) { + + if (processing) { + Cairo::RefPtr cr = win->create_cairo_context(); + cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + double px = x + w/6.0; + double pw = w*2.0/3.0; + double py = y + h/4.0; + double ph = h/2.0; + cr->move_to (px, py); + cr->line_to (px+pw, py); + cr->set_line_width (ph); + cr->set_line_cap (Cairo::LINE_CAP_ROUND); + cr->set_source_rgb (foregr.get_red_p(), foregr.get_green_p(), foregr.get_blue_p()); + cr->stroke (); + + cr->move_to (px, py); + cr->line_to (px+pw, py); + cr->set_line_width (ph*3.0/4.0); + cr->set_source_rgb (backgr.get_red_p(), backgr.get_green_p(), backgr.get_blue_p()); + cr->stroke (); + + cr->move_to (px, py); + cr->line_to (px+pw*progress, py); + cr->set_line_width (ph/2.0); + cr->set_source_rgb (foregr.get_red_p(), foregr.get_green_p(), foregr.get_blue_p()); + cr->stroke (); + } +} + +void BatchQueueEntry::removeButtonSet () { + + delete buttonSet; + buttonSet = NULL; +} +struct bqupdate { + BatchQueueEntryIdleHelper* bqih; + guint8* img; + int w,h; +}; + +int bqeupdate (void* data) { + + gdk_threads_enter (); + bqupdate* params = (bqupdate*)data; + + BatchQueueEntryIdleHelper* bqih = params->bqih; + + if (bqih->destroyed) { + if (bqih->pending == 1) + delete bqih; + else + bqih->pending--; + delete [] params->img; + delete params; + gdk_threads_leave (); + return 0; + } + + bqih->bqentry->_updateImage (params->img, params->w, params->h); + bqih->pending--; + + gdk_threads_leave (); + delete params; + return 0; +} + +void BatchQueueEntry::updateImage (guint8* img, int w, int h) { + + bqih->pending++; + + bqupdate* param = new bqupdate (); + param->bqih = bqih; + param->img = img; + param->w = w; + param->h = h; + g_idle_add (bqeupdate, param); +} + +void BatchQueueEntry::_updateImage (guint8* img, int w, int h) { + + if (preh == h) { + prew = w; + preview = new guint8 [prew*preh*3]; + memcpy (preview, img, prew*preh*3); + if (parent) + parent->redrawNeeded (this); + } + delete [] img; +} + diff --git a/rtgui/batchqueueentry.h b/rtgui/batchqueueentry.h new file mode 100644 index 000000000..d16d96f8f --- /dev/null +++ b/rtgui/batchqueueentry.h @@ -0,0 +1,66 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _BATCHQUEUEENTRY_ +#define _BATCHQUEUEENTRY_ + +#include +#include +#include +#include +#include + +class BatchQueueEntry; +struct BatchQueueEntryIdleHelper { + BatchQueueEntry* bqentry; + bool destroyed; + int pending; +}; + +class BatchQueueEntry : public ThumbBrowserEntryBase, public BQEntryUpdateListener { + + guint8* opreview; + int origpw, origph; + BatchQueueEntryIdleHelper* bqih; + +public: + Thumbnail* thumbnail; + rtengine::ProcessingJob* job; + rtengine::procparams::ProcParams params; + double progress; + Glib::ustring outFileName; + SaveFormat saveFormat; + + BatchQueueEntry (rtengine::ProcessingJob* job, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, guint8* previmg, int prevw, int prevh, Thumbnail* thumbnail=NULL); + ~BatchQueueEntry (); + + void refreshThumbnailImage (); + void calcThumbnailSize (); + + void drawProgressBar (Glib::RefPtr win, Glib::RefPtr gc, const Gdk::Color& foregr, const Gdk::Color& backgr, int x, int w, int y, int h); + + void removeButtonSet (); + + // bqentryupdatelistener interface + void updateImage (guint8* img, int w, int h); + void _updateImage (guint8* img, int w, int h); // inside gtk thread +}; + + + +#endif diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc new file mode 100644 index 000000000..e094083c2 --- /dev/null +++ b/rtgui/batchqueuepanel.cc @@ -0,0 +1,242 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include + +BatchQueuePanel::BatchQueuePanel () { + + batchQueue = new BatchQueue(); + + // construct batch queue panel with the extra "start" and "stop" button + Gtk::VBox* batchQueueButtonBox = Gtk::manage (new Gtk::VBox); + start = Gtk::manage (new Gtk::ToggleButton (M("FILEBROWSER_STARTPROCESSING"))); + stop = Gtk::manage (new Gtk::ToggleButton (M("FILEBROWSER_STOPPROCESSING"))); + autoStart = Gtk::manage (new Gtk::CheckButton (M("BATCHQUEUE_AUTOSTART"))); + start->set_tooltip_text (M("FILEBROWSER_STARTPROCESSINGHINT")); + stop->set_tooltip_text (M("FILEBROWSER_STOPPROCESSINGHINT")); + autoStart->set_tooltip_text (M("FILEBROWSER_TOOLTIP_STOPPROCESSING")); + start->set_active (false); + stop->set_active (true); + autoStart->set_active (options.procQueueEnabled); + + start->set_image (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-media-play"), Gtk::ICON_SIZE_BUTTON))); + startConnection = start->signal_toggled().connect (sigc::mem_fun(*this, &BatchQueuePanel::startBatchProc)); + stop->set_image (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-media-stop"), Gtk::ICON_SIZE_BUTTON))); + stopConnection = stop->signal_toggled().connect (sigc::mem_fun(*this, &BatchQueuePanel::stopBatchProc)); + batchQueueButtonBox->pack_start (*start, Gtk::PACK_SHRINK, 4); + batchQueueButtonBox->pack_start (*stop, Gtk::PACK_SHRINK, 4); + batchQueueButtonBox->pack_start (*autoStart, Gtk::PACK_SHRINK, 4); + + // Output directory selection + fdir = Gtk::manage (new Gtk::Frame (M("PREFERENCES_OUTDIR"))); + Gtk::VBox* odvb = Gtk::manage (new Gtk::VBox ()); + odvb->set_border_width (4); + Gtk::HBox* hb2 = Gtk::manage (new Gtk::HBox ()); + useTemplate = Gtk::manage (new Gtk::RadioButton (M("PREFERENCES_OUTDIRTEMPLATE")+":")); + hb2->pack_start (*useTemplate, Gtk::PACK_SHRINK,4); + outdirTemplate = Gtk::manage (new Gtk::Entry ()); + hb2->pack_start (*outdirTemplate); + odvb->pack_start (*hb2, Gtk::PACK_SHRINK, 4); + outdirTemplate->set_tooltip_markup (M("PREFERENCES_OUTDIRTEMPLATEHINT")); + useTemplate->set_tooltip_markup (M("PREFERENCES_OUTDIRTEMPLATEHINT")); + Gtk::HBox* hb3 = Gtk::manage (new Gtk::HBox ()); + useFolder = Gtk::manage (new Gtk::RadioButton (M("PREFERENCES_OUTDIRFOLDER")+":")); + hb3->pack_start (*useFolder, Gtk::PACK_SHRINK,4); + outdirFolder = Gtk::manage (new Gtk::FileChooserButton (M("PREFERENCES_OUTDIRFOLDER"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + hb3->pack_start (*outdirFolder); + odvb->pack_start (*hb3, Gtk::PACK_SHRINK, 4); + outdirFolder->set_tooltip_markup (M("PREFERENCES_OUTDIRFOLDERHINT")); + useFolder->set_tooltip_markup (M("PREFERENCES_OUTDIRFOLDERHINT")); + Gtk::RadioButton::Group g = useTemplate->get_group(); + useFolder->set_group (g); + fdir->add (*odvb); + + // Output file format selection + fformat = Gtk::manage (new Gtk::Frame (M("PREFERENCES_FILEFORMAT"))); + saveFormatPanel = Gtk::manage (new SaveFormatPanel ()); + fformat->add (*saveFormatPanel); + + saveFormatPanel->init (options.saveFormat); + outdirTemplate->set_text (options.savePathTemplate); + if (Glib::file_test (options.savePathFolder, Glib::FILE_TEST_IS_DIR)) + outdirFolder->set_filename (options.savePathFolder); + useTemplate->set_active (options.saveUsePathTemplate); + useFolder->set_active (!options.saveUsePathTemplate); + + // setup signal handlers + outdirTemplate->signal_changed().connect (sigc::mem_fun(*this, &BatchQueuePanel::saveOptions)); + outdirFolder->signal_current_folder_changed().connect (sigc::mem_fun(*this, &BatchQueuePanel::saveOptions)); + useTemplate->signal_toggled().connect (sigc::mem_fun(*this, &BatchQueuePanel::saveOptions)); + useFolder->signal_toggled().connect (sigc::mem_fun(*this, &BatchQueuePanel::saveOptions)); + saveFormatPanel->setListener (this); + + // setup button bar + topBox = Gtk::manage (new Gtk::HBox ()); + pack_start (*topBox, Gtk::PACK_SHRINK); + + topBox->pack_start (*batchQueueButtonBox, Gtk::PACK_SHRINK, 4); + topBox->pack_start (*fdir); + topBox->pack_start (*fformat, Gtk::PACK_SHRINK, 4); + + // add middle browser area + Gtk::HBox* hBox = Gtk::manage (new Gtk::HBox ()); + pack_start (*batchQueue); + + // lower box with thumbnail zoom + bottomBox = Gtk::manage (new Gtk::HBox ()); + pack_start (*bottomBox, Gtk::PACK_SHRINK); + + // change thumbnail arrangement button + hAlignIcon = new Gtk::Image (argv0+"/images/horizontals.png"); + vAlignIcon = new Gtk::Image (argv0+"/images/verticals.png"); + hAlignIcon->show (); + vAlignIcon->show (); + chAlign = Gtk::manage (new Gtk::Button ()); + chAlign->show (); + bottomBox->pack_end (*chAlign, Gtk::PACK_SHRINK); + chAlign->set_image (*hAlignIcon); + chAlign->set_relief (Gtk::RELIEF_NONE); + chAlign->signal_pressed().connect (sigc::mem_fun(*this, &BatchQueuePanel::arrangementButtonPressed)); + chAlign->set_tooltip_text (M("FILEBROWSER_ARRANGEMENTHINT")); + bottomBox->pack_end (*Gtk::manage (new Gtk::VSeparator), Gtk::PACK_SHRINK, 4); + if (options.fbArrangement==1) + chAlign->set_image (*vAlignIcon); + else + chAlign->set_image (*hAlignIcon); + arrangementButtonPressed (); + + // thumbnail zoom + Gtk::HBox* zoomBox = Gtk::manage (new Gtk::HBox ()); + zoomBox->pack_start (*Gtk::manage (new Gtk::VSeparator), Gtk::PACK_SHRINK, 4); + Gtk::Label* zoomLabel = Gtk::manage (new Gtk::Label (Glib::ustring("")+M("FILEBROWSER_THUMBSIZE")+":")); + zoomLabel->set_use_markup (true); + zoomBox->pack_start (*zoomLabel, Gtk::PACK_SHRINK, 4); + zoomInButton = Gtk::manage (new Gtk::Button ()); + zoomInButton->set_image (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-zoom-in"), Gtk::ICON_SIZE_SMALL_TOOLBAR))); + zoomInButton->signal_pressed().connect (sigc::mem_fun(*batchQueue, &BatchQueue::zoomIn)); + zoomInButton->set_relief (Gtk::RELIEF_NONE); + zoomInButton->set_tooltip_text (M("FILEBROWSER_ZOOMINHINT")); + zoomBox->pack_end (*zoomInButton, Gtk::PACK_SHRINK); + zoomOutButton = Gtk::manage (new Gtk::Button ()); + zoomOutButton->set_image (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-zoom-out"), Gtk::ICON_SIZE_SMALL_TOOLBAR))); + zoomOutButton->signal_pressed().connect (sigc::mem_fun(*batchQueue, &BatchQueue::zoomOut)); + zoomOutButton->set_relief (Gtk::RELIEF_NONE); + zoomOutButton->set_tooltip_text (M("FILEBROWSER_ZOOMOUTHINT")); + zoomBox->pack_end (*zoomOutButton, Gtk::PACK_SHRINK); + bottomBox->pack_end (*zoomBox, Gtk::PACK_SHRINK); + + + batchQueue->setBatchQueueListener (this); + + show_all (); +} + +void BatchQueuePanel::arrangementButtonPressed () { + + if (chAlign->get_image()==hAlignIcon) { + chAlign->set_image (*vAlignIcon); + batchQueue->setArrangement (BatchQueue::TB_Vertical); + } + else { + chAlign->set_image (*hAlignIcon); + batchQueue->setArrangement (BatchQueue::TB_Horizontal); + } +} + +void BatchQueuePanel::queueSizeChanged (int qsize) { + + // TODO: write it somewhere +} + +void BatchQueuePanel::imageProcessingReady (Glib::ustring fname) { + + parent->imageDeveloped (fname); +} + +void BatchQueuePanel::startBatchProc () { + + stopConnection.block (true); + startConnection.block (true); + stop->set_active (false); + start->set_active (true); + stopConnection.block (false); + startConnection.block (false); + + if (batchQueue->hasJobs()) { + fdir->set_sensitive (false); + fformat->set_sensitive (false); + saveOptions(); + batchQueue->startProcessing (); + } + else + stopBatchProc (); +} + +void BatchQueuePanel::stopBatchProc () { + + stopConnection.block (true); + startConnection.block (true); + stop->set_active (true); + start->set_active (false); + stopConnection.block (false); + startConnection.block (false); +} + +void BatchQueuePanel::addBatchQueueJob (BatchQueueEntry* bqe, bool head) { + + batchQueue->addEntry (bqe, head); + + if (stop->get_active () && autoStart->get_active ()) + startBatchProc (); +} + +void BatchQueuePanel::queueEmpty () { + + stopBatchProc (); + fdir->set_sensitive (true); + fformat->set_sensitive (true); +} + +bool BatchQueuePanel::canStartNext () { + + if (start->get_active ()) + return true; + else { + fdir->set_sensitive (true); + fformat->set_sensitive (true); + return false; + } +} + +void BatchQueuePanel::saveOptions () { + + options.saveFormat = saveFormatPanel->getFormat (); + options.savePathTemplate = outdirTemplate->get_text(); + options.savePathFolder = outdirFolder->get_filename(); + options.saveUsePathTemplate = useTemplate->get_active(); + options.procQueueEnabled = autoStart->get_active (); +} + +void BatchQueuePanel::formatChanged () { + + saveOptions (); +} diff --git a/rtgui/batchqueuepanel.h b/rtgui/batchqueuepanel.h new file mode 100644 index 000000000..fa7436a70 --- /dev/null +++ b/rtgui/batchqueuepanel.h @@ -0,0 +1,78 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _BATCHQUEUEPANEL_ +#define _BATCHQUEUEPANEL_ + +#include +#include +#include + +class RTWindow; +class BatchQueuePanel : public Gtk::VBox, + public BatchQueueListener, + public FormatChangeListener { + + Gtk::Button* zoomInButton; + Gtk::Button* zoomOutButton; + Gtk::ToggleButton* start; + Gtk::ToggleButton* stop; + Gtk::CheckButton* autoStart; + sigc::connection startConnection; + sigc::connection stopConnection; + + Gtk::Entry* outdirTemplate; + Gtk::FileChooserButton* outdirFolder; + Gtk::RadioButton* useTemplate; + Gtk::RadioButton* useFolder; + SaveFormatPanel* saveFormatPanel; + Gtk::Frame *fdir, *fformat; + + Gtk::Image* hAlignIcon; + Gtk::Image* vAlignIcon; + Gtk::Button* chAlign; + + RTWindow* parent; + BatchQueue* batchQueue; + Gtk::HBox* bottomBox; + Gtk::HBox* topBox; + + public: + + BatchQueuePanel (); + + void setParent (RTWindow* p) { parent = p; } + void arrangementButtonPressed (); + + void addBatchQueueJob (BatchQueueEntry* bqe, bool head=false); + + // batchqueuelistener interface + void queueSizeChanged (int qsize); + void imageProcessingReady (Glib::ustring fname); + void queueEmpty (); + bool canStartNext (); + + void startBatchProc (); + void stopBatchProc (); + + void saveOptions (); + void formatChanged (); +}; + +#endif + diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc new file mode 100644 index 000000000..c65c37099 --- /dev/null +++ b/rtgui/batchtoolpanelcoord.cc @@ -0,0 +1,299 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include +#include + +using namespace rtengine::procparams; + +BatchToolPanelCoordinator::BatchToolPanelCoordinator (FilePanel* parent) : ToolPanelCoordinator(), parent(parent) { + + // remove exif panel and iptc panel + std::vector::iterator epi = std::find (toolPanels.begin(), toolPanels.end(), exifpanel); + if (epi!=toolPanels.end()) + toolPanels.erase (epi); + std::vector::iterator ipi = std::find (toolPanels.begin(), toolPanels.end(), iptcpanel); + if (ipi!=toolPanels.end()) + toolPanels.erase (ipi); + toolPanelNotebook->remove_page (*metadataPanel); + + for (int i=0; isetBatchMode (true); +} + +void BatchToolPanelCoordinator::selectionChanged (const std::vector& selected) { + + if (selected!=this->selected) { + closeSession (); + this->selected = selected; + selFileNames.clear (); + for (int i=0; igetFileName ()); + initSession (); + } +} + +void BatchToolPanelCoordinator::closeSession (bool save) { + + pparamsEdited.set (false); + + for (int i=0; iremoveThumbnailListener (this); + + if (somethingChanged && save) { + + // read new values from the gui + for (int i=0; iwrite (&pparams, &pparamsEdited); + + // combine with initial parameters and set + ProcParams newParams; + for (int i=0; isetProcParams (newParams, BATCHEDITOR, true); + } + } + for (int i=0; iclearParamChanges (); +} + +void BatchToolPanelCoordinator::initSession () { + + somethingChanged = false; + + initialPP.resize (selected.size()); + for (int i=0; igetProcParams (); + selected[i]->applyAutoExp (initialPP[i]); + selected[i]->addThumbnailListener (this); + } + + pparamsEdited.initFrom (initialPP); + +/* curve->setAdjusterBehavior (false, false, false, false); + whitebalance->setAdjusterBehavior (false, false); + vignetting->setAdjusterBehavior (false); + rotate->setAdjusterBehavior (false); + distortion->setAdjusterBehavior (false); + cacorrection->setAdjusterBehavior (false, false); + colorshift->setAdjusterBehavior (false, false); + colorboost->setAdjusterBehavior (false); + lumadenoise->setAdjusterBehavior (false); + sharpening->setAdjusterBehavior (false); + shadowshighlights->setAdjusterBehavior (false, false, false); +*/ + crop->setDimensions (100000, 100000); + +/* if (selected.size()>0) { + pparams = selected[0]->getProcParams (); + for (int i=0; isetDefaults (&pparams, &pparamsEdited); + toolPanels[i]->read (&pparams, &pparamsEdited); + } + for (int i=0; iprocParamsChanged (&pparams, rtengine::EvPhotoLoaded, "batch processing", &pparamsEdited); + } +*/ + + if (selected.size()>0) { + + pparams = selected[0]->getProcParams (); + coarse->initBatchBehavior (); + + curve->setAdjusterBehavior (options.baBehav[ADDSET_TC_EXPCOMP], options.baBehav[ADDSET_TC_BRIGHTNESS], options.baBehav[ADDSET_TC_BLACKLEVEL], options.baBehav[ADDSET_TC_CONTRAST]); + lcurve->setAdjusterBehavior (options.baBehav[ADDSET_LC_BRIGHTNESS], options.baBehav[ADDSET_LC_CONTRAST]); + whitebalance->setAdjusterBehavior (options.baBehav[ADDSET_WB_TEMPERATURE], options.baBehav[ADDSET_WB_GREEN]); + vignetting->setAdjusterBehavior (options.baBehav[ADDSET_VIGN_AMOUNT]); + rotate->setAdjusterBehavior (options.baBehav[ADDSET_ROTATE_DEGREE]); + distortion->setAdjusterBehavior (options.baBehav[ADDSET_DIST_AMOUNT]); + cacorrection->setAdjusterBehavior (options.baBehav[ADDSET_CA_RED], options.baBehav[ADDSET_CA_BLUE]); + colorshift->setAdjusterBehavior (options.baBehav[ADDSET_CS_BLUEYELLOW], options.baBehav[ADDSET_CS_GREENMAGENTA]); + colorboost->setAdjusterBehavior (options.baBehav[ADDSET_CBOOST_AMOUNT]); + lumadenoise->setAdjusterBehavior (options.baBehav[ADDSET_LD_EDGETOLERANCE]); + sharpening->setAdjusterBehavior (options.baBehav[ADDSET_SHARP_AMOUNT]); + shadowshighlights->setAdjusterBehavior (options.baBehav[ADDSET_SH_HIGHLIGHTS], options.baBehav[ADDSET_SH_SHADOWS], options.baBehav[ADDSET_SH_LOCALCONTRAST]); + + if (options.baBehav[ADDSET_TC_EXPCOMP]) pparams.toneCurve.expcomp = 0; + if (options.baBehav[ADDSET_TC_BRIGHTNESS]) pparams.toneCurve.brightness = 0; + if (options.baBehav[ADDSET_TC_BLACKLEVEL]) pparams.toneCurve.black = 0; + if (options.baBehav[ADDSET_TC_CONTRAST]) pparams.toneCurve.contrast = 0; + + if (options.baBehav[ADDSET_SH_HIGHLIGHTS]) pparams.sh.highlights = 0; + if (options.baBehav[ADDSET_SH_SHADOWS]) pparams.sh.shadows = 0; + if (options.baBehav[ADDSET_SH_LOCALCONTRAST]) pparams.sh.localcontrast = 0; + + if (options.baBehav[ADDSET_LC_BRIGHTNESS]) pparams.lumaCurve.brightness = 0; + if (options.baBehav[ADDSET_LC_CONTRAST]) pparams.lumaCurve.contrast = 0; + + if (options.baBehav[ADDSET_SHARP_AMOUNT]) pparams.sharpening.amount = 0; + if (options.baBehav[ADDSET_LD_EDGETOLERANCE]) pparams.lumaDenoise.edgetolerance = 0; + + if (options.baBehav[ADDSET_WB_TEMPERATURE]) pparams.wb.temperature = 0; + if (options.baBehav[ADDSET_WB_GREEN]) pparams.wb.green = 0; + + if (options.baBehav[ADDSET_CBOOST_AMOUNT]) pparams.colorBoost.amount = 0; + + if (options.baBehav[ADDSET_CS_BLUEYELLOW]) pparams.colorShift.a = 0; + if (options.baBehav[ADDSET_CS_GREENMAGENTA]) pparams.colorShift.b = 0; + + if (options.baBehav[ADDSET_ROTATE_DEGREE]) pparams.rotate.degree = 0; + if (options.baBehav[ADDSET_DIST_AMOUNT]) pparams.distortion.amount = 0; + if (options.baBehav[ADDSET_CA_RED]) pparams.cacorrection.red = 0; + if (options.baBehav[ADDSET_CA_BLUE]) pparams.cacorrection.blue = 0; + if (options.baBehav[ADDSET_VIGN_AMOUNT]) pparams.vignetting.amount = 0; + + for (int i=0; isetDefaults (&pparams, &pparamsEdited); + toolPanels[i]->read (&pparams, &pparamsEdited); + } + for (int i=0; iprocParamsChanged (&pparams, rtengine::EvPhotoLoaded, M("BATCH_PROCESSING"), &pparamsEdited); + } +} + +void BatchToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr) { + + if (selected.size()==0) + return; + + somethingChanged = true; + + pparamsEdited.set (false); + // read new values from the gui + for (int i=0; iwrite (&pparams, &pparamsEdited); + + if (event==rtengine::EvAutoExp || event==rtengine::EvClip) + for (int i=0; iapplyAutoExp (initialPP[i]); + } + + // combine with initial parameters and set + ProcParams newParams; + for (int i=0; isetProcParams (newParams, BATCHEDITOR, false); + } + + for (int i=0; iprocParamsChanged (&pparams, event, descr, &pparamsEdited); +} + +void BatchToolPanelCoordinator::getAutoWB (double& temp, double& green) { + + if (selected.size()>0) + selected[0]->getAutoWB (temp, green); +} + +void BatchToolPanelCoordinator::getCamWB (double& temp, double& green) { + + if (selected.size()>0) + selected[0]->getCamWB (temp, green); +} + +void BatchToolPanelCoordinator::optionsChanged () { + + closeSession (); + initSession (); +} + +void BatchToolPanelCoordinator::procParamsChanged (Thumbnail* thm, int whoChangedIt) { + + if (whoChangedIt!=BATCHEDITOR) { + closeSession (false); + initSession (); + } +} + +void BatchToolPanelCoordinator::profileChange (const ProcParams *nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited) { + + pparams = *nparams; + if (paramsEdited) + pparamsEdited = *paramsEdited; + + for (int i=0; iread (&pparams, &pparamsEdited); + + somethingChanged = true; + + // read new values from the gui + for (int i=0; iwrite (&pparams, &pparamsEdited); + + // combine with initial parameters and set + ProcParams newParams; + for (int i=0; isetProcParams (newParams, BATCHEDITOR, false); + } + + for (int i=0; iprocParamsChanged (&pparams, event, descr, &pparamsEdited); +} + +void BatchToolPanelCoordinator::cropSelectionReady () { + + toolBar->setTool (TMHand); +} + +CropGUIListener* BatchToolPanelCoordinator::startCropEditing (Thumbnail* thm) { + + if (thm) { + int w, h; + thm->getFinalSize (thm->getProcParams (), w, h); + crop->setDimensions (w, h); + } + return crop; +} + +void BatchToolPanelCoordinator::rotateSelectionReady (double rotate_deg, Thumbnail* thm) { + + toolBar->setTool (TMHand); + if (rotate_deg!=0.0) + rotate->straighten (rotate_deg); +} + +void BatchToolPanelCoordinator::spotWBselected (int x, int y, Thumbnail* thm) { + +// toolBar->setTool (TOOL_HAND); + if (x>0 && y>0 && thm) { + for (int i=0; igetSpotWB (x, y, whitebalance->getSize(), temp, green); + double otemp = initialPP[i].wb.temperature; + double ogreen = initialPP[i].wb.green; + if (options.baBehav[12]) + temp = temp - otemp; + if (options.baBehav[13]) + green = green - ogreen; + whitebalance->setWB (temp, green); + } + } +} + diff --git a/rtgui/batchtoolpanelcoord.h b/rtgui/batchtoolpanelcoord.h new file mode 100644 index 000000000..b743275d7 --- /dev/null +++ b/rtgui/batchtoolpanelcoord.h @@ -0,0 +1,76 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef __BATCHTOOLPANELCCORD__ +#define __BATCHTOOLPANELCCORD__ + +#include +#include +#include +#include +#include +#include + +class FilePanel; +class BatchToolPanelCoordinator : + public ToolPanelCoordinator, + public FileSelectionChangeListener, + public ThumbnailListener +{ + protected: + rtengine::procparams::ProcParams pparams; + ParamsEdited pparamsEdited; + std::vector selected; + std::vector selFileNames; + std::vector initialPP; + bool somethingChanged; + FilePanel* parent; + + void closeSession (bool save=true); + void initSession (); + + public: + + BatchToolPanelCoordinator (FilePanel* parent); + + // FileSelectionChangeListener interface + void selectionChanged (const std::vector& selected); + + // toolpanellistener interface + void panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr); + + // profilechangelistener interface + void profileChange (const rtengine::procparams::ProcParams* nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited=NULL); + + // wbprovider interface + void getAutoWB (double& temp, double& green); + void getCamWB (double& temp, double& green); + + // thumbnaillistener interface + void procParamsChanged (Thumbnail* thm, int whoChangedIt); + + // imageareatoollistener interface + void spotWBselected (int x, int y, Thumbnail* thm=NULL); + void cropSelectionReady (); + void rotateSelectionReady (double rotate_deg, Thumbnail* thm=NULL); + CropGUIListener* startCropEditing (Thumbnail* thm=NULL); + + void optionsChanged (); +}; + +#endif diff --git a/rtgui/bqentryupdater.cc b/rtgui/bqentryupdater.cc new file mode 100644 index 000000000..e4b9b720e --- /dev/null +++ b/rtgui/bqentryupdater.cc @@ -0,0 +1,137 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +BatchQueueEntryUpdater batchQueueEntryUpdater; + +BatchQueueEntryUpdater::BatchQueueEntryUpdater () + : tostop(false), stopped(true), qMutex(NULL) { +} + +void BatchQueueEntryUpdater::add (guint8* oimg, int ow, int oh, int newh, BQEntryUpdateListener* listener) { + + if (!qMutex) + qMutex = new Glib::Mutex (); + + qMutex->lock (); + // look up if an older version is in the queue + std::list::iterator i; + for (i=jqueue.begin(); i!=jqueue.end(); i++) + if (i->oimg==oimg && i->listener==listener) { + i->ow = ow; + i->oh = oh; + i->newh = newh; + i->listener = listener; + break; + } + // not found, create and append new job + if (i==jqueue.end ()) { + Job j; + j.oimg = oimg; + j.ow = ow; + j.oh = oh; + j.newh = newh; + j.listener = listener; + jqueue.push_back (j); + } + qMutex->unlock (); +} + +void BatchQueueEntryUpdater::process () { + + if (stopped) + #undef THREAD_PRIORITY_NORMAL + thread = Glib::Thread::create(sigc::mem_fun(*this, &BatchQueueEntryUpdater::process_), (unsigned long int)0, true, true, Glib::THREAD_PRIORITY_NORMAL); +} + +void BatchQueueEntryUpdater::process_ () { + + stopped = false; + tostop = false; + +// TODO: process visible jobs first + while (!tostop && !jqueue.empty ()) { + qMutex->lock (); + Job current = jqueue.front (); + jqueue.pop_front (); + qMutex->unlock (); + if (current.listener) { + int neww = current.newh * current.ow / current.oh; + guint8* img = new guint8 [current.newh*neww*3]; + thumbInterp (current.oimg, current.ow, current.oh, img, neww, current.newh); + current.listener->updateImage (img, neww, current.newh); + } + } + stopped = true; +} + +void BatchQueueEntryUpdater::stop () { + + if (stopped) { + tostop = true; + return; } + + gdk_threads_leave(); + tostop = true; + Glib::Thread::self()->yield(); + if (!stopped) + thread->join (); + gdk_threads_enter(); +} + +void BatchQueueEntryUpdater::removeJobs () { + + if (!qMutex) + return; + + qMutex->lock (); + while (!jqueue.empty()) + jqueue.pop_front (); + qMutex->unlock (); +} + +void BatchQueueEntryUpdater::removeJobs (BQEntryUpdateListener* listener) { + + if (!qMutex) + return; + + qMutex->lock (); + bool ready = false; + while (!ready) { + ready = true; + std::list::iterator i; + for (i=jqueue.begin(); i!=jqueue.end(); i++) + if (i->listener == listener) { + jqueue.erase (i); + ready = false; + break; + } + } + qMutex->unlock (); +} + +void BatchQueueEntryUpdater::terminate () { + + stop (); + removeJobs (); +} + + diff --git a/rtgui/bqentryupdater.h b/rtgui/bqentryupdater.h new file mode 100644 index 000000000..630180640 --- /dev/null +++ b/rtgui/bqentryupdater.h @@ -0,0 +1,62 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _BQENTRYUPDATER_ +#define _BQENTRYUPDATER_ + +#include +#include +#include + +class BQEntryUpdateListener { + + public: + virtual void updateImage (guint8* img, int w, int h) {} +}; + +class BatchQueueEntryUpdater { + + struct Job { + guint8* oimg; + int ow, oh, newh; + BQEntryUpdateListener* listener; + }; + + protected: + bool tostop; + bool stopped; + std::list jqueue; + Glib::Thread* thread; + Glib::Mutex* qMutex; + + public: + BatchQueueEntryUpdater (); + + void add (guint8* oimg, int ow, int oh, int newh, BQEntryUpdateListener* listener); + void process (); + void stop (); + void removeJobs (); + void removeJobs (BQEntryUpdateListener* listener); + void terminate (); + + void process_ (); +}; + +extern BatchQueueEntryUpdater batchQueueEntryUpdater; + +#endif diff --git a/rtgui/browserfilter.cc b/rtgui/browserfilter.cc new file mode 100644 index 000000000..3d44f113c --- /dev/null +++ b/rtgui/browserfilter.cc @@ -0,0 +1,26 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include + +BrowserFilter::BrowserFilter () : exifFilterEnabled (false) { + + showTrash = true; + for (int i=0; i<6; i++) + showRanked[i] = true; +} diff --git a/rtgui/browserfilter.h b/rtgui/browserfilter.h new file mode 100644 index 000000000..bfbb7039f --- /dev/null +++ b/rtgui/browserfilter.h @@ -0,0 +1,37 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _BROWSERFILTER_ +#define _BROWSERFILTER_ + +#include + +class BrowserFilter { + + public: + bool showRanked[6]; + bool showTrash; + bool showNotTrash; + + bool exifFilterEnabled; + ExifFilterSettings exifFilter; + + BrowserFilter (); +}; + +#endif diff --git a/rtgui/cacheimagedata.cc b/rtgui/cacheimagedata.cc new file mode 100644 index 000000000..29dc40867 --- /dev/null +++ b/rtgui/cacheimagedata.cc @@ -0,0 +1,139 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include + +CacheImageData::CacheImageData () + : md5(""), supported(false), format(FT_Invalid), rank(0), inTrash(false), recentlySaved(false), + timeValid(false), exifValid(false) { +} + +int CacheImageData::load (const Glib::ustring& fname) { + + rtengine::SafeKeyFile keyFile; + + try { + if (!keyFile.load_from_file (fname)) + return 1; + + if (keyFile.has_group ("General")) { + if (keyFile.has_key ("General", "MD5")) md5 = keyFile.get_string ("General", "MD5"); + if (keyFile.has_key ("General", "Version")) version = keyFile.get_integer ("General", "Version"); + if (keyFile.has_key ("General", "Supported")) supported = keyFile.get_boolean ("General", "Supported"); + if (keyFile.has_key ("General", "Format")) format = (ThFileType)keyFile.get_integer ("General", "Format"); + if (keyFile.has_key ("General", "Rank")) rank = keyFile.get_integer ("General", "Rank"); + if (keyFile.has_key ("General", "InTrash")) inTrash = keyFile.get_boolean ("General", "InTrash"); + if (keyFile.has_key ("General", "RecentlySaved")) recentlySaved = keyFile.get_boolean ("General", "RecentlySaved"); + } + + timeValid = keyFile.has_group ("DateTime"); + + if (timeValid) { + if (keyFile.has_key ("DateTime", "Year")) year = keyFile.get_integer ("DateTime", "Year"); + if (keyFile.has_key ("DateTime", "Month")) month = keyFile.get_integer ("DateTime", "Month"); + if (keyFile.has_key ("DateTime", "Day")) day = keyFile.get_integer ("DateTime", "Day"); + if (keyFile.has_key ("DateTime", "Hour")) hour = keyFile.get_integer ("DateTime", "Hour"); + if (keyFile.has_key ("DateTime", "Min")) min = keyFile.get_integer ("DateTime", "Min"); + if (keyFile.has_key ("DateTime", "Sec")) sec = keyFile.get_integer ("DateTime", "Sec"); + if (keyFile.has_key ("DateTime", "MSec")) msec = keyFile.get_integer ("DateTime", "MSec"); + } + + exifValid = false; + + if (keyFile.has_group ("ExifInfo")) { + exifValid = true; + if (keyFile.has_key ("ExifInfo", "Valid")) exifValid = keyFile.get_boolean ("ExifInfo", "Valid"); + + if (exifValid) { + if (keyFile.has_key ("ExifInfo", "FNumber")) fnumber = keyFile.get_double ("ExifInfo", "FNumber"); + if (keyFile.has_key ("ExifInfo", "Shutter")) shutter = keyFile.get_double ("ExifInfo", "Shutter"); + if (keyFile.has_key ("ExifInfo", "FocalLen")) focalLen = keyFile.get_double ("ExifInfo", "FocalLen"); + if (keyFile.has_key ("ExifInfo", "ISO")) iso = keyFile.get_integer ("ExifInfo", "ISO"); + } + if (keyFile.has_key ("ExifInfo", "Lens")) lens = keyFile.get_string ("ExifInfo", "Lens"); + if (keyFile.has_key ("ExifInfo", "Camera")) camera = keyFile.get_string ("ExifInfo", "Camera"); + } + + if (format==FT_Raw && keyFile.has_group ("ExtraRawInfo")) { + if (keyFile.has_key ("ExtraRawInfo", "ThumbImageType")) thumbImgType = keyFile.get_integer ("ExtraRawInfo", "ThumbImageType"); + if (keyFile.has_key ("ExtraRawInfo", "ThumbImageOffset")) thumbOffset = keyFile.get_integer ("ExtraRawInfo", "ThumbImageOffset"); + } + else { + rotate = 0; + thumbImgType = 0; + } + return 0; + } + catch (Glib::Error) { + return 1; + } +} + +int CacheImageData::save (const Glib::ustring& fname) { + + rtengine::SafeKeyFile keyFile; + + try { + keyFile.load_from_file (fname); + } catch (...) {} + + keyFile.set_string ("General", "MD5", md5); + keyFile.set_integer ("General", "Version", options.version); + keyFile.set_boolean ("General", "Supported", supported); + keyFile.set_integer ("General", "Format", format); + keyFile.set_integer ("General", "Rank", rank); + keyFile.set_boolean ("General", "InTrash", inTrash); + keyFile.set_boolean ("General", "RecentlySaved", recentlySaved); + + if (timeValid) { + keyFile.set_integer ("DateTime", "Year", year); + keyFile.set_integer ("DateTime", "Month", month); + keyFile.set_integer ("DateTime", "Day", day); + keyFile.set_integer ("DateTime", "Hour", hour); + keyFile.set_integer ("DateTime", "Min", min); + keyFile.set_integer ("DateTime", "Sec", sec); + keyFile.set_integer ("DateTime", "MSec", msec); + } + + keyFile.set_boolean ("ExifInfo", "Valid", exifValid); + if (exifValid) { + keyFile.set_double ("ExifInfo", "FNumber", fnumber); + keyFile.set_double ("ExifInfo", "Shutter", shutter); + keyFile.set_double ("ExifInfo", "FocalLen", focalLen); + keyFile.set_integer ("ExifInfo", "ISO", iso); + } + keyFile.set_string ("ExifInfo", "Lens", lens); + keyFile.set_string ("ExifInfo", "Camera", camera); + + if (format==FT_Raw) { + keyFile.set_integer ("ExtraRawInfo", "ThumbImageType", thumbImgType); + keyFile.set_integer ("ExtraRawInfo", "ThumbImageOffset", thumbOffset); + } + + FILE *f = g_fopen (fname.c_str(), "wt"); + if (!f) + return 1; + else { + fprintf (f, "%s", keyFile.to_data().c_str()); + fclose (f); + return 0; + } } + diff --git a/rtgui/cacheimagedata.h b/rtgui/cacheimagedata.h new file mode 100644 index 000000000..2ac4b42bf --- /dev/null +++ b/rtgui/cacheimagedata.h @@ -0,0 +1,67 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _CACHEIMAGEDATA_ +#define _CACHEIMAGEDATA_ + +#include +#include + +class CacheImageData { + + public: + + // basic informations + Glib::ustring md5; + int version; + bool supported; + ThFileType format; + char rank; + bool inTrash; + bool recentlySaved; + + // time/date info + bool timeValid; + short year; + char month; + char day; + char hour; + char min; + char sec; + char msec; + + // exif info + bool exifValid; + double fnumber; + double shutter; + double focalLen; + unsigned iso; + Glib::ustring lens; + Glib::ustring camera; + + // additional info on raw images + int rotate; + int thumbImgType; + int thumbOffset; + + CacheImageData (); + + int load (const Glib::ustring& fname); + int save (const Glib::ustring& fname); +}; +#endif diff --git a/rtgui/cachemanager.cc b/rtgui/cachemanager.cc new file mode 100644 index 000000000..fde9442d8 --- /dev/null +++ b/rtgui/cachemanager.cc @@ -0,0 +1,253 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include + +CacheManager cacheMgr; + +void CacheManager::init () { + + openEntries.clear (); + baseDir = options.cacheBaseDir; + + if (!Glib::file_test (baseDir, Glib::FILE_TEST_IS_DIR)) + g_mkdir_with_parents (baseDir.c_str(), 511); + if (!Glib::file_test (Glib::build_filename (baseDir, "profiles"), Glib::FILE_TEST_IS_DIR)) + g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "profiles")).c_str(), 511); + if (!Glib::file_test (Glib::build_filename (baseDir, "images"), Glib::FILE_TEST_IS_DIR)) + g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "images")).c_str(), 511); + if (!Glib::file_test (Glib::build_filename (baseDir, "aehistograms"), Glib::FILE_TEST_IS_DIR)) + g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "aehistograms")).c_str(), 511); + if (!Glib::file_test (Glib::build_filename (baseDir, "embprofiles"), Glib::FILE_TEST_IS_DIR)) + g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "embprofiles")).c_str(), 511); + if (!Glib::file_test (Glib::build_filename (baseDir, "data"), Glib::FILE_TEST_IS_DIR)) + g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "data")).c_str(), 511); +} + +Thumbnail* CacheManager::getEntry (const Glib::ustring& fname) { + + Thumbnail* res = NULL; + + std::map::iterator r = openEntries.find (fname); + // if it is open, return it + if (r!=openEntries.end()) { + r->second->increaseRef (); + return r->second; + } + + // compute the md5 + std::string md5 = getMD5 (fname); + if (md5=="") + return NULL; + + // build path name + Glib::ustring cfname = getCacheFileName ("data", fname, md5) + ".txt"; + + // let's see if we have it in the cache + if (Glib::file_test (cfname, Glib::FILE_TEST_EXISTS)) { + CacheImageData* cfs = new CacheImageData (); + int e = cfs->load (cfname); + if (!e && cfs->supported==true) + res = new Thumbnail (this, fname, cfs); + if (res && !res->isSupported ()) { + delete res; + res = NULL; + } + delete cfs; + } + // if not, create a new one + if (!res) { + res = new Thumbnail (this, fname, md5); + if (!res->isSupported ()) { + delete res; + res = NULL; + } + } + + if (res) + openEntries[fname] = res; + return res; +} + + +void CacheManager::deleteEntry (const Glib::ustring& fname) { + + // check if it is opened + std::map::iterator r = openEntries.find (fname); + // if it is open, dont delete it + if (r!=openEntries.end()) { + std::string md5 = r->second->getMD5 (); + r->second->decreaseRef (); + // if in the editor, the thumbnail still exists. If not, delete it: + r = openEntries.find (fname); + if (r==openEntries.end() && md5!="") { + ::g_remove ((getCacheFileName ("data", fname, md5) + ".txt").c_str()); + ::g_remove ((getCacheFileName ("profiles", fname, md5) + ".pp2").c_str()); + ::g_remove ((getCacheFileName ("images", fname, md5) + ".cust").c_str()); + ::g_remove ((getCacheFileName ("images", fname, md5) + ".jpg").c_str()); + ::g_remove ((getCacheFileName ("aehistograms", fname, md5)).c_str()); + ::g_remove ((getCacheFileName ("embprofiles", fname, md5) + ".icc").c_str()); + } + } + else { + std::string md5 = getMD5 (fname); + if (md5!="") { + ::g_remove ((getCacheFileName ("data", fname, md5) + ".txt").c_str()); + ::g_remove ((getCacheFileName ("profiles", fname, md5) + ".pp2").c_str()); + ::g_remove ((getCacheFileName ("images", fname, md5) + ".cust").c_str()); + ::g_remove ((getCacheFileName ("images", fname, md5) + ".jpg").c_str()); + ::g_remove ((getCacheFileName ("aehistograms", fname, md5)).c_str()); + ::g_remove ((getCacheFileName ("embprofiles", fname, md5) + ".icc").c_str()); + } + } +} + + +void CacheManager::renameEntry (const std::string& oldfilename, const std::string& oldmd5, const std::string& newfilename) { + + std::string newmd5 = getMD5 (newfilename); + + ::g_rename ((getCacheFileName ("profiles", oldfilename, oldmd5) + ".pp2").c_str(), (getCacheFileName ("profiles", newfilename, newmd5) + ".pp2").c_str()); + ::g_rename ((getCacheFileName ("images", oldfilename, oldmd5) + ".cust").c_str(), (getCacheFileName ("images", newfilename, newmd5) + ".cust").c_str()); + ::g_rename ((getCacheFileName ("images", oldfilename, oldmd5) + ".jpg").c_str(), (getCacheFileName ("images", newfilename, newmd5) + ".jpg").c_str()); + ::g_rename ((getCacheFileName ("aehistograms", oldfilename, oldmd5)).c_str(), (getCacheFileName ("aehistograms", newfilename, newmd5)).c_str()); + ::g_rename ((getCacheFileName ("embprofiles", oldfilename, oldmd5) + ".icc").c_str(), (getCacheFileName ("embprofiles", newfilename, newmd5) + ".icc").c_str()); + ::g_rename ((getCacheFileName ("data", oldfilename, oldmd5) + ".txt").c_str(), (getCacheFileName ("data", newfilename, newmd5) + ".txt").c_str()); + + // check if it is opened + std::map::iterator r = openEntries.find (oldfilename); + // if it is open, update md5 + if (r!=openEntries.end()) { + Thumbnail* t = r->second; + openEntries.erase (r); + t->setFileName (newfilename); + openEntries[newfilename] = t; + t->updateCache (); + t->reSaveThumbnail (); + } +} + +void CacheManager::closeThumbnail (Thumbnail* t) { + + t->updateCache (); + std::map::iterator r = openEntries.find (t->getFileName()); + if (r!=openEntries.end()) + openEntries.erase (r); + delete t; +} + +void CacheManager::closeCache () { + + applyCacheSizeLimitation (); +} + +void CacheManager::clearAll () { + + deleteDir ("images"); + deleteDir ("aehistograms"); + deleteDir ("embprofiles"); + deleteDir ("profiles"); + deleteDir ("data"); + + // re-generate thumbnail images and clear profiles of open thumbnails + std::map::iterator i; + for (i=openEntries.begin(); i!=openEntries.end(); i++) { + i->second->clearProcParams (CACHEMGR); + i->second->generateThumbnailImage (); + i->second->updateCache (); + } +} +void CacheManager::clearThumbImages () { + + deleteDir ("images"); + deleteDir ("aehistograms"); + deleteDir ("embprofiles"); + + // re-generate thumbnail images of open thumbnails + std::map::iterator i; + for (i=openEntries.begin(); i!=openEntries.end(); i++) + i->second->generateThumbnailImage (); +} + +void CacheManager::clearProfiles () { + + deleteDir ("profiles"); + // clear profiles of open thumbnails + std::map::iterator i; + for (i=openEntries.begin(); i!=openEntries.end(); i++) + i->second->clearProcParams (CACHEMGR); +} + +void CacheManager::deleteDir (const Glib::ustring& dirName) { + + try { + Glib::Dir* dir = new Glib::Dir (Glib::build_filename (baseDir, dirName)); + for (Glib::DirIterator i = dir->begin(); i!=dir->end(); ++i) + ::g_remove (Glib::build_filename (Glib::build_filename (baseDir, dirName), *i).c_str()); + delete dir; + } + catch (const Glib::FileError& fe) { + } +} + +std::string CacheManager::getMD5 (const Glib::ustring& fname) { + + Glib::RefPtr file = Gio::File::create_for_path (fname); + if (file) { + Glib::RefPtr info = safe_query_file_info (file); + if (info) + return Glib::Checksum::compute_checksum (Glib::Checksum::CHECKSUM_MD5, Glib::ustring::compose ("%1%2", fname, info->get_size())); + } + return ""; +} + +Glib::ustring CacheManager::getCacheFileName (const Glib::ustring& subdir, const Glib::ustring& fname, const Glib::ustring& md5) { + + Glib::ustring cfn = Glib::build_filename (baseDir, subdir); + Glib::ustring cname = Glib::path_get_basename (fname) + "." + md5; + return Glib::build_filename (cfn, cname); +} + +void CacheManager::applyCacheSizeLimitation () { + + std::vector flist; + Glib::ustring dataDir = Glib::build_filename (baseDir, "data"); + Glib::RefPtr dir = Gio::File::create_for_path (dataDir); + + safe_build_file_list (dir, flist); + + if (flist.size() > options.maxCacheEntries) { + std::sort (flist.begin(), flist.end()); + while (flist.size() > options.maxCacheEntries) { + ::g_remove ((Glib::build_filename (Glib::build_filename (baseDir, "data"), flist.front().fname) + ".txt").c_str()); + ::g_remove ((Glib::build_filename (Glib::build_filename (baseDir, "images"), flist.front().fname) + ".cust").c_str()); + ::g_remove ((Glib::build_filename (Glib::build_filename (baseDir, "images"), flist.front().fname) + ".jpg").c_str()); + ::g_remove ((Glib::build_filename (Glib::build_filename (baseDir, "aehistograms"), flist.front().fname)).c_str()); + ::g_remove ((Glib::build_filename (Glib::build_filename (baseDir, "embprofiles"), flist.front().fname) + ".icc").c_str()); +// ::g_remove ((Glib::build_filename (Glib::build_filename (baseDir, "profiles"), flist.front().fname) + ".pp2").c_str()); + flist.erase (flist.begin()); + } + } +} + diff --git a/rtgui/cachemanager.h b/rtgui/cachemanager.h new file mode 100644 index 000000000..d99d2a5ef --- /dev/null +++ b/rtgui/cachemanager.h @@ -0,0 +1,64 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _CACHEMANAGER_ +#define _CACHEMANAGER_ + +#include +#include +#include +#include +#include + +class Thumbnail; + +class CacheManager { + + std::map openEntries; + Glib::ustring baseDir; + + void deleteDir (const Glib::ustring& dirName); + + public: + CacheManager () {} + + void init (); + Thumbnail* getEntry (const Glib::ustring& fname); + void deleteEntry (const Glib::ustring& fname); + void renameEntry (const std::string& oldfilename, const std::string& oldmd5, const std::string& newfilename); + + void closeThumbnail (Thumbnail* t); + + const Glib::ustring& getBaseDir () { return baseDir; } + void closeCache (); + + static std::string getMD5 (const Glib::ustring& fname); + + void clearAll (); + void clearThumbImages (); + void clearProfiles (); + + void applyCacheSizeLimitation (); + + Glib::ustring getCacheFileName (const Glib::ustring& subdir, const Glib::ustring& fname, const Glib::ustring& md5); +}; + +extern CacheManager cacheMgr; + +#endif + diff --git a/rtgui/cacorrection.cc b/rtgui/cacorrection.cc new file mode 100644 index 000000000..c727a57f5 --- /dev/null +++ b/rtgui/cacorrection.cc @@ -0,0 +1,103 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +CACorrection::CACorrection () : valaAdd(false), valbAdd(false) { + + red = Gtk::manage (new Adjuster (M("TP_CACORRECTION_RED"), -0.005, 0.005, 0.0001, 0)); + red->setAdjusterListener (this); + + blue = Gtk::manage (new Adjuster (M("TP_CACORRECTION_BLUE"), -0.005, 0.005, 0.0001, 0)); + blue->setAdjusterListener (this); + + pack_start (*red); + pack_start (*blue); + + show_all(); +} + +void CACorrection::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + red->setEditedState (pedited->cacorrection.red ? Edited : UnEdited); + blue->setEditedState (pedited->cacorrection.blue ? Edited : UnEdited); + } + + red->setValue (pp->cacorrection.red); + blue->setValue (pp->cacorrection.blue); + + enableListener (); +} + +void CACorrection::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->cacorrection.red = red->getValue (); + pp->cacorrection.blue = blue->getValue (); + + if (pedited) { + pedited->cacorrection.red = red->getEditedState (); + pedited->cacorrection.blue = blue->getEditedState (); + } +} + +void CACorrection::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + red->setDefault (defParams->cacorrection.red); + blue->setDefault (defParams->cacorrection.blue); + + if (pedited) { + red->setDefaultEditedState (pedited->cacorrection.red ? Edited : UnEdited); + blue->setDefaultEditedState (pedited->cacorrection.blue ? Edited : UnEdited); + } + else { + red->setDefaultEditedState (Irrelevant); + blue->setDefaultEditedState (Irrelevant); + } +} + +void CACorrection::adjusterChanged (Adjuster* a, double newval) { + + if (listener) + listener->panelChanged (EvCACorr, Glib::ustring::compose ("%1=%3\n%2=%4", M("TP_CACORRECTION_RED"), M("TP_CACORRECTION_BLUE"), Glib::ustring::format (std::setw(5), std::fixed, std::setprecision(4), red->getValue()), Glib::ustring::format (std::setw(5), std::fixed, std::setprecision(4), blue->getValue()))); +} + +void CACorrection::setAdjusterBehavior (bool baadd, bool bbadd) { + + if (!valaAdd && baadd || valaAdd && !baadd) + red->setLimits (-0.005, 0.005, 0.0001, 0); + + if (!valbAdd && bbadd || valbAdd && !bbadd) + blue->setLimits (-0.005, 0.005, 0.0001, 0); + + valaAdd = baadd; + valbAdd = bbadd; +} + +void CACorrection::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + red->showEditedCB (); + blue->showEditedCB (); +} diff --git a/rtgui/cacorrection.h b/rtgui/cacorrection.h new file mode 100644 index 000000000..d51dd73f0 --- /dev/null +++ b/rtgui/cacorrection.h @@ -0,0 +1,46 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _CACORRECTION_H_ +#define _CACORRECTION_H_ + +#include +#include +#include + +class CACorrection : public Gtk::VBox, public AdjusterListener, public ToolPanel { + + protected: + Adjuster* red; + Adjuster* blue; + bool valaAdd, valbAdd; + + public: + + CACorrection (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void setAdjusterBehavior (bool baadd, bool bbadd); +}; + +#endif diff --git a/rtgui/chmixer.cc b/rtgui/chmixer.cc new file mode 100644 index 000000000..10544f5f2 --- /dev/null +++ b/rtgui/chmixer.cc @@ -0,0 +1,151 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +ChMixer::ChMixer () { + + Gtk::Label* rlabel = Gtk::manage (new Gtk::Label ()); + rlabel->set_markup (Glib::ustring("") + M("TP_CHMIXER_RED") + Glib::ustring(":")); + + red[0] = Gtk::manage (new Adjuster (M("TP_CHMIXER_RED"), -200, 200, 1, 100)); + red[1] = Gtk::manage (new Adjuster (M("TP_CHMIXER_GREEN"), -200, 200, 1, 0)); + red[2] = Gtk::manage (new Adjuster (M("TP_CHMIXER_BLUE"), -200, 200, 1, 0)); + + Gtk::HSeparator* rsep = Gtk::manage (new Gtk::HSeparator ()); + + pack_start (*rlabel); + for (int i=0; i<3; i++) + pack_start (*red[i]); + pack_start (*rsep); + + Gtk::Label* glabel = Gtk::manage (new Gtk::Label ()); + glabel->set_markup (Glib::ustring("") + M("TP_CHMIXER_GREEN") + Glib::ustring(":")); + + green[0] = Gtk::manage (new Adjuster (M("TP_CHMIXER_RED"), -200, 200, 1, 0)); + green[1] = Gtk::manage (new Adjuster (M("TP_CHMIXER_GREEN"), -200, 200, 1, 100)); + green[2] = Gtk::manage (new Adjuster (M("TP_CHMIXER_BLUE"), -200, 200, 1, 0)); + + Gtk::HSeparator* gsep = Gtk::manage (new Gtk::HSeparator ()); + + pack_start (*glabel); + for (int i=0; i<3; i++) + pack_start (*green[i]); + pack_start (*gsep); + + Gtk::Label* blabel = Gtk::manage (new Gtk::Label ()); + blabel->set_markup (Glib::ustring("") + M("TP_CHMIXER_BLUE") + Glib::ustring(":")); + + blue[0] = Gtk::manage (new Adjuster (M("TP_CHMIXER_RED"), -200, 200, 1, 0)); + blue[1] = Gtk::manage (new Adjuster (M("TP_CHMIXER_GREEN"), -200, 200, 1, 0)); + blue[2] = Gtk::manage (new Adjuster (M("TP_CHMIXER_BLUE"), -200, 200, 1, 100)); + + for (int i=0; i<3; i++) { + red[i]->setAdjusterListener (this); + green[i]->setAdjusterListener (this); + blue[i]->setAdjusterListener (this); + } + + pack_start (*blabel); + for (int i=0; i<3; i++) + pack_start (*blue[i]); + + show_all(); +} + +void ChMixer::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) + for (int i=0; i<3; i++) { + red[i]->setEditedState (pedited->chmixer.red[i] ? Edited : UnEdited); + green[i]->setEditedState (pedited->chmixer.green[i] ? Edited : UnEdited); + blue[i]->setEditedState (pedited->chmixer.blue[i] ? Edited : UnEdited); + } + + for (int i=0; i<3; i++) { + red[i]->setValue (pp->chmixer.red[i]); + green[i]->setValue (pp->chmixer.green[i]); + blue[i]->setValue (pp->chmixer.blue[i]); + } + + enableListener (); +} + +void ChMixer::write (ProcParams* pp, ParamsEdited* pedited) { + + for (int i=0; i<3; i++) { + pp->chmixer.red[i] = (int) red[i]->getValue (); + pp->chmixer.green[i] = (int) green[i]->getValue (); + pp->chmixer.blue[i] = (int) blue[i]->getValue (); + } + + if (pedited) + for (int i=0; i<3; i++) { + pedited->chmixer.red[i] = red[i]->getEditedState (); + pedited->chmixer.green[i] = green[i]->getEditedState (); + pedited->chmixer.blue[i] = blue[i]->getEditedState (); + } +} + +void ChMixer::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + for (int i=0; i<3; i++) { + red[i]->setDefault (defParams->chmixer.red[i]); + green[i]->setDefault (defParams->chmixer.green[i]); + blue[i]->setDefault (defParams->chmixer.blue[i]); + } + + if (pedited) + for (int i=0; i<3; i++) { + red[i]->setDefaultEditedState (pedited->chmixer.red[i] ? Edited : UnEdited); + green[i]->setDefaultEditedState (pedited->chmixer.green[i] ? Edited : UnEdited); + blue[i]->setDefaultEditedState (pedited->chmixer.blue[i] ? Edited : UnEdited); + } + else + for (int i=0; i<3; i++) { + red[i]->setDefaultEditedState (Irrelevant); + green[i]->setDefaultEditedState (Irrelevant); + blue[i]->setDefaultEditedState (Irrelevant); + } +} + +void ChMixer::adjusterChanged (Adjuster* a, double newval) { + + if (listener) { + Glib::ustring descr = Glib::ustring::compose ("R=%1,%2,%3\nG=%4,%5,%6\nB=%7,%8,%9", + (int)red[0]->getValue(), (int)red[1]->getValue(), (int)red[2]->getValue(), + (int)green[0]->getValue(), (int)green[1]->getValue(), (int)green[2]->getValue(), + (int)blue[0]->getValue(), (int)blue[1]->getValue(), (int)blue[2]->getValue()); + listener->panelChanged (EvChMixer, descr); + } +} + +void ChMixer::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + for (int i=0; i<3; i++) { + red[i]->showEditedCB (); + green[i]->showEditedCB (); + blue[i]->showEditedCB (); + } +} diff --git a/rtgui/chmixer.h b/rtgui/chmixer.h new file mode 100644 index 000000000..b84ba222f --- /dev/null +++ b/rtgui/chmixer.h @@ -0,0 +1,45 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _CHMIXER_H_ +#define _CHMIXER_H_ + +#include +#include +#include + +class ChMixer : public Gtk::VBox, public AdjusterListener, public ToolPanel { + + protected: + Adjuster *red[3]; + Adjuster *green[3]; + Adjuster *blue[3]; + + public: + + ChMixer (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); +}; + +#endif diff --git a/rtgui/clipboard.cc b/rtgui/clipboard.cc new file mode 100644 index 000000000..48a8822f4 --- /dev/null +++ b/rtgui/clipboard.cc @@ -0,0 +1,21 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include + +Clipboard clipboard; diff --git a/rtgui/clipboard.h b/rtgui/clipboard.h new file mode 100644 index 000000000..76a386c3f --- /dev/null +++ b/rtgui/clipboard.h @@ -0,0 +1,44 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _CLIPBOARD_ +#define _CLIPBOARD_ + +#include +#include + +class Clipboard { + + bool _hasIPTC; + std::vector iptc; + bool _hasProcParams; + rtengine::procparams::ProcParams procParams; + + public: + void setIPTC (const std::vector& iptcc) { iptc = iptcc; _hasIPTC = true;} + const std::vector& getIPTC () { return iptc; } + bool hasIPTC () { return _hasIPTC; } + + void setProcParams (const rtengine::procparams::ProcParams& pparams) { procParams = pparams; _hasProcParams = true; } + const rtengine::procparams::ProcParams& getProcParams () { return procParams; } + bool hasProcParams () { return _hasProcParams; } +}; + +extern Clipboard clipboard; + +#endif diff --git a/rtgui/coarsepanel.cc b/rtgui/coarsepanel.cc new file mode 100644 index 000000000..775ffab05 --- /dev/null +++ b/rtgui/coarsepanel.cc @@ -0,0 +1,148 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include + +extern Glib::ustring argv0; + +using namespace rtengine; +using namespace rtengine::procparams; + +CoarsePanel::CoarsePanel () : ToolPanel () { + + degree = 0; + + Gtk::Image* rotateli = Gtk::manage (new Gtk::Image (argv0+"/images/stock-rotate-270-16.png")); + rotate_left = Gtk::manage (new Gtk::Button ()); + rotate_left->add (*rotateli); + rotate_left->set_relief(Gtk::RELIEF_NONE); + pack_start (*rotate_left); + + Gtk::Image* rotateri = Gtk::manage (new Gtk::Image (argv0+"/images/stock-rotate-90-16.png")); + rotate_right = Gtk::manage (new Gtk::Button ()); + rotate_right->add (*rotateri); + rotate_right->set_relief(Gtk::RELIEF_NONE); + pack_start (*rotate_right); + + Gtk::Image* fliphi = Gtk::manage (new Gtk::Image (argv0+"/images/stock-flip-horizontal-16.png")); + hflip = Gtk::manage (new Gtk::ToggleButton ()); + hflip->add (*fliphi); + hflip->set_relief(Gtk::RELIEF_NONE); + pack_start (*hflip); + + Gtk::Image* flipvi = Gtk::manage (new Gtk::Image (argv0+"/images/stock-flip-vertical-16.png")); + vflip = Gtk::manage (new Gtk::ToggleButton ()); + vflip->add (*flipvi); + vflip->set_relief(Gtk::RELIEF_NONE); + pack_start (*vflip); + + rotate_left->set_tooltip_text (M("TP_COARSETRAF_TOOLTIP_ROTLEFT")); + rotate_right->set_tooltip_text (M("TP_COARSETRAF_TOOLTIP_ROTRIGHT")); + vflip->set_tooltip_text (M("TP_COARSETRAF_TOOLTIP_VFLIP")); + hflip->set_tooltip_text (M("TP_COARSETRAF_TOOLTIP_HFLIP")); + + rotate_left->signal_pressed().connect( sigc::mem_fun(*this, &CoarsePanel::rotateLeft) ); + rotate_right->signal_pressed().connect( sigc::mem_fun(*this, &CoarsePanel::rotateRight) ); + hflip->signal_toggled().connect( sigc::mem_fun(*this, &CoarsePanel::flipHorizontal) ); + vflip->signal_toggled().connect( sigc::mem_fun(*this, &CoarsePanel::flipVertical) ); + + show_all_children (); +} + +void CoarsePanel::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + degree = 0; + hflip->set_active (pedited->coarse.hflip ? pp->coarse.hflip : false); + vflip->set_active (pedited->coarse.vflip ? pp->coarse.vflip : false); + oldhflip = pp->coarse.hflip; + oldvflip = pp->coarse.vflip; + } + else { + degree = pp->coarse.rotate; + hflip->set_active (pp->coarse.hflip); + vflip->set_active (pp->coarse.vflip); + } + enableListener (); +} + +void CoarsePanel::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->coarse.rotate = degree; + + if (pedited) { + pedited->coarse.rotate = degree!=0; + pedited->coarse.hflip = oldhflip != hflip->get_active (); + pedited->coarse.vflip = oldvflip != vflip->get_active (); + pp->coarse.hflip = oldhflip != hflip->get_active (); + pp->coarse.vflip = oldvflip != vflip->get_active (); + } + else { + pp->coarse.hflip = hflip->get_active (); + pp->coarse.vflip = vflip->get_active (); + } +} + +void CoarsePanel::initBatchBehavior () { + + disableListener (); + + degree = 0; + hflip->set_active (false); + vflip->set_active (false); + + enableListener (); +} + +void CoarsePanel::rotateLeft () { + + degree = (degree + 270) % 360; + if (listener) + listener->panelChanged (EvCTRotate, Glib::ustring::format (degree)); +} + +void CoarsePanel::rotateRight () { + + degree = (degree + 90) % 360; + if (listener) + listener->panelChanged (EvCTRotate, Glib::ustring::format (degree)); +} + +void CoarsePanel::flipHorizontal () { + + if (listener) { + if (hflip->get_active ()) + listener->panelChanged (EvCTHFlip, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvCTHFlip, M("GENERAL_DISABLED")); + } +} + +void CoarsePanel::flipVertical () { + + if (listener) { + if (vflip->get_active ()) + listener->panelChanged (EvCTVFlip, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvCTVFlip, M("GENERAL_DISABLED")); + } +} + + diff --git a/rtgui/coarsepanel.h b/rtgui/coarsepanel.h new file mode 100644 index 000000000..0811b151a --- /dev/null +++ b/rtgui/coarsepanel.h @@ -0,0 +1,49 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef __COARSEPANEL__ +#define __COARSEPANEL__ + +#include +#include + +class CoarsePanel : public Gtk::HBox, public ToolPanel { + + protected: + Gtk::Button* rotate_left; + Gtk::Button* rotate_right; + Gtk::ToggleButton* hflip; + Gtk::ToggleButton* vflip; + int degree; + bool oldhflip, oldvflip; + + public: + + CoarsePanel (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void initBatchBehavior (); + + void rotateLeft (); + void rotateRight (); + void flipHorizontal (); + void flipVertical (); +}; + +#endif diff --git a/rtgui/colorboost.cc b/rtgui/colorboost.cc new file mode 100644 index 000000000..6221b675a --- /dev/null +++ b/rtgui/colorboost.cc @@ -0,0 +1,191 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +ColorBoost::ColorBoost () : ToolPanel(), cbAdd(false) { + + colorboost = new Adjuster (M("TP_COLORBOOST_AMOUNT"), -100, 300, 1, 0); + + pack_start (*colorboost); + pack_start (*Gtk::manage (new Gtk::HSeparator())); + + avoidclip = Gtk::manage (new Gtk::CheckButton (M("TP_COLORBOOST_AVOIDCOLORCLIP"))); + + pack_start (*avoidclip); + pack_start (*Gtk::manage (new Gtk::HSeparator())); + + enablelimiter = Gtk::manage (new Gtk::CheckButton (M("TP_COLORBOOST_ENABLESATLIMITER"))); + pack_start (*enablelimiter); + + saturationlimiter = new Adjuster (M("TP_COLORBOOST_SATLIMIT"), 0, 200, 0.1, 100); + saturationlimiter->show (); + saturationlimiter->reference (); + + colorboost->setAdjusterListener (this); + saturationlimiter->setAdjusterListener (this); + acconn = avoidclip->signal_toggled().connect( sigc::mem_fun(*this, &ColorBoost::avoidclip_toggled) ); + elconn = enablelimiter->signal_toggled().connect( sigc::mem_fun(*this, &ColorBoost::enablelimiter_toggled) ); + + show_all_children (); +} + +ColorBoost::~ColorBoost () { + + delete saturationlimiter; +} + +void ColorBoost::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + colorboost->setEditedState (pedited->colorBoost.amount ? Edited : UnEdited); + saturationlimiter->setEditedState (pedited->colorBoost.saturationlimit ? Edited : UnEdited); + avoidclip->set_inconsistent (!pedited->colorBoost.avoidclip); + enablelimiter->set_inconsistent (!pedited->colorBoost.enable_saturationlimiter); + } + + colorboost->setValue (pp->colorBoost.amount); + saturationlimiter->setValue (pp->colorBoost.saturationlimit); + acconn.block (true); + avoidclip->set_active (pp->colorBoost.avoidclip); + acconn.block (false); + elconn.block (true); + enablelimiter->set_active (pp->colorBoost.enable_saturationlimiter); + elconn.block (false); + + removeIfThere (this, saturationlimiter, false); + if (enablelimiter->get_active () || enablelimiter->get_inconsistent()) + pack_start (*saturationlimiter); + + lastACVal = pp->colorBoost.avoidclip; + lastELVal = pp->colorBoost.enable_saturationlimiter; + + enableListener (); +} + +void ColorBoost::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->colorBoost.amount = (int)colorboost->getValue(); + pp->colorBoost.avoidclip = avoidclip->get_active (); + pp->colorBoost.enable_saturationlimiter = enablelimiter->get_active (); + pp->colorBoost.saturationlimit = saturationlimiter->getValue (); + + if (pedited) { + pedited->colorBoost.amount = colorboost->getEditedState (); + pedited->colorBoost.avoidclip = !avoidclip->get_inconsistent(); + pedited->colorBoost.enable_saturationlimiter = !enablelimiter->get_inconsistent(); + pedited->colorBoost.saturationlimit = saturationlimiter->getEditedState (); + } +} + +void ColorBoost::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + colorboost->setDefault (defParams->colorBoost.amount); + saturationlimiter->setDefault (defParams->colorBoost.saturationlimit); + + if (pedited) { + colorboost->setDefaultEditedState (pedited->colorBoost.amount ? Edited : UnEdited); + saturationlimiter->setDefaultEditedState (pedited->colorBoost.saturationlimit ? Edited : UnEdited); + } + else { + colorboost->setDefaultEditedState (Irrelevant); + saturationlimiter->setDefaultEditedState (Irrelevant); + } +} + +void ColorBoost::avoidclip_toggled () { + + if (batchMode) { + if (avoidclip->get_inconsistent()) { + avoidclip->set_inconsistent (false); + acconn.block (true); + avoidclip->set_active (false); + acconn.block (false); + } + else if (lastACVal) + avoidclip->set_inconsistent (true); + + lastACVal = avoidclip->get_active (); + } + + if (listener) { + if (avoidclip->get_active ()) + listener->panelChanged (EvCBAvoidClip, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvCBAvoidClip, M("GENERAL_DISABLED")); + } +} + +void ColorBoost::enablelimiter_toggled () { + + if (batchMode) { + if (enablelimiter->get_inconsistent()) { + enablelimiter->set_inconsistent (false); + elconn.block (true); + enablelimiter->set_active (false); + elconn.block (false); + } + else if (lastELVal) + enablelimiter->set_inconsistent (true); + + lastELVal = enablelimiter->get_active (); + } + + removeIfThere (this, saturationlimiter, false); + if (enablelimiter->get_active () || enablelimiter->get_inconsistent()) + pack_start (*saturationlimiter); + + if (listener) { + if (enablelimiter->get_active ()) + listener->panelChanged (EvCBSatLimiter, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvCBSatLimiter, M("GENERAL_DISABLED")); + } +} + +void ColorBoost::adjusterChanged (Adjuster* a, double newval) { + + if (listener) { + if (a!=saturationlimiter) + listener->panelChanged (EvCBBoost, Glib::ustring::format ((int)a->getValue())); + else + listener->panelChanged (EvCBSatLimit, Glib::ustring::format (std::setw(2), std::fixed, std::setprecision(1), a->getValue())); + } +} + +void ColorBoost::setAdjusterBehavior (bool bcbadd) { + + if (!cbAdd && bcbadd || cbAdd && !bcbadd) + colorboost->setLimits (-100, 100, 1, 0); + + cbAdd = bcbadd; +} + +void ColorBoost::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + colorboost->showEditedCB (); + saturationlimiter->showEditedCB (); +} diff --git a/rtgui/colorboost.h b/rtgui/colorboost.h new file mode 100644 index 000000000..cc581da87 --- /dev/null +++ b/rtgui/colorboost.h @@ -0,0 +1,53 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _COLORBOOST_H_ +#define _COLORBOOST_H_ + +#include +#include +#include + +class ColorBoost : public Gtk::VBox, public AdjusterListener, public ToolPanel { + + protected: + Adjuster* colorboost; + Gtk::CheckButton* avoidclip; + Gtk::CheckButton* enablelimiter; + Adjuster* saturationlimiter; + bool cbAdd; + sigc::connection acconn, elconn; + bool lastACVal, lastELVal; + + public: + + ColorBoost (); + virtual ~ColorBoost (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void avoidclip_toggled (); + void enablelimiter_toggled (); + void setAdjusterBehavior (bool bcbadd); +}; + +#endif diff --git a/rtgui/colordenoise.cc b/rtgui/colordenoise.cc new file mode 100644 index 000000000..b35a4871a --- /dev/null +++ b/rtgui/colordenoise.cc @@ -0,0 +1,120 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +ColorDenoise::ColorDenoise () : ToolPanel() { + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (false); + + amount = Gtk::manage (new Adjuster (M("TP_DETAIL_AMOUNT"), 1, 100, 1, 30)); + + pack_start (*enabled); + pack_start (*Gtk::manage (new Gtk::HSeparator())); + pack_start (*amount); + + enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &ColorDenoise::enabledChanged) ); + amount->setAdjusterListener (this); + + show_all_children (); +} + +void ColorDenoise::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + amount->setEditedState (pedited->colorDenoise.amount ? Edited : UnEdited); + enabled->set_inconsistent (!pedited->colorDenoise.enabled); + } + + enaConn.block (true); + enabled->set_active (pp->colorDenoise.enabled); + enaConn.block (false); + + lastEnabled = pp->colorDenoise.enabled; + + amount->setValue (pp->colorDenoise.amount); + + enableListener (); +} + +void ColorDenoise::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->colorDenoise.amount = amount->getValue (); + pp->colorDenoise.enabled = enabled->get_active(); + + if (pedited) { + pedited->colorDenoise.amount = amount->getEditedState (); + pedited->colorDenoise.enabled = !enabled->get_inconsistent(); + } +} + +void ColorDenoise::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + amount->setDefault (defParams->colorDenoise.amount); + + if (pedited) + amount->setDefaultEditedState (pedited->colorDenoise.amount ? Edited : UnEdited); + else + amount->setDefaultEditedState (Irrelevant); +} + +void ColorDenoise::adjusterChanged (Adjuster* a, double newval) { + + if (listener && enabled->get_active()) { + + listener->panelChanged (EvCDNRadius, Glib::ustring::format (std::setw(2), std::fixed, std::setprecision(1), a->getValue())); + } +} + +void ColorDenoise::enabledChanged () { + + if (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaConn.block (true); + enabled->set_active (false); + enaConn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_active ()) + listener->panelChanged (EvCDNEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvCDNEnabled, M("GENERAL_DISABLED")); + } +} + +void ColorDenoise::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + amount->showEditedCB (); +} diff --git a/rtgui/colordenoise.h b/rtgui/colordenoise.h new file mode 100644 index 000000000..0114f7b6a --- /dev/null +++ b/rtgui/colordenoise.h @@ -0,0 +1,47 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _COLORDENOISE_H_ +#define _COLORDENOISE_H_ + +#include +#include +#include + +class ColorDenoise : public Gtk::VBox, public AdjusterListener, public ToolPanel { + + protected: + Adjuster* amount; + Gtk::CheckButton* enabled; + bool lastEnabled; + sigc::connection enaConn; + + public: + + ColorDenoise (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void enabledChanged (); +}; + +#endif diff --git a/rtgui/colorshift.cc b/rtgui/colorshift.cc new file mode 100644 index 000000000..63732c48c --- /dev/null +++ b/rtgui/colorshift.cc @@ -0,0 +1,108 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +ColorShift::ColorShift () : ToolPanel(), aAdd(false), bAdd(false) { + + ashift = Gtk::manage (new Adjuster (M("TP_COLORSHIFT_GREENMAGENTA"), -25, 25, 0.1, 0)); + pack_start (*ashift); + + bshift = Gtk::manage (new Adjuster (M("TP_COLORSHIFT_BLUEYELLOW"), -25, 25, 0.1, 0)); + pack_start (*bshift); + + ashift->setAdjusterListener (this); + bshift->setAdjusterListener (this); + + show_all (); +} + +void ColorShift::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + ashift->setEditedState (pedited->colorShift.a ? Edited : UnEdited); + bshift->setEditedState (pedited->colorShift.b ? Edited : UnEdited); + } + + ashift->setValue (pp->colorShift.a); + bshift->setValue (pp->colorShift.b); + + enableListener (); +} + +void ColorShift::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->colorShift.a = ashift->getValue (); + pp->colorShift.b = bshift->getValue (); + + if (pedited) { + pedited->colorShift.a = ashift->getEditedState (); + pedited->colorShift.b = bshift->getEditedState (); + } +} + +void ColorShift::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + ashift->setDefault (defParams->colorShift.a); + bshift->setDefault (defParams->colorShift.b); + + if (pedited) { + ashift->setDefaultEditedState (pedited->colorShift.a ? Edited : UnEdited); + bshift->setDefaultEditedState (pedited->colorShift.b ? Edited : UnEdited); + } + else { + ashift->setDefaultEditedState (Irrelevant); + bshift->setDefaultEditedState (Irrelevant); + } +} + +void ColorShift::adjusterChanged (Adjuster* a, double newval) { + + if (!listener) + return; + + if (a==ashift) + listener->panelChanged (EvCShiftA, Glib::ustring::format (std::setw(2), std::fixed, std::setprecision(1), a->getValue())); + else if (a==bshift) + listener->panelChanged (EvCShiftB, Glib::ustring::format (std::setw(2), std::fixed, std::setprecision(1), a->getValue())); +} + +void ColorShift::setAdjusterBehavior (bool baadd, bool bbadd) { + + if (!aAdd && baadd || aAdd && !baadd) + ashift->setLimits (-25, 25, 0.1, 0); + + if (!bAdd && bbadd || bAdd && !bbadd) + bshift->setLimits (-25, 25, 0.1, 0); + + aAdd = baadd; + bAdd = bbadd; +} + +void ColorShift::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + ashift->showEditedCB (); + bshift->showEditedCB (); +} diff --git a/rtgui/colorshift.h b/rtgui/colorshift.h new file mode 100644 index 000000000..0dc3d009d --- /dev/null +++ b/rtgui/colorshift.h @@ -0,0 +1,46 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _COLORSHIFT_H_ +#define _COLORSHIFT_H_ + +#include +#include +#include + +class ColorShift : public Gtk::VBox, public AdjusterListener, public ToolPanel { + + protected: + Adjuster* ashift; + Adjuster* bshift; + bool aAdd, bAdd; + + public: + + ColorShift (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void setAdjusterBehavior (bool baadd, bool bbadd); +}; + +#endif diff --git a/rtgui/config.h.in b/rtgui/config.h.in new file mode 100644 index 000000000..19638a24a --- /dev/null +++ b/rtgui/config.h.in @@ -0,0 +1,25 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2010 Lukas Jirkovsky + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ + +#ifndef __CONFIG_H__ +#define __CONFIG_H__ + +#define DATA_SEARCH_PATH "${DATADIR}" + +#endif diff --git a/rtgui/createicon.cc b/rtgui/createicon.cc new file mode 100644 index 000000000..ac11a61e2 --- /dev/null +++ b/rtgui/createicon.cc @@ -0,0 +1,200 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include + +void png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { + png_size_t check; + + /* fread() returns 0 on error, so it is OK to store this in a png_size_t + * instead of an int, which is what fread() actually returns. + */ + check = (png_size_t)fread(data, (png_size_t)1, length, (FILE *)png_ptr->io_ptr); + + if (check != length) + { + png_error(png_ptr, "Read Error"); + } +} + +void png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { + png_uint_32 check; + + check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr)); + if (check != length) + { + png_error(png_ptr, "Write Error"); + } +} + +void png_flush(png_structp png_ptr) { + FILE *io_ptr; + io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr)); + if (io_ptr != NULL) + fflush(io_ptr); +} + + +unsigned char* loadPNG (char* fname, int& w, int& h) { + + FILE *file = fopen (fname,"rb"); + + unsigned char header[8]; + fread (header, 1, 8, file); + + png_structp png = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0); + png_infop info = png_create_info_struct (png); + png_infop end_info = png_create_info_struct (png); + if (setjmp (png_jmpbuf(png))) { + png_destroy_read_struct (&png, &info, &end_info); + fclose (file); + return NULL; + } + //set up png read + png_set_read_fn (png, file, png_read_data); + png_set_sig_bytes (png,8); + + png_read_info(png,info); + + unsigned long width,height; + int bit_depth,color_type,interlace_type,compression_type,filter_method; + png_get_IHDR(png,info,&width,&height,&bit_depth,&color_type,&interlace_type, + &compression_type, &filter_method); + + //converting to 32bpp format + if (color_type==PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png); + + if (color_type==PNG_COLOR_TYPE_GRAY || color_type==PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png); + + if (png_get_valid(png,info,PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png); + + if (interlace_type!=PNG_INTERLACE_NONE) { + png_destroy_read_struct (&png, &info, &end_info); + fclose (file); + return NULL; + } + + if (color_type & PNG_COLOR_MASK_ALPHA) + png_set_strip_alpha(png); + + //setting gamma + double gamma; + if (png_get_gAMA(png,info,&gamma)) + png_set_gamma(png, 2.0, gamma); + else + png_set_gamma(png,2.0, 0.45455); + + int bps = 8; + + //updating png info struct + png_read_update_info(png,info); + png_get_IHDR(png,info,&width,&height,&bit_depth,&color_type,&interlace_type, + &compression_type, &filter_method); + + if (color_type & PNG_COLOR_MASK_ALPHA) + png_set_strip_alpha(png); + + png_read_update_info(png,info); + png_get_IHDR(png,info,&width,&height,&bit_depth,&color_type,&interlace_type, + &compression_type, &filter_method); + + + unsigned char* data = new unsigned char[width*height*3]; + int rowlen = width*3; + unsigned char *row = new unsigned char [rowlen]; + + for (unsigned int i=0;i + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +using namespace rtengine; +using namespace rtengine::procparams; + +extern Glib::ustring argv0; +extern Options options; + +class RefreshSpinHelper { + + public: + Crop* crop; + bool notify; + RefreshSpinHelper (Crop* _crop, bool _notify) + : crop(_crop), notify(_notify) {} +}; + +Crop::Crop () { + + clistener = NULL; + + maxw = 3000; + maxh = 2000; + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (false); + pack_start(*enabled); + + pack_start(*Gtk::manage (new Gtk::HSeparator())); + + Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ()); + + hb1->pack_start (*Gtk::manage (new Gtk::Label (Glib::ustring(" ") + M("TP_CROP_X") +": "))); + x = Gtk::manage (new Gtk::SpinButton ()); + x->set_size_request (60, -1); + hb1->pack_start (*x); + + hb1->pack_start (*Gtk::manage (new Gtk::Label (Glib::ustring(" ") + M("TP_CROP_Y") + ": "))); + y = Gtk::manage (new Gtk::SpinButton ()); + y->set_size_request (60, -1); + hb1->pack_start (*y); + + pack_start (*hb1, Gtk::PACK_SHRINK, 2); + + Gtk::HBox* hb2 = Gtk::manage (new Gtk::HBox ()); + + hb2->pack_start (*Gtk::manage (new Gtk::Label (M("TP_CROP_W") + ": "))); + w = Gtk::manage (new Gtk::SpinButton ()); + w->set_size_request (60, -1); + hb2->pack_start (*w); + + hb2->pack_start (*Gtk::manage (new Gtk::Label (M("TP_CROP_H") + ": "))); + h = Gtk::manage (new Gtk::SpinButton ()); + h->set_size_request (60, -1); + hb2->pack_start (*h); + + pack_start (*hb2, Gtk::PACK_SHRINK, 4); + + selectCrop = Gtk::manage (new Gtk::Button (M("TP_CROP_SELECTCROP"))); + selectCrop->set_image (*Gtk::manage (new Gtk::Image (argv0+"/images/crop16.png"))); + + pack_start (*selectCrop, Gtk::PACK_SHRINK, 2); + + Gtk::HBox* hb3 = Gtk::manage (new Gtk::HBox ()); + + fixr = Gtk::manage (new Gtk::CheckButton (M("TP_CROP_FIXRATIO"))); + fixr->set_active (1); + + hb3->pack_start (*fixr, Gtk::PACK_SHRINK, 4); + + ratio = Gtk::manage (new Gtk::ComboBoxText ()); + hb3->pack_start (*ratio, Gtk::PACK_SHRINK, 4); + + orientation = Gtk::manage (new Gtk::ComboBoxText ()); + hb3->pack_start (*orientation); + + pack_start (*hb3, Gtk::PACK_SHRINK, 4); + + Gtk::HBox* hb31 = Gtk::manage (new Gtk::HBox ()); + + hb31->pack_start (*Gtk::manage (new Gtk::Label (M("TP_CROP_GUIDETYPE"))), Gtk::PACK_SHRINK, 4); + guide = Gtk::manage (new Gtk::ComboBoxText ()); + hb31->pack_start (*guide); + + pack_start (*hb31, Gtk::PACK_SHRINK, 4); + + dpibox = Gtk::manage (new Gtk::VBox()); + dpibox->pack_start (*Gtk::manage (new Gtk::HSeparator()), Gtk::PACK_SHRINK, 2); + + Gtk::HBox* hb4 = Gtk::manage (new Gtk::HBox ()); + hb4->pack_start (*Gtk::manage (new Gtk::Label (M("TP_CROP_DPI")))); + dpi = Gtk::manage (new Gtk::SpinButton ()); + dpi->set_size_request (60, -1); + hb4->pack_start (*dpi); + + dpibox->pack_start (*hb4, Gtk::PACK_SHRINK, 2); + + sizecm = Gtk::manage (new Gtk::Label (M("GENERAL_NA") + " cm x " + M("GENERAL_NA") + " cm")); + sizein = Gtk::manage (new Gtk::Label (M("GENERAL_NA") + " in x " + M("GENERAL_NA") + " in")); + + dpibox->pack_start (*sizecm, Gtk::PACK_SHRINK, 1); + dpibox->pack_start (*sizein, Gtk::PACK_SHRINK, 1); + + pack_start (*dpibox, Gtk::PACK_SHRINK, 0); + + dpi->set_value (300); + + ratio->append_text ("3:2"); + ratio->append_text ("4:3"); + ratio->append_text ("16:9"); + ratio->append_text ("16:10"); + ratio->append_text ("5:4"); + ratio->append_text ("2:1"); + ratio->append_text ("1:1"); + ratio->append_text ("DIN"); + ratio->set_active (0); + + orientation->append_text (M("GENERAL_LANDSCAPE")); + orientation->append_text (M("GENERAL_PORTRAIT")); + orientation->set_active (0); + + guide->append_text (M("TP_CROP_GTNONE")); + guide->append_text (M("TP_CROP_GTRULETHIRDS")); + guide->append_text (M("TP_CROP_GTDIAGONALS")); + guide->append_text (M("TP_CROP_GTHARMMEANS1")); + guide->append_text (M("TP_CROP_GTHARMMEANS2")); + guide->append_text (M("TP_CROP_GTHARMMEANS3")); + guide->append_text (M("TP_CROP_GTHARMMEANS4")); + guide->set_active (0); + + w->set_range (0, maxw); + h->set_range (0, maxh); + x->set_range (0, maxw); + y->set_range (0, maxh); + + x->set_digits (0); + x->set_increments (1,100); + x->set_value (0); + + y->set_digits (0); + y->set_increments (1,100); + y->set_value (0); + + w->set_digits (0); + w->set_increments (1,100); + w->set_value (200); + + h->set_digits (0); + h->set_increments (1,100); + h->set_value (200); + + dpi->set_digits (0); + dpi->set_increments (1,100); + dpi->set_range (50, 12000); + dpi->set_value (300); + + xconn = x->signal_value_changed().connect ( sigc::mem_fun(*this, &Crop::positionChanged), true); + yconn = y->signal_value_changed().connect ( sigc::mem_fun(*this, &Crop::positionChanged), true); + wconn = w->signal_value_changed().connect ( sigc::mem_fun(*this, &Crop::widthChanged), true); + hconn = h->signal_value_changed().connect ( sigc::mem_fun(*this, &Crop::heightChanged), true); + econn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &Crop::enabledChanged) ); + fconn = fixr->signal_toggled().connect( sigc::mem_fun(*this, &Crop::ratioChanged) ); + rconn = ratio->signal_changed().connect( sigc::mem_fun(*this, &Crop::ratioChanged) ); + oconn = orientation->signal_changed().connect( sigc::mem_fun(*this, &Crop::ratioChanged) ); + gconn = guide->signal_changed().connect( sigc::mem_fun(*this, &Crop::notifyListener) ); + selectCrop->signal_pressed().connect( sigc::mem_fun(*this, &Crop::selectPressed) ); + dpi->signal_value_changed().connect( sigc::mem_fun(*this, &Crop::refreshSize) ); + + nx = ny = nw = nh = 0; + nsx = nsy = nsw = nsh = 0; + lastScale = 1.0; + lastRotationDeg = 0; + show_all (); +} + +void Crop::writeOptions () { + + options.cropDPI = (int)dpi->get_value (); +} + +void Crop::readOptions () { + + disableListener (); + + dpi->set_value (options.cropDPI); + + enableListener (); +} + +void Crop::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + xconn.block (true); + yconn.block (true); + wconn.block (true); + hconn.block (true); + rconn.block (true); + fconn.block (true); + oconn.block (true); + gconn.block (true); + enabled->set_active (pp->crop.enabled); + + // check if the new values are larger than the maximum + double tmp, maxw, maxh; + w->get_range (tmp, maxw); + h->get_range (tmp, maxh); + if (pp->crop.x + pp->crop.w > maxw || pp->crop.y + pp->crop.h > maxh) + setDimensions (pp->crop.x + pp->crop.w, pp->crop.y + pp->crop.h); + + ratio->set_active_text (pp->crop.ratio); + fixr->set_active (pp->crop.fixratio); + + if (pp->crop.orientation == "Landscape") + orientation->set_active (0); + else if (pp->crop.orientation == "Portrait") + orientation->set_active (1); + + if (pp->crop.guide == "None") + guide->set_active (0); + else if (pp->crop.guide == "Rule of thirds") + guide->set_active (1); + else if (pp->crop.guide == "Rule of diagonals") + guide->set_active (2); + else if (pp->crop.guide == "Harmonic means 1") + guide->set_active (3); + else if (pp->crop.guide == "Harmonic means 2") + guide->set_active (4); + else if (pp->crop.guide == "Harmonic means 3") + guide->set_active (5); + else if (pp->crop.guide == "Harmonic means 4") + guide->set_active (6); + + x->set_value (pp->crop.x); + y->set_value (pp->crop.y); + w->set_value (pp->crop.w); + h->set_value (pp->crop.h); + + nx = pp->crop.x; + ny = pp->crop.y; + nw = pp->crop.w; + nh = pp->crop.h; + + if (pp->resize.enabled) + lastScale = pp->resize.scale; + else + lastScale = 1.0; + nsx = nx / lastScale; + nsy = ny / lastScale; + nsw = nw / lastScale; + nsh = nh / lastScale; + lastRotationDeg = pp->coarse.rotate; + + wDirty = false; + hDirty = false; + xDirty = false; + yDirty = false; + + if (pedited) { + wDirty = pedited->crop.w; + hDirty = pedited->crop.h; + xDirty = pedited->crop.x; + yDirty = pedited->crop.y; + if (!pedited->crop.ratio) + ratio->set_active (8); + if (!pedited->crop.orientation) + orientation->set_active (2); + if (!pedited->crop.guide) + guide->set_active (7); + enabled->set_inconsistent (!pedited->crop.enabled); + fixr->set_inconsistent (!pedited->crop.fixratio); + } + + lastEnabled = pp->crop.enabled; + lastAspect = pp->crop.fixratio; + + xconn.block (false); + yconn.block (false); + wconn.block (false); + hconn.block (false); + rconn.block (false); + fconn.block (false); + oconn.block (false); + gconn.block (false); + + enableListener (); +} + +void Crop::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->crop.enabled = enabled->get_active (); + pp->crop.x = nx; + pp->crop.y = ny; + pp->crop.w = nw; + pp->crop.h = nh; + pp->crop.fixratio = fixr->get_active (); + pp->crop.ratio = ratio->get_active_text (); + + if (orientation->get_active_row_number()==0) + pp->crop.orientation = "Landscape"; + else if (orientation->get_active_row_number()==1) + pp->crop.orientation = "Portrait"; + + if (guide->get_active_row_number()==0) + pp->crop.guide = "None"; + else if (guide->get_active_row_number()==1) + pp->crop.guide = "Rule of thirds"; + else if (guide->get_active_row_number()==2) + pp->crop.guide = "Rule of diagonals"; + else if (guide->get_active_row_number()==3) + pp->crop.guide = "Harmonic means 1"; + else if (guide->get_active_row_number()==4) + pp->crop.guide = "Harmonic means 2"; + else if (guide->get_active_row_number()==5) + pp->crop.guide = "Harmonic means 3"; + else if (guide->get_active_row_number()==6) + pp->crop.guide = "Harmonic means 4"; + + if (pedited) { + pedited->crop.enabled = !enabled->get_inconsistent(); + pedited->crop.ratio = ratio->get_active_row_number() != 8; + pedited->crop.orientation = orientation->get_active_row_number() != 2; + pedited->crop.guide = guide->get_active_row_number() != 7; + pedited->crop.fixratio = !fixr->get_inconsistent(); + pedited->crop.w = wDirty; + pedited->crop.h = hDirty; + pedited->crop.x = xDirty; + pedited->crop.y = yDirty; + } + +} + +void Crop::selectPressed () { + + if (clistener) + clistener->cropSelectRequested (); +} + +void Crop::notifyListener () { + + if (listener && enabled->get_active ()) + listener->panelChanged (EvCrop, Glib::ustring::compose ("%1=%2, %3=%4\n%5=%6, %7=%8", M("TP_CROP_X"), nx, M("TP_CROP_Y"), ny, M("TP_CROP_W"), nw, M("TP_CROP_H"), nh)); +} + +void Crop::enabledChanged () { + + if (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + econn.block (true); + enabled->set_active (false); + econn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_active ()) + listener->panelChanged (EvCrop, Glib::ustring::compose ("%1=%2, %3=%4\n%5=%6, %7=%8", M("TP_CROP_X"), nx, M("TP_CROP_Y"), ny, M("TP_CROP_W"), nw, M("TP_CROP_H"), nh)); + else + listener->panelChanged (EvCrop, M("GENERAL_DISABLED")); + } +} + +int notifylistener (void* data) { + + gdk_threads_enter (); + ((Crop*)data)->notifyListener (); + gdk_threads_leave (); + return 0; +} + +int refreshspins (void* data) { + + gdk_threads_enter (); + RefreshSpinHelper* rsh = (RefreshSpinHelper*) data; + rsh->crop->refreshSpins (rsh->notify); + delete rsh; + gdk_threads_leave (); + return 0; +} + +void Crop::resizeScaleChanged (double rsc) { + + lastScale = rsc; + + nx = (int)round (nsx * rsc); + ny = (int)round (nsy * rsc); + nw = (int)round (nsw * rsc); + nh = (int)round (nsh * rsc); + + if (nx+nw > maxw || ny+nh > maxh) + setDimensions (nx+nw, ny+nh); + + g_idle_add (refreshspins, new RefreshSpinHelper (this, false)); +} + +void Crop::hFlipCrop () { + + nx = maxw - nx - nw; + nsx = nx / lastScale; + g_idle_add (refreshspins, new RefreshSpinHelper (this, false)); +} + +void Crop::vFlipCrop () { + + ny = maxh - ny - nh; + nsy = ny / lastScale; + g_idle_add (refreshspins, new RefreshSpinHelper (this, false)); +} + +void Crop::rotateCrop (int deg) { + + int tmp; + switch ((360+deg-lastRotationDeg)%360) { + case 90: + tmp = nx; + nx = maxh - ny - nh; + ny = tmp; + tmp = nw; + nw = nh; + nh = tmp; + break; + case 270: + tmp = ny; + ny = maxw - nx - nw; + nx = tmp; + tmp = nw; + nw = nh; + nh = tmp; + break; + case 180: + nx = maxw - nx - nw; + ny = maxh - ny - nh; + break; + } + nsx = nx / lastScale; + nsy = ny / lastScale; + nsw = nw / lastScale; + nsh = nh / lastScale; + + lastRotationDeg = deg; + g_idle_add (refreshspins, new RefreshSpinHelper (this, false)); +} + +void Crop::positionChanged () { + + xDirty = true; + yDirty = true; + + int X = (int)x->get_value (); + int Y = (int)y->get_value (); + int W = nw; + int H = nh; + cropMoved (X, Y, W, H); + g_idle_add (notifylistener, this); +} + +void Crop::widthChanged () { + + wDirty = true; + + int X = nx; + int Y = ny; + int W = (int)w->get_value (); + int H = nh; + cropWidth2Resized (X, Y, W, H); + g_idle_add (notifylistener, this); +} + +void Crop::heightChanged () { + + hDirty = true; + + int X = nx; + int Y = ny; + int W = nw; + int H = (int)h->get_value (); + cropHeight2Resized (X, Y, W, H); + g_idle_add (notifylistener, this); +} + + +void Crop::ratioChanged () { + + if (batchMode && lastAspect != fixr->get_active ()) { + if (fixr->get_inconsistent()) { + fixr->set_inconsistent (false); + fconn.block (true); + fixr->set_active (false); + fconn.block (false); + } + else if (lastAspect) + fixr->set_inconsistent (true); + + lastAspect = fixr->get_active (); + } + + + if (fixr->get_active() && !fixr->get_inconsistent()) { + +// int W = w->get_value (); +// int H = h->get_value (); + int W = nw; + int H = nh; + int X = nx; + int Y = ny; + if (W>=H) + cropWidth2Resized (X, Y, W, H); + else + cropHeight2Resized (X, Y, W, H); + + g_idle_add (refreshspins, new RefreshSpinHelper (this, true)); + } +} + +void Crop::refreshSize () { + + if (!batchMode) { + + std::ostringstream ostrin; + ostrin.precision (3); + // ostrin << h->get_value()/dpi->get_value() << " in x " << w->get_value()/dpi->get_value() << " in";; + ostrin << nh/dpi->get_value() << " in x " << nw/dpi->get_value() << " in";; + + sizein->set_text (ostrin.str ()); + + std::ostringstream ostrcm; + ostrcm.precision (3); + // ostrcm << h->get_value()/dpi->get_value()*2.54 << " cm x " << w->get_value()/dpi->get_value()*2.54 << " cm";; + ostrcm << nh/dpi->get_value()*2.54 << " cm x " << nw/dpi->get_value()*2.54 << " cm";; + + sizecm->set_text (ostrcm.str ()); + } +} + +void Crop::setDimensions (int mw, int mh) { + + maxw = mw; + maxh = mh; + + xconn.block (true); + yconn.block (true); + wconn.block (true); + hconn.block (true); + + w->set_range (0, maxw); + h->set_range (0, maxh); + x->set_range (0, maxw); + y->set_range (0, maxh); + + xconn.block (false); + yconn.block (false); + wconn.block (false); + hconn.block (false); + + if (enabled->get_active()==false) { + nx = 0; + ny = 0; + nw = mw; + nh = mh; + + nsx = nx / lastScale; + nsy = ny / lastScale; + nsw = nw / lastScale; + nsh = nh / lastScale; + refreshSpins (); + } + refreshSize (); +} + +struct setdimparams { + Crop* crop; + int x; + int y; +}; + +int setdim (void* data) { + + gdk_threads_enter (); + setdimparams* params = (setdimparams*)data; + params->crop->setDimensions (params->x, params->y); + delete params; + gdk_threads_leave (); + return 0; +} + +void Crop::sizeChanged (int x, int y, int ow, int oh) { + + setdimparams* params = new setdimparams; + params->x = x; + params->y = y; + params->crop = this; + g_idle_add (setdim, params); +} + +bool Crop::refreshSpins (bool notify) { + + xconn.block (true); + yconn.block (true); + wconn.block (true); + hconn.block (true); + + x->set_value (nx); + y->set_value (ny); + w->set_value (nw); + h->set_value (nh); + + xDirty = true; + yDirty = true; + wDirty = true; + hDirty = true; + + xconn.block (false); + yconn.block (false); + wconn.block (false); + hconn.block (false); + + refreshSize (); + if (notify) + notifyListener (); + + return false; +} + +void Crop::cropMoved (int &X, int &Y, int &W, int &H) { + +// W = w->get_value (); +// H = h->get_value (); + W = nw; + H = nh; + + if (X+W>maxw) + X = maxw-W; + if (Y+H>maxh) + Y = maxh-H; + if (X<0) + X = 0; + if (Y<0) + Y = 0; + + nx = X; + ny = Y; + nw = W; + nh = H; + + nsx = nx / lastScale; + nsy = ny / lastScale; + nsw = nw / lastScale; + nsh = nh / lastScale; + + g_idle_add (refreshspins, new RefreshSpinHelper (this, false)); +// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins)); +} + +void Crop::cropWidth1Resized (int &X, int &Y, int &W, int &H) { + + if (W<0) + W = 0; + if (H<0) + H = 0; + + if (X<0) { + W += X; + X = 0; + } + if (fixr->get_active()) { + double r = getRatio(); + int W2max = (int)round(r*(maxh-Y)); + if (W>W2max) { + X += W - W2max; + W = W2max; + } + H = (int)round(W / r); + } + + nx = X; + ny = Y; + nw = W; + nh = H; + + nsx = nx / lastScale; + nsy = ny / lastScale; + nsw = nw / lastScale; + nsh = nh / lastScale; + + g_idle_add (refreshspins, new RefreshSpinHelper (this, false)); +// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins)); +} + +void Crop::cropWidth2Resized (int &X, int &Y, int &W, int &H) { + +// X = x->get_value (); +// Y = y->get_value (); + X = nx; + Y = ny; + + if (W<0) + W = 0; + if (H<0) + H = 0; + + if (W>maxw-X) + W = maxw-X; + + if (fixr->get_active()) { + double r = getRatio(); + int W2max = (int)round(r*(maxh-Y)); + if (W>W2max) + W = W2max; + H = (int)round(W / r); + } + + nx = X; + ny = Y; + nw = W; + nh = H; + + nsx = nx / lastScale; + nsy = ny / lastScale; + nsw = nw / lastScale; + nsh = nh / lastScale; + + g_idle_add (refreshspins, new RefreshSpinHelper (this, false)); +// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins)); +} + +void Crop::cropHeight1Resized (int &X, int &Y, int &W, int &H) { + + if (W<0) + W = 0; + if (H<0) + H = 0; + + if (Y<0) { + H += Y; + Y = 0; + } + + if (fixr->get_active()) { + double r = getRatio(); + int H2max = (int)round((maxw-X) / r); + if (H>H2max) { + Y += H - H2max; + H = H2max; + } + W = (int)round(H * r); + } + + nx = X; + ny = Y; + nw = W; + nh = H; + + nsx = nx / lastScale; + nsy = ny / lastScale; + nsw = nw / lastScale; + nsh = nh / lastScale; + + g_idle_add (refreshspins, new RefreshSpinHelper (this, false)); +// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins)); +} + +void Crop::cropHeight2Resized (int &X, int &Y, int &W, int &H) { + +// X = x->get_value (); +// Y = y->get_value (); + X = nx; + Y = ny; + + if (W<0) + W = 0; + if (H<0) + H = 0; + int H1max = maxh-Y; + if (H>H1max) + H = H1max; + if (fixr->get_active()) { + double r = getRatio (); + int H2max = (int)round ((maxw-X) / r); + if (H>H2max) + H = H2max; + W = (int)round(H * r); + } + + nx = X; + ny = Y; + nw = W; + nh = H; + + nsx = nx / lastScale; + nsy = ny / lastScale; + nsw = nw / lastScale; + nsh = nh / lastScale; + + g_idle_add (refreshspins, new RefreshSpinHelper (this, false)); +// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins)); +} + +void Crop::cropInit (int &x, int &y, int &w, int &h) { + + nx = x; + ny = y; + nw = 1; + nh = 1; + + nsx = nx / lastScale; + nsy = ny / lastScale; + nsw = nw / lastScale; + nsh = nh / lastScale; + + w = 1; h = 1; + + econn.block (true); + enabled->set_active (1); + econn.block (false); + g_idle_add (refreshspins, new RefreshSpinHelper (this, false)); +// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins)); +} + +void Crop::cropResized (int &x, int &y, int& x2, int& y2) { + + if (x2<0) + x2 = 0; + if (y2<0) + y2 = 0; + if (x2>=maxw) + x2 = maxw-1; + if (y2>=maxh) + y2 = maxh-1; + + int X, Y; + int W; + if (xmaxw) + W = maxw; + if (H>maxh) + H = maxh; + + if (fixr->get_active()) { + double r = getRatio (); + if (y<=y2) { + int W2max = (int)round ((maxh-Y) * r); + if (W>W2max) + W = W2max; + } + else { + int W2max = (int)round (y * r); + if (W>W2max) + W = W2max; + } + H = (int)round(W / r); + if (xget_active()==false) + return r; + if (ratio->get_active_row_number()==0) + r = 3.0/2.0; + else if (ratio->get_active_row_number()==1) + r = 4.0/3.0; + else if (ratio->get_active_row_number()==2) + r = 16.0/9.0; + else if (ratio->get_active_row_number()==3) + r = 16.0/10.0; + else if (ratio->get_active_row_number()==4) + r = 5.0/4.0; + else if (ratio->get_active_row_number()==5) + r = 2.0/1.0; + else if (ratio->get_active_row_number()==6) + r = 1.0/1.0; + else if (ratio->get_active_row_number()==7) + r = 1.414; + if (orientation->get_active_row_number()==0) + return r; + else + return 1.0 / r; +} + +void Crop::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + + ratio->append_text ("(Unchanged)"); + orientation->append_text ("(Unchanged)"); + guide->append_text ("(Unchanged)"); + removeIfThere (this, dpibox); +} diff --git a/rtgui/crop.h b/rtgui/crop.h new file mode 100644 index 000000000..c607b0e1e --- /dev/null +++ b/rtgui/crop.h @@ -0,0 +1,100 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _CROP_H_ +#define _CROP_H_ + +#include +#include +#include + +class CropPanelListener { + + public: + virtual void cropSelectRequested () {} +}; + + +class Crop : public Gtk::VBox, public CropGUIListener, public ToolPanel, public rtengine::SizeListener { + + protected: + Gtk::CheckButton* enabled; + Gtk::CheckButton* fixr; + Gtk::ComboBoxText* ratio; + Gtk::ComboBoxText* orientation; + Gtk::ComboBoxText* guide; + Gtk::Button* selectCrop; + CropPanelListener* clistener; + int opt; + Gtk::SpinButton* x; + Gtk::SpinButton* y; + Gtk::SpinButton* w; + Gtk::SpinButton* h; + Gtk::SpinButton* dpi; + Gtk::Label* sizecm; + Gtk::Label* sizein; + Gtk::VBox* dpibox; + int maxw, maxh; + int nx, ny, nw, nh; + double nsx, nsy, nsw, nsh, lastScale; + int lastRotationDeg; + sigc::connection xconn, yconn, wconn, hconn, econn, fconn, rconn, oconn, gconn; + bool wDirty, hDirty, xDirty, yDirty, lastEnabled, lastAspect; + + public: + + Crop (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void ratioChanged (); + void refreshSize (); + void selectPressed (); + void setDimensions (int mw, int mh); + void enabledChanged (); + void positionChanged (); + void widthChanged (); + void heightChanged (); + bool refreshSpins (bool notify=false); + void notifyListener (); + void sizeChanged (int w, int h, int ow, int oh); + + void readOptions (); + void writeOptions (); + + void cropMoved (int &x, int &y, int &w, int &h); + void cropWidth1Resized (int &x, int &y, int &w, int &h); + void cropWidth2Resized (int &x, int &y, int &w, int &h); + void cropHeight1Resized (int &x, int &y, int &w, int &h); + void cropHeight2Resized (int &x, int &y, int &w, int &h); + void cropInit (int &x, int &y, int &w, int &h); + void cropResized (int &x, int &y, int& x2, int& y2); + void cropManipReady (); + double getRatio (); + + void setCropPanelListener (CropPanelListener* cl) { clistener = cl; } + + void resizeScaleChanged (double rsc); + void hFlipCrop (); + void vFlipCrop (); + void rotateCrop (int deg); +}; + +#endif diff --git a/rtgui/cropguilistener.h b/rtgui/cropguilistener.h new file mode 100644 index 000000000..75248b9a8 --- /dev/null +++ b/rtgui/cropguilistener.h @@ -0,0 +1,36 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef __CROPGUILISTENER__ +#define __CROPGUILISTENER__ + +class CropGUIListener { + + public: + virtual void cropMoved (int &x, int &y, int &w, int &h) =0; + virtual void cropWidth1Resized (int &x, int &y, int &w, int &h) =0; + virtual void cropWidth2Resized (int &x, int &y, int &w, int &h) =0; + virtual void cropHeight1Resized (int &x, int &y, int &w, int &h) =0; + virtual void cropHeight2Resized (int &x, int &y, int &w, int &h) =0; + virtual void cropInit (int &x, int &y, int &w, int &h) =0; + virtual void cropResized (int &x, int &y, int& x2, int& y2) =0; + virtual void cropManipReady () =0; + virtual double getRatio () =0; +}; + +#endif diff --git a/rtgui/crophandler.cc b/rtgui/crophandler.cc new file mode 100644 index 000000000..9e26c40a6 --- /dev/null +++ b/rtgui/crophandler.cc @@ -0,0 +1,329 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#undef THREAD_PRIORITY_NORMAL + +using namespace rtengine; + +CropHandler::CropHandler () + : crop(NULL), listener(NULL), cropimg(NULL), ipc(NULL), + cx(0), cy(0), cw(0), ch(0), + cropX(0), cropY(0), cropW(0), cropH(0), + zoom(1000), enabled(false) { + + chi = new CropHandlerIdleHelper; + chi->destroyed = false; + chi->pending = 0; + chi->cropHandler = this; +} + +CropHandler::~CropHandler () { + + if (ipc) + ipc->delSizeListener (this); + + setEnabled (false); + if (crop) + crop->destroy (); + cimg.lock (); + if (chi->pending) + chi->destroyed = true; + else + delete chi; + cimg.unlock (); +} + +void CropHandler::newImage (StagedImageProcessor* ipc_) { + + ipc = ipc_; + cx = 0; + cy = 0; + + if (!ipc) + return; + + crop = ipc->createCrop (); + ipc->setSizeListener (this); + crop->setListener (enabled ? this : NULL); + initial = true; +} + +void CropHandler::sizeChanged (int x, int y, int ow, int oh) { // the ipc notifies it to keep track size changes like rotation + + compDim (); + +// this should be put into an idle source!!! +/* if (listener) + listener->cropWindowChanged (); + */ +} + +double CropHandler::getFitZoom () { + + if (ipc) { + double z1 = (double) wh / ipc->getFullHeight (); + double z2 = (double) ww / ipc->getFullWidth (); + return z1=0) + x = centerx; + if (centery>=0) + y = centery; + + zoom = z; + if (zoom>=1000) { + cw = ww * 1000 / zoom; + ch = wh * 1000 / zoom; + } + else { + cw = ww * zoom; + ch = wh * zoom; + } + cx = x - cw / 2; + cy = y - ch / 2; + + compDim (); + if (enabled) + update (); +} + + +void CropHandler::setWSize (int w, int h) { + + ww = w; + wh = h; + if (zoom>=1000) { + cw = ww * 1000 / zoom; + ch = wh * 1000 / zoom; + } + else { + cw = ww * zoom; + ch = wh * zoom; + } + + compDim (); + if (enabled) + update (); +} + +void CropHandler::getWSize (int& w, int &h) { + + w = ww; + h = wh; +} + +void CropHandler::setPosition (int x, int y, bool update_) { + + cx = x; + cy = y; + + compDim (); + if (enabled && update_) + update (); +} + +void CropHandler::getPosition (int& x, int& y) { + + x = cropX; + y = cropY; +} + + +int createpixbufs (void* data) { + + gdk_threads_enter (); + + CropHandlerIdleHelper* chi = (CropHandlerIdleHelper*) data; + if (chi->destroyed) { + if (chi->pending == 1) + delete chi; + else + chi->pending--; + gdk_threads_leave (); + return 0; + } + + CropHandler* ch = chi->cropHandler; + + ch->cimg.lock (); + ch->cropPixbuf.clear (); + + if (!ch->enabled) { + delete [] ch->cropimg; + ch->cropimg = NULL; + ch->cimg.unlock (); + gdk_threads_leave (); + return 0; + } + + if (ch->cropimg) { + if (ch->cix==ch->cropX && ch->ciy==ch->cropY && ch->ciw==ch->cropW && ch->cih==ch->cropH && ch->cis==(ch->zoom>=1000?1:ch->zoom)) { + // calculate final image size + int czoom = ch->zoom<1000 ? 1000 : ch->zoom; + int imw = ch->cropimg_width * czoom / 1000; + int imh = ch->cropimg_height * czoom / 1000; + if (imw>ch->ww) + imw = ch->ww; + if (imh>ch->wh) + imh = ch->wh; + + Glib::RefPtr tmpPixbuf = Gdk::Pixbuf::create_from_data (ch->cropimg, Gdk::COLORSPACE_RGB, false, 8, ch->cropimg_width, ch->cropimg_height, 3*ch->cropimg_width); + ch->cropPixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, imw, imh); + tmpPixbuf->scale (ch->cropPixbuf, 0, 0, imw, imh, 0, 0, czoom/1000.0, czoom/1000.0, Gdk::INTERP_NEAREST); + tmpPixbuf.clear (); + } + delete [] ch->cropimg; + ch->cropimg = NULL; + } + ch->cimg.unlock (); + if (ch->listener) { + ch->listener->cropImageUpdated (); + if (ch->initial) { + ch->listener->initialImageArrived (); + ch->initial = false; + } + } + + chi->pending--; + + gdk_threads_leave (); + return 0; +} + +void CropHandler::setDetailedCrop (IImage8* im, rtengine::procparams::CropParams cp, int ax, int ay, int aw, int ah, int askip) { + + if (!enabled) + return; + + cimg.lock (); + + cropParams = cp; + + cropPixbuf.clear (); + if (cropimg) + delete [] cropimg; + cropimg = NULL; + + if (ax==cropX && ay==cropY && aw==cropW && ah==cropH && askip==(zoom>=1000?1:zoom)) { + cropimg_width = im->getWidth (); + cropimg_height = im->getHeight (); + cropimg = new unsigned char [3*cropimg_width*cropimg_height]; + memcpy (cropimg, im->getData(), 3*cropimg_width*cropimg_height); + cix = ax; + ciy = ay; + ciw = aw; + cih = ah; + cis = askip; + chi->pending++; + g_idle_add (createpixbufs, chi); + } + cimg.unlock (); + } + +bool CropHandler::getWindow (int& cwx, int& cwy, int& cww, int& cwh, int& cskip) { + + cwx = cropX; + cwy = cropY; + cww = cropW; + cwh = cropH; + + // hack: if called before first size allocation the size will be 0 + if (cww<10) + cww = 10; + if (cwh<32) + cwh = 32; + + cskip = zoom>=1000 ? 1 : zoom; + + return true; +} + +void CropHandler::update () { + + if (crop) { +// crop->setWindow (cropX, cropY, cropW, cropH, zoom>=1000 ? 1 : zoom); --> we use the "getWindow" hook instead of setting the size before + crop->setListener (this); + cropPixbuf.clear (); + Glib::Thread::create(sigc::mem_fun(*crop, &DetailedCrop::fullUpdate), 0, false, true, Glib::THREAD_PRIORITY_NORMAL); + } +} + +void CropHandler::setEnabled (bool e) { + + enabled = e; + if (!enabled) { + if (crop) + crop->setListener (NULL); + cimg.lock (); + delete [] cropimg; + cropimg = NULL; + cropPixbuf.clear (); + cimg.unlock (); + } + else + update (); +} + +bool CropHandler::getEnabled () { + + return enabled; +} + +void CropHandler::getSize (int& w, int& h) { + + w = cropW; + h = cropH; +} + +void CropHandler::compDim () { + + cropX = cx; + cropY = cy; + cropW = cw; + cropH = ch; + + cutRectToImgBounds (cropX, cropY, cropW, cropH); +} + +void CropHandler::cutRectToImgBounds (int& x, int& y, int& w, int& h) { + + if (ipc) { + if (w > ipc->getFullWidth()) + w = ipc->getFullWidth(); + if (h > ipc->getFullHeight()) + h = ipc->getFullHeight(); + if (x < 0) + x = 0; + if (y < 0) + y = 0; + if (x + w >= ipc->getFullWidth()) + x = ipc->getFullWidth() - w; + if (y + h >= ipc->getFullHeight()) + y = ipc->getFullHeight() - h; + } +} diff --git a/rtgui/crophandler.h b/rtgui/crophandler.h new file mode 100644 index 000000000..990316342 --- /dev/null +++ b/rtgui/crophandler.h @@ -0,0 +1,94 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef __CROPHANDLER__ +#define __CROPHANDLER__ + +#include +#include + +class CropHandlerListener { + + public: + virtual void cropImageUpdated () {} + virtual void cropWindowChanged () {} + virtual void initialImageArrived () {} +}; + +class CropHandler; +struct CropHandlerIdleHelper { + CropHandler* cropHandler; + bool destroyed; + int pending; +}; + +class CropHandler : public rtengine::DetailedCropListener, public rtengine::SizeListener { + + friend int createpixbufs (void* data); + + protected: + int zoom; + int ww, wh; // size of the crop view on the screen + int cx, cy, cw, ch; // position and size of the requested crop + int cropX, cropY, cropW, cropH; // position and size of the crop corresponding to cropPixbuf + bool enabled; + unsigned char* cropimg; + int cropimg_width, cropimg_height, cix, ciy, ciw, cih, cis; + bool initial; + + rtengine::StagedImageProcessor* ipc; + rtengine::DetailedCrop* crop; + + CropHandlerListener* listener; + CropHandlerIdleHelper* chi; + + void update (); + void compDim (); + public: + + rtengine::procparams::CropParams cropParams; + Glib::RefPtr cropPixbuf; + Glib::Mutex cimg; + + CropHandler (); + ~CropHandler (); + + void setCropHandlerListener (CropHandlerListener* l) { listener = l; } + + void newImage (rtengine::StagedImageProcessor* ipc_); + void setZoom (int z, int centerx=-1, int centery=-1); + double getFitZoom (); + void setWSize (int w, int h); + void getWSize (int& w, int &h); + void setPosition (int x, int y, bool update=true); + void getPosition (int& x, int& y); + void getSize (int& w, int& h); + + void setEnabled (bool e); + bool getEnabled (); + + // DetailedCropListener interface + void setDetailedCrop (rtengine::IImage8* im, rtengine::procparams::CropParams cp, int cx, int cy, int cw, int ch, int skip); + bool getWindow (int& cwx, int& cwy, int& cww, int& cwh, int& cskip); + // SizeListener interface + void sizeChanged (int w, int h, int ow, int oh); + + void cutRectToImgBounds (int& x, int& y, int& w, int& h); +}; + +#endif diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc new file mode 100644 index 000000000..37f90003b --- /dev/null +++ b/rtgui/cropwindow.cc @@ -0,0 +1,1030 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include + +struct ZoomStep { + Glib::ustring label; + double zoom; + int czoom; +}; + +ZoomStep zoomSteps[] = {"10%", 0.1, 10, + "12.5%", 0.125, 8, + "16.6%", 1.0/6.0, 6, + "20%", 0.2, 5, + "25%", 0.25, 4, + "33%", 1.0/3.0, 3, + "50%", 0.5, 2, + "100%", 1.0, 1000, + "200%", 2.0, 2000, + "300%", 3.0, 3000, + "400%", 4.0, 4000, + "500%", 5.0, 5000, + "600%", 6.0, 6000, + "700%", 7.0, 7000, + "800%", 8.0, 8000}; +#define MAXZOOMSTEPS 14 +#define ZOOM11INDEX 7 + +CropWindow::CropWindow (ImageArea* parent, rtengine::StagedImageProcessor* ipc_) + : iarea(parent), cropgl(NULL), xpos(30), ypos(30), imgX(0), imgY(0), imgW(1), imgH(1), + titleHeight(30), sideBorderWidth(3), upperBorderWidth(1), lowerBorderWidth(3), sepWidth(2), + cropZoom(ZOOM11INDEX), deleted(false), onResizeArea(false), fitZoom(false), + fitZoomEnabled(true), decorated(true), backColor(0), observedCropWin(NULL), + pmlistener(NULL) { + + Glib::RefPtr context = parent->get_pango_context () ; + Pango::FontDescription fontd = context->get_font_description (); + fontd.set_weight (Pango::WEIGHT_BOLD); + fontd.set_size(8*Pango::SCALE); + context->set_font_description (fontd); + cropLabel = "100%"; + Glib::RefPtr cllayout = parent->create_pango_layout("1000%"); + + int iw, ih; + cllayout->get_pixel_size (iw, ih); + + titleHeight = ih; + + resizeSurface = Cairo::ImageSurface::create_from_png (argv0+"/images/resize.png"); + bZoomIn = new LWButton (Cairo::ImageSurface::create_from_png (argv0+"/images/gtk-zoom-in.png"), 0, NULL, LWButton::Left, LWButton::Center, "Zoom In"); + bZoomOut = new LWButton (Cairo::ImageSurface::create_from_png (argv0+"/images/gtk-zoom-out.png"), 1, NULL, LWButton::Left, LWButton::Center, "Zoom Out"); + bZoom100 = new LWButton (Cairo::ImageSurface::create_from_png (argv0+"/images/gtk-zoom-100.png"), 2, NULL, LWButton::Left, LWButton::Center, "Zoom 100/%"); + bZoomFit = new LWButton (Cairo::ImageSurface::create_from_png (argv0+"/images/gtk-zoom-fit.png"), 3, NULL, LWButton::Left, LWButton::Center, "Zoom Fit"); + bClose = new LWButton (Cairo::ImageSurface::create_from_png (argv0+"/images/gtk-close.png"), 4, NULL, LWButton::Right, LWButton::Center, "Close"); + + buttonSet.add (bZoomIn); + buttonSet.add (bZoomOut); + buttonSet.add (bZoom100); + buttonSet.add (bClose); + + buttonSet.setColors (Gdk::Color("black"), Gdk::Color("white")); + buttonSet.setButtonListener (this); + + int bsw, bsh; + buttonSet.getMinimalDimensions (bsw, bsh); + + if (bsh>titleHeight) + titleHeight = bsh; + + minWidth = bsw + iw + 2*sideBorderWidth; + + setSize (300, 300); + cropHandler.newImage (ipc_); + cropHandler.setPosition (0,0); + cropHandler.setEnabled (true); + cropHandler.setCropHandlerListener (this); + state = SNormal; +} + +CropWindow::~CropWindow () { + +} + +void CropWindow::setPosition (int x, int y) { + + if (y<0) + y = 0; + xpos = x; + ypos = y; + if (decorated) + buttonSet.arrangeButtons (xpos + sideBorderWidth, ypos + upperBorderWidth, width - 2*sideBorderWidth, titleHeight); +} + +void CropWindow::getPosition (int& x, int& y) { + + x = xpos; + y = ypos; +} + +void CropWindow::getCropPosition (int& x, int& y) { + + int cropX, cropY; + cropHandler.getPosition (cropX, cropY); + if (state!=SCropImgMove) { + x = cropX; + y = cropY; + } + else { + x = cropX + action_x; + y = cropY + action_y; + } +} + +void CropWindow::getCropRectangle (int& x, int& y, int& w, int& h) { + + int cropX, cropY, cropW, cropH; + cropHandler.getPosition (cropX, cropY); + cropHandler.getSize (cropW, cropH); + if (state!=SCropImgMove) { + x = cropX; + y = cropY; + } + else { + x = cropX + action_x; + y = cropY + action_y; + } + if (state!=SCropWinResize) { + w = cropW; + h = cropH; + } + else { + w = imgAreaW; + h = imgAreaH; + } + cropHandler.cutRectToImgBounds (x, y, w, h); +} + +void CropWindow::setCropPosition (int x, int y) { + + cropHandler.setPosition (x, y); + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->cropPositionChanged (this); +} + +void CropWindow::setSize (int w, int h, bool norefresh) { + + width = w; + height = h; + + fitZoom = false; + + if (widthredraw (); +} + +void CropWindow::getSize (int& w, int& h) { + + w = width; + h = height; +} + +void CropWindow::getCropSize (int& w, int& h) { + + w = imgAreaW; + h = imgAreaH; +} + +bool CropWindow::isInside (int x, int y) { + + return x>=xpos && x=ypos && ygrabFocus (this); + if (button==1 && type==GDK_2BUTTON_PRESS && onArea (CropImage, x, y) && (state==SNormal || state==SCropImgMove)) { + if (fitZoomEnabled) { + if (fitZoom) { + translateCoord (x, y, action_x, action_y); + changeZoom (ZOOM11INDEX, true, action_x, action_y); + fitZoom = false; + } + else + zoomFit (); + } + else + zoom11 (); + state = SNormal; + } + else if (button==1 && type==GDK_2BUTTON_PRESS && onArea (CropBorder, x, y)) { + backColor = (backColor+1) % 3; + } + else if (button==1 && type==GDK_BUTTON_PRESS && state==SNormal && onArea (CropToolBar, x, y)) { + if (!decorated || !buttonSet.pressNotify (x, y)) { + state = SCropWinMove; + action_x = x; + action_y = y; + press_x = xpos; + press_y = ypos; + } + } + else if (button==1 && type==GDK_BUTTON_PRESS && state==SNormal && onArea (CropResize, x, y)) { + state = SCropWinResize; + action_x = x; + action_y = y; + press_x = width; + press_y = height; + } + else if (button==1 && type==GDK_BUTTON_PRESS && state==SNormal && onArea (CropImage, x, y)) { + if (onArea (CropTop, x, y)) { + state = SResizeH1; + press_y = y; + action_y = cropHandler.cropParams.y; + } + else if (onArea (CropBottom, x, y)) { + state = SResizeH2; + press_y = y; + action_y = cropHandler.cropParams.h; + } + else if (onArea (CropLeft, x, y)) { + state = SResizeW1; + press_x = x; + action_x = cropHandler.cropParams.x; + } + else if (onArea (CropRight, x, y)) { + state = SResizeW2; + press_x = x; + action_x = cropHandler.cropParams.w; + } + else if (onArea (CropObserved, x, y)) { + state = SObservedMove; + press_x = x; + press_y = y; + } + else if ((bstate & GDK_SHIFT_MASK) && onArea (CropInside, x, y)) { + state = SCropMove; + press_x = x; + press_y = y; + action_x = cropHandler.cropParams.x; + action_y = cropHandler.cropParams.y; + } + else if (iarea->getToolMode () == TMHand) { + state = SCropImgMove; + action_x = 0; + action_y = 0; + press_x = x; + press_y = y; + } + else if (iarea->getToolMode () == TMStraighten) { + state = SRotateSelecting; + press_x = x; + press_y = y; + action_x = x; + action_y = y; + rot_deg = 0; + } + else if (iarea->getToolMode () == TMSpotWB) { + translateCoord (x, y, action_x, action_y); + iarea->spotWBSelected (action_x, action_y); + } + else if (iarea->getToolMode () == TMCropSelect && cropgl) { + state = SCropSelecting; + translateCoord (x, y, press_x, press_y); + cropHandler.cropParams.x = press_x; + cropHandler.cropParams.y = press_y; + cropHandler.cropParams.w = cropHandler.cropParams.h = 1; + cropgl->cropInit (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + } + } + if (button==3) { + state = SNormal; + iarea->setToolHand (); + } + iarea->redraw (); + updateCursor (x, y); +} + +void CropWindow::buttonRelease (int button, int num, int bstate, int x, int y) { + + if (state==SCropWinResize) { + setSize (press_x + x - action_x, press_y + y - action_y); + state = SNormal; + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->cropWindowSizeChanged (this); + } + else if (state==SCropImgMove) { + int cropX, cropY; + cropHandler.getPosition (cropX, cropY); + cropHandler.setPosition (cropX + action_x, cropY + action_y); + cropHandler.getPosition (cropX, cropY); + state = SNormal; + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->cropPositionChanged (this); + } + else if (state==SRotateSelecting) { + iarea->straightenReady (rot_deg); + iarea->setToolHand (); + } + else if (state==SObservedMove) { + observedCropWin->remoteMoveReady (); + state = SNormal; + } + if (cropgl && (state==SCropSelecting || state==SResizeH1 || state==SResizeH2 || state==SResizeW1 || state==SResizeW2 || state==SCropMove)) { + cropgl->cropManipReady (); + iarea->setToolHand (); + } + + if (decorated) + buttonSet.releaseNotify (x, y); + if (deleted) + return; + + state = SNormal; + iarea->grabFocus (NULL); + iarea->redraw (); + updateCursor (x, y); +} + +void CropWindow::pointerMoved (int x, int y) { + + if (state==SCropWinMove) { + setPosition (press_x + x - action_x, press_y + y - action_y); + iarea->redraw (); + } + else if (state==SCropWinResize) { + setSize (press_x + x - action_x, press_y + y - action_y, true); + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->cropWindowSizeChanged (this); + iarea->redraw (); + } + else if (state==SCropImgMove) { + action_x = (press_x - x) / zoomSteps[cropZoom].zoom; + action_y = (press_y - y) / zoomSteps[cropZoom].zoom; + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->cropPositionChanged (this); + iarea->redraw (); + } + else if (state==SRotateSelecting) { + action_x = x; + action_y = y; + iarea->redraw (); + } + else if (state==SNormal && iarea->getToolMode () == TMSpotWB) { + action_x = x; + action_y = y; + iarea->redraw (); + } + else if (state==SResizeH1 && cropgl) { + int oy = cropHandler.cropParams.y; + cropHandler.cropParams.y = action_y + (y-press_y) / zoomSteps[cropZoom].zoom; + cropHandler.cropParams.h += oy - cropHandler.cropParams.y; + cropgl->cropHeight1Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + iarea->redraw (); + } + else if (state==SResizeH2 && cropgl) { + cropHandler.cropParams.h = action_y + (y-press_y) / zoomSteps[cropZoom].zoom; + cropgl->cropHeight2Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + iarea->redraw (); + } + else if (state==SResizeW1 && cropgl) { + int ox = cropHandler.cropParams.x; + cropHandler.cropParams.x = action_x + (x-press_x) / zoomSteps[cropZoom].zoom; + cropHandler.cropParams.w += ox - cropHandler.cropParams.x; + cropgl->cropWidth1Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + iarea->redraw (); + } + else if (state==SResizeW2 && cropgl) { + cropHandler.cropParams.w = action_x + (x-press_x) / zoomSteps[cropZoom].zoom; + cropgl->cropWidth2Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + iarea->redraw (); + } + else if (state==SCropMove && cropgl) { + cropHandler.cropParams.x = action_x + (x-press_x) / zoomSteps[cropZoom].zoom; + cropHandler.cropParams.y = action_y + (y-press_y) / zoomSteps[cropZoom].zoom; + cropgl->cropMoved (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + iarea->redraw (); + } + else if (state==SCropSelecting && cropgl) { + translateCoord (x, y, action_x, action_y); + int cx1 = press_x, cy1 = press_y; + int cx2 = action_x, cy2 = action_y; + cropgl->cropResized (cx1, cy1, cx2, cy2); + if (cx2 > cx1) { + cropHandler.cropParams.x = cx1; + cropHandler.cropParams.w = cx2 - cx1 + 1; + } + else { + cropHandler.cropParams.x = cx2; + cropHandler.cropParams.w = cx1 - cx2 + 1; + } + if (cy2 > cy1) { + cropHandler.cropParams.y = cy1; + cropHandler.cropParams.h = cy2 - cy1 + 1; + } + else { + cropHandler.cropParams.y = cy2; + cropHandler.cropParams.h = cy1 - cy2 + 1; + } + iarea->redraw (); + } + else if (state==SObservedMove) { + observedCropWin->remoteMove ((x - press_x)/zoomSteps[cropZoom].zoom, (y - press_y)/zoomSteps[cropZoom].zoom); + iarea->redraw (); + } + updateCursor (x, y); + + bool oRA = onArea (CropResize, x, y); + if (oRA!=onResizeArea) { + onResizeArea = oRA; + iarea->redraw (); + } + + if (decorated) + buttonSet.motionNotify (x, y); + + if (pmlistener) { + int mx, my; + translateCoord (x, y, mx, my); + if (!onArea (CropImage, x, y) || !cropHandler.cropPixbuf) + pmlistener->pointerMoved (false, mx, my, -1, -1, -1); + else { + cropHandler.cimg.lock (); + int vx = x - xpos - imgX; + int vy = y - ypos - imgY; + guint8* pix = cropHandler.cropPixbuf->get_pixels() + vy*cropHandler.cropPixbuf->get_rowstride() + vx*3; + if (vx < cropHandler.cropPixbuf->get_width() && vy < cropHandler.cropPixbuf->get_height()) + pmlistener->pointerMoved (true, mx, my, pix[0], pix[1], pix[2]); + cropHandler.cimg.unlock (); + } + } +} + +bool CropWindow::onArea (CursorArea a, int x, int y) { + + int CROPRESIZEBORDER = 6 / zoomSteps[cropZoom].zoom; + int x1, y1, w, h; + switch (a) { + case CropWinButtons: + return decorated && buttonSet.inside (x, y); + case CropToolBar: + return x>xpos && y>ypos && x=xpos+imgX && y>=ypos+imgY && x=xpos+imgAreaX && y>=ypos+imgAreaY && x=xpos+imgX && y>=ypos+imgY && xcropHandler.cropParams.x+CROPRESIZEBORDER && + x1cropHandler.cropParams.y-CROPRESIZEBORDER && + y1cropHandler.cropParams.x+CROPRESIZEBORDER && + x1cropHandler.cropParams.y+cropHandler.cropParams.h-1-CROPRESIZEBORDER && + y1cropHandler.cropParams.y+CROPRESIZEBORDER && + y1cropHandler.cropParams.x-CROPRESIZEBORDER && + x1cropHandler.cropParams.y+CROPRESIZEBORDER && + y1cropHandler.cropParams.x+cropHandler.cropParams.w-1-CROPRESIZEBORDER && + x1cropHandler.cropParams.y && + y1cropHandler.cropParams.x && + x1=xpos+width-16 && y>=ypos+height-16 && xx1-6 && y>y1-6 && xx1+2 && y>y1+2 && xgetToolMode (); + + if (state==SNormal) { + if (onArea (CropWinButtons, x, y)) + cursorManager.setCursor (iarea->get_window(), CSArrow); + else if (onArea (CropToolBar, x, y)) + cursorManager.setCursor (iarea->get_window(), CSMove); + else if (onArea (CropResize, x, y)) + cursorManager.setCursor (iarea->get_window(), CSResizeDiagonal); + else if (tm==TMHand && (onArea (CropTop, x, y) || onArea (CropBottom, x, y))) + cursorManager.setCursor (iarea->get_window(), CSResizeHeight); + else if (tm==TMHand && (onArea (CropLeft, x, y) || onArea (CropRight, x, y))) + cursorManager.setCursor (iarea->get_window(), CSResizeWidth); + else if (onArea (CropImage, x, y)) { + if (tm==TMHand) { + if (onArea (CropObserved, x, y)) + cursorManager.setCursor (iarea->get_window(), CSMove); + else + cursorManager.setCursor (iarea->get_window(), CSOpenHand); + } + else if (tm==TMSpotWB) + cursorManager.setCursor (iarea->get_window(), CSSpotWB); + else if (tm==TMCropSelect) + cursorManager.setCursor (iarea->get_window(), CSCropSelect); + else if (tm==TMStraighten) + cursorManager.setCursor (iarea->get_window(), CSStraighten); + } + else + cursorManager.setCursor (iarea->get_window(), CSArrow); + } + else if (state==SCropSelecting) + cursorManager.setCursor (iarea->get_window(), CSCropSelect); + else if (state==SRotateSelecting) + cursorManager.setCursor (iarea->get_window(), CSStraighten); + else if (state==SCropMove || state==SCropWinMove || state==SObservedMove) + cursorManager.setCursor (iarea->get_window(), CSMove); + else if (state==SHandMove || state==SCropImgMove) + cursorManager.setCursor (iarea->get_window(), CSClosedHand); + else if (state==SResizeW1 || state==SResizeW2) + cursorManager.setCursor (iarea->get_window(), CSResizeWidth); + else if (state==SResizeH1 || state==SResizeH2) + cursorManager.setCursor (iarea->get_window(), CSResizeHeight); + else if (state==SCropWinResize) + cursorManager.setCursor (iarea->get_window(), CSResizeDiagonal); +} + +void CropWindow::expose (Cairo::RefPtr cr) { + + MyTime t1, t2, t3, t4; + + t1.set (); + + if (decorated) + drawDecoration (cr); + + int x = xpos, y = ypos, h = height, w = width; + + // draw border + if (backColor==0) { + Gdk::Color cback = iarea->get_style()->get_bg(Gtk::STATE_NORMAL); + cr->set_source_rgb (cback.get_red_p(), cback.get_green_p(), cback.get_blue_p()); + } + else if (backColor==1) + cr->set_source_rgb (0,0,0); + else if (backColor==2) + cr->set_source_rgb (1,1,1); + + cr->rectangle (x+imgAreaX+0.5, y+imgAreaY+0.5, imgAreaW, imgAreaH); + cr->stroke_preserve (); + cr->fill (); + + cropHandler.cimg.lock (); + // draw image + if (state==SCropImgMove || state==SCropWinResize) { + // draw a rough image + int cropX, cropY; + cropHandler.getPosition (cropX, cropY); + if (state==SCropImgMove) { + cropX += action_x; + cropY += action_y; + } + Glib::RefPtr rough = iarea->getPreviewHandler()->getRoughImage (cropX, cropY, imgAreaW, imgAreaH, zoomSteps[cropZoom].zoom); + if (rough) { + iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), rough, 0, 0, x+imgAreaX+(imgAreaW-rough->get_width())/2, y+imgAreaY+(imgAreaH-rough->get_height())/2, -1, -1, Gdk::RGB_DITHER_NORMAL, 0, 0); +// if (cropHandler.cropParams.enabled) +// drawCrop (cr, x+imgX, y+imgY, imgW, imgH, cropX, cropY, zoomSteps[cropZoom].zoom, cropHandler.cropParams); + } + } + else { + if (cropHandler.cropPixbuf) { + imgW = cropHandler.cropPixbuf->get_width (); + imgH = cropHandler.cropPixbuf->get_height (); + imgX = imgAreaX + (imgAreaW-imgW)/2; + imgY = imgAreaY + (imgAreaH-imgH)/2; +// PERFORMANCE BOTTLENECK STARTS HERE + t3.set (); + bool showcs = iarea->indClippedPanel->showClippedShadows(); + bool showch = iarea->indClippedPanel->showClippedHighlights(); + if (showcs || showch) { + Glib::RefPtr tmp = cropHandler.cropPixbuf->copy (); + guint8* pix = tmp->get_pixels(); + for (int i=0; iget_height(); i++) + for (int j=0; jget_width(); j++) { + guint8* curr = pix + i*tmp->get_rowstride () + j*3; + if (showch && (curr[0]>=options.highlightThreshold || curr[1]>=options.highlightThreshold || curr[2]>=options.highlightThreshold)) + curr[0] = curr[1] = curr[2] = 0; + else if (showcs && (curr[0]<=options.shadowThreshold || curr[1]<=options.shadowThreshold || curr[2]<=options.shadowThreshold)) + curr[0] = curr[1] = curr[2] = 255; + } + iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), tmp, 0, 0, x+imgX, y+imgY, -1, -1, Gdk::RGB_DITHER_NONE, 0, 0); + } + else + iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), cropHandler.cropPixbuf, 0, 0, x+imgX, y+imgY, -1, -1, Gdk::RGB_DITHER_NONE, 0, 0); + t4.set (); +// END OF BOTTLENECK + if (cropHandler.cropParams.enabled) { + int cropX, cropY; + cropHandler.getPosition (cropX, cropY); + drawCrop (cr, x+imgX, y+imgY, imgW, imgH, cropX, cropY, zoomSteps[cropZoom].zoom, cropHandler.cropParams); + } + } + else { + int cropX, cropY; + cropHandler.getPosition (cropX, cropY); + Glib::RefPtr rough = iarea->getPreviewHandler()->getRoughImage (cropX, cropY, imgAreaW, imgAreaH, zoomSteps[cropZoom].zoom); + if (rough) { + iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), rough, 0, 0, x+imgAreaX+(imgAreaW-rough->get_width())/2, y+imgAreaY+(imgAreaH-rough->get_height())/2, -1, -1, Gdk::RGB_DITHER_NORMAL, 0, 0); + if (cropHandler.cropParams.enabled) { + int cropX, cropY; + cropHandler.getPosition (cropX, cropY); + drawCrop (cr, x+imgX, y+imgY, imgW, imgH, cropX, cropY, zoomSteps[cropZoom].zoom, cropHandler.cropParams); + } + } + } + } + + if (observedCropWin) + drawObservedFrame (cr); + + // if cursor stays above resize area, draw the icon + if (decorated && (state==SCropWinResize || onResizeArea)) { + int rw = resizeSurface->get_width (); + int rh = resizeSurface->get_height (); + cr->set_source_rgb (0.5,0.5,0.5); + cr->rectangle (x+w-1.5-rw-1, y+h-1.5-rh-1, rw+1, rh+1); + cr->stroke_preserve (); + cr->fill (); + cr->set_source (resizeSurface, x+w-1.5-rw, y+h-1.5-rh); + cr->paint (); + cr->set_source_rgb (0,0,0); + cr->move_to (x+w-2.5-rw, y+h-1.5); + cr->line_to (x+w-2.5-rw, y+h-2.5-rh); + cr->line_to (x+w-1.5, y+h-2.5-rh); + cr->stroke (); + } + if (state==SRotateSelecting) + drawStraightenGuide (cr); + if (state==SNormal && iarea->getToolMode () == TMSpotWB) + drawSpotWBRectangle (cr); + + t2.set (); + cropHandler.cimg.unlock (); +// printf ("etime --> %d, %d\n", t2.etime (t1), t4.etime (t3)); +} + +void CropWindow::zoomIn () { + + changeZoom (cropZoom+1); + fitZoom = false; +} + +void CropWindow::zoomOut () { + + changeZoom (cropZoom-1); + fitZoom = false; +} + +void CropWindow::zoom11 () { + + changeZoom (ZOOM11INDEX); + fitZoom = false; +} + +double CropWindow::getZoom () { + + return zoomSteps[cropZoom].zoom; +} + +void CropWindow::setZoom (double zoom) { + + int cz = MAXZOOMSTEPS; + if (zoom < zoomSteps[0].zoom) + cz = 0; + else + for (int i=0; i zoom) { + cz = i; + break; + } + changeZoom (cz, false); +} + +void CropWindow::zoomFit () { + + double z = cropHandler.getFitZoom (); + int cz = MAXZOOMSTEPS; + if (z < zoomSteps[0].zoom) + cz = 0; + else + for (int i=0; i z) { + cz = i; + break; + } + changeZoom (cz); + fitZoom = true; +} + +void CropWindow::buttonPressed (LWButton* button, int actionCode, void* actionData) { + + if (button==bZoomIn) // zoom in + zoomIn (); + else if (button==bZoomOut) // zoom out + zoomOut (); + else if (button==bZoom100) // zoom 100 + zoom11 (); + else if (button==bClose) {// close + deleted = true; + iarea->cropWindowClosed (this); + } +} + +void CropWindow::redrawNeeded (LWButton* button) { + + iarea->redraw (); +} + +void CropWindow::changeZoom (int zoom, bool notify, int centerx, int centery) { + + cropZoom = zoom; + if (cropZoom<0) + cropZoom = 0; + else if (cropZoom>MAXZOOMSTEPS) + cropZoom = MAXZOOMSTEPS; + + cropLabel = zoomSteps[cropZoom].label; + cropHandler.setZoom (zoomSteps[cropZoom].czoom, centerx, centery); + if (notify) + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->cropZoomChanged (this); + iarea->redraw (); +} + +void CropWindow::translateCoord (int phyx, int phyy, int& imgx, int& imgy) { + + int cropX, cropY; + cropHandler.getPosition (cropX, cropY); + imgx = cropX + (phyx - xpos - imgX)/zoomSteps[cropZoom].zoom; + imgy = cropY + (phyy - ypos - imgY)/zoomSteps[cropZoom].zoom; +} + +void CropWindow::drawDecoration (Cairo::RefPtr cr) { + + int x = xpos, y = ypos; + // prepare label + Glib::RefPtr context = iarea->get_pango_context () ; + Pango::FontDescription fontd = context->get_font_description (); + fontd.set_weight (Pango::WEIGHT_BOLD); + fontd.set_size(8*Pango::SCALE); + context->set_font_description (fontd); + Glib::RefPtr cllayout = iarea->create_pango_layout(cropLabel); + int iw, ih; + cllayout->get_pixel_size (iw, ih); + + // draw decoration (border) + int h = height, w = width; + cr->set_source_rgb (0,0,0); + cr->set_line_width (1.0); + cr->move_to (x+0.5, y+h-0.5); + cr->line_to (x+0.5, y+0.5); + cr->line_to (x+w-0.5, y+0.5); + cr->stroke (); + cr->set_source_rgb (1,1,1); + cr->move_to (x+w-0.5, y+0.5); + cr->line_to (x+w-0.5, y+h-0.5); + cr->line_to (x+0.5, y+h-0.5); + cr->stroke (); + cr->set_source_rgb (0.5,0.5,0.5); + cr->rectangle (x+1.5, y+1.5+titleHeight, w-3, h-titleHeight-3); + cr->stroke (); + cr->set_source_rgb (1,1,1); + cr->move_to (x+2.5, y+h-2.5); + cr->line_to (x+2.5, y+titleHeight+2.5); + cr->line_to (x+w-2.5, y+titleHeight+2.5); + cr->stroke (); + cr->set_source_rgb (0,0,0); + cr->move_to (x+w-2.5, y+titleHeight+2.5); + cr->line_to (x+w-2.5, y+h-2.5); + cr->line_to (x+2.5, y+h-2.5); + cr->stroke (); + cr->set_source_rgb (0.5,0.5,0.5); + cr->rectangle (x+1.5, y+1.5, w-3, titleHeight); + cr->stroke_preserve (); + cr->fill (); + + // draw label + cr->set_source_rgb (1,1,1); + cr->move_to (x+6+sideBorderWidth+bZoomIn->getIcon()->get_width()+bZoomOut->getIcon()->get_width()+bZoom100->getIcon()->get_width(), y+upperBorderWidth+(titleHeight-ih)/2); + cllayout->add_to_cairo_context (cr); + cr->fill (); + + buttonSet.redraw (cr); +} + +void CropWindow::drawStraightenGuide (Cairo::RefPtr cr) { + + if (action_x!=press_x || action_y!=press_y) { + double arg = (press_x-action_x) / sqrt(double((press_x-action_x)*(press_x-action_x)+(press_y-action_y)*(press_y-action_y))); + double sol1, sol2; + double pi = M_PI; + if (press_y>action_y) { + sol1 = acos(arg)*180/pi; + sol2 = -acos(-arg)*180/pi; + } + else { + sol1 = acos(-arg)*180/pi; + sol2 = -acos(arg)*180/pi; + } + if (fabs(sol1)45) + rot_deg = - 90.0 + rot_deg; + } + else + rot_deg = 0; + + Glib::RefPtr context = iarea->get_pango_context () ; + Pango::FontDescription fontd = context->get_font_description (); + fontd.set_weight (Pango::WEIGHT_BOLD); + fontd.set_size (8*Pango::SCALE); + context->set_font_description (fontd); + Glib::RefPtr deglayout = iarea->create_pango_layout(Glib::ustring::compose ("%1 deg", Glib::ustring::format(std::setprecision(2), rot_deg))); + + int x1 = press_x; + int y1 = press_y; + int y2 = action_y; + int x2 = action_x; +/* if (x1<0) x1 = 0; + if (y1<0) y1 = 0; + if (x2<0) x2 = 0; + if (y2<0) y2 = 0; + if (x2>=image->getWidth()) x2 = image->getWidth()-1; + if (y2>=image->getHeight()) y2 = image->getHeight()-1; + if (x1>=image->getWidth()) x1 = image->getWidth()-1; + if (y1>=image->getHeight()) y1 = image->getHeight()-1; +*/ + + cr->set_line_width (1.5); + cr->set_source_rgb (1.0, 1.0, 1.0); + cr->move_to (x1, y1); + cr->line_to (x2, y2); + cr->stroke (); + cr->set_source_rgb (0.0, 0.0, 0.0); + std::valarray ds (1); + ds[0] = 4; + cr->set_dash (ds, 0); + cr->move_to (x1, y1); + cr->line_to (x2, y2); + cr->stroke (); + + if (press_x!=action_x && press_y!=action_y) { + cr->set_source_rgb (0.0, 0.0, 0.0); + cr->move_to ((x1+x2)/2+1, (y1+y2)/2+1); + deglayout->add_to_cairo_context (cr); + cr->move_to ((x1+x2)/2+1, (y1+y2)/2-1); + deglayout->add_to_cairo_context (cr); + cr->move_to ((x1+x2)/2-1, (y1+y2)/2+1); + deglayout->add_to_cairo_context (cr); + cr->move_to ((x1+x2)/2+1, (y1+y2)/2+1); + deglayout->add_to_cairo_context (cr); + cr->fill (); + cr->set_source_rgb (1.0, 1.0, 1.0); + cr->move_to ((x1+x2)/2, (y1+y2)/2); + deglayout->add_to_cairo_context (cr); + cr->fill (); + } +} + +void CropWindow::drawSpotWBRectangle (Cairo::RefPtr cr) { + + int rectsize = iarea->getSpotWBRectSize (); + int x1 = action_x/zoomSteps[cropZoom].zoom - rectsize; + int y1 = action_y/zoomSteps[cropZoom].zoom - rectsize; + int y2 = action_y/zoomSteps[cropZoom].zoom + rectsize; + int x2 = action_x/zoomSteps[cropZoom].zoom + rectsize; + + cr->set_line_width (1.0); + cr->rectangle (xpos+imgX-0.5, ypos+imgY-0.5, imgW, imgH); + cr->clip (); + + cr->set_source_rgb (1.0, 1.0, 1.0); + cr->rectangle (x1*zoomSteps[cropZoom].zoom-1.5, y1*zoomSteps[cropZoom].zoom-1.5, x2*zoomSteps[cropZoom].zoom-x1*zoomSteps[cropZoom].zoom+2, y2*zoomSteps[cropZoom].zoom-y1*zoomSteps[cropZoom].zoom+2); + cr->stroke (); + cr->set_source_rgb (0.0, 0.0, 0.0); + cr->rectangle (x1*zoomSteps[cropZoom].zoom-0.5, y1*zoomSteps[cropZoom].zoom-0.5, x2*zoomSteps[cropZoom].zoom-x1*zoomSteps[cropZoom].zoom, y2*zoomSteps[cropZoom].zoom-y1*zoomSteps[cropZoom].zoom); + cr->stroke (); + + cr->reset_clip (); +} + +void CropWindow::getObservedFrameArea (int& x, int& y, int& w, int& h) { + + int cropX, cropY, cropW, cropH; + observedCropWin->getCropRectangle (cropX, cropY, cropW, cropH); + int myCropX, myCropY, myCropW, myCropH; + getCropRectangle (myCropX, myCropY, myCropW, myCropH); + + // translate it to screen coordinates + x = xpos + imgX + (cropX-myCropX)*zoomSteps[cropZoom].zoom; + y = ypos + imgY + (cropY-myCropY)*zoomSteps[cropZoom].zoom; + w = cropW * zoomSteps[cropZoom].zoom; + h = cropH * zoomSteps[cropZoom].zoom; +} + +void CropWindow::drawObservedFrame (Cairo::RefPtr cr) { + + int x, y, w, h; + getObservedFrameArea (x, y, w, h); + + cr->set_source_rgb (1.0, 1.0, 1.0); + cr->set_line_width (4); + cr->rectangle (x-2, y-2, w+4, h+4); + cr->stroke (); + cr->set_source_rgb (1.0, 0.0, 0.0); + cr->set_line_width (2); + cr->rectangle (x-2, y-2, w+4, h+4); + cr->stroke (); +} + +void CropWindow::cropImageUpdated () { + + iarea->redraw (); +} + +void CropWindow::cropWindowChanged () { + + if (!decorated) + iarea->updateScrollbars (); + iarea->redraw (); +} + +void CropWindow::initialImageArrived () { + + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->initialImageArrived (this); +} + + +void CropWindow::remoteMove (int deltaX, int deltaY) { + + state = SCropImgMove; + action_x = deltaX; + action_y = deltaY; + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->cropPositionChanged (this); +} + +void CropWindow::remoteMoveReady () { + + int cropX, cropY; + cropHandler.getPosition (cropX, cropY); + cropHandler.setPosition (cropX + action_x, cropY + action_y); + cropHandler.getPosition (cropX, cropY); + state = SNormal; + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->cropPositionChanged (this); +} + +void CropWindow::delCropWindowListener (CropWindowListener* l) { + + std::list::iterator i=listeners.begin(); + while (i!=listeners.end()) + if (*i==l) + i = listeners.erase (i); + else + i++; +} diff --git a/rtgui/cropwindow.h b/rtgui/cropwindow.h new file mode 100644 index 000000000..35372efca --- /dev/null +++ b/rtgui/cropwindow.h @@ -0,0 +1,146 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _CROPWINDOW_ +#define _CROPWINDOW_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class CropWindow; +class CropWindowListener { + + public: + virtual void cropPositionChanged (CropWindow*) {} + virtual void cropWindowSizeChanged (CropWindow*) {} + virtual void cropZoomChanged (CropWindow*) {} + virtual void initialImageArrived (CropWindow*) {} +}; + +class ImageArea; +class CropWindow : public LWButtonListener, public CropHandlerListener { + + // state management + ImgEditState state; // current state of user (see enum State) + int action_x, action_y, press_x, press_y; + double rot_deg; + bool onResizeArea; + bool deleted; + bool fitZoomEnabled; + bool fitZoom; + + // decoration + Cairo::RefPtr resizeSurface; + LWButton *bZoomIn, *bZoomOut, *bZoom100, *bZoomFit, *bClose; + LWButtonSet buttonSet; + Glib::ustring cropLabel; + int backColor; + bool decorated; + + // sizes, positions + int titleHeight, sideBorderWidth, lowerBorderWidth, upperBorderWidth, sepWidth, minWidth; + int imgAreaX, imgAreaY, imgAreaW, imgAreaH; + int imgX, imgY, imgW, imgH; + int xpos, ypos, width, height; + + // image handling + CropHandler cropHandler; + ImageArea* iarea; + int cropZoom; // *1000 + + // crop gui listener + CropGUIListener* cropgl; + PointerMotionListener* pmlistener; + std::list listeners; + + CropWindow* observedCropWin; + + bool onArea (CursorArea a, int x, int y); + void updateCursor (int x, int y); + void drawDecoration (Cairo::RefPtr cr); + void drawStraightenGuide (Cairo::RefPtr cr); + void drawSpotWBRectangle (Cairo::RefPtr cr); + void drawObservedFrame (Cairo::RefPtr cr); + void translateCoord (int phyx, int phyy, int& imgx, int& imgy); + void changeZoom (int zoom, bool notify=true, int centerx=-1, int centery=-1); + void getObservedFrameArea(int& x, int& y, int& w, int& h); + + public: + CropWindow (ImageArea* parent, rtengine::StagedImageProcessor* ipc_); + ~CropWindow (); + + void setDecorated (bool decorated) { this->decorated = decorated; } + void setFitZoomEnabled (bool fze) { fitZoomEnabled = fze; } + void setObservedCropWin (CropWindow* cw) { observedCropWin = cw; } + + void setPosition (int x, int y); + void getPosition (int& x, int& y); + void setSize (int w, int h, bool norefresh=false); + void getSize (int& w, int& h); + + // zoomlistener interface + void zoomIn (); + void zoomOut (); + void zoom11 (); + void zoomFit (); + double getZoom (); + void setZoom (double zoom); + + bool isInside (int x, int y); + + void buttonPress (int button, int num, int state, int x, int y); + void buttonRelease (int button, int num, int state, int x, int y); + void pointerMoved (int x, int y); + + void expose (Cairo::RefPtr cr); + + // interface lwbuttonlistener + void buttonPressed (LWButton* button, int actionCode, void* actionData); + void redrawNeeded (LWButton* button); + + // crop handling + void getCropRectangle (int& x, int& y, int& w, int& h); + void getCropPosition (int& x, int& y); + void setCropPosition (int x, int y); + void getCropSize (int& w, int& h); + + // listeners + void setCropGUIListener (CropGUIListener* cgl) { cropgl = cgl; } + void setPointerMotionListener (PointerMotionListener* pml) { pmlistener = pml; } + + // crop window listeners + void addCropWindowListener (CropWindowListener* l) { listeners.push_back (l); } + void delCropWindowListener (CropWindowListener* l); + + // crophandlerlistener interface + void cropImageUpdated (); + void cropWindowChanged (); + void initialImageArrived (); + + void remoteMove (int deltaX, int deltaY); + void remoteMoveReady (); +}; + +#endif diff --git a/rtgui/cursormanager.cc b/rtgui/cursormanager.cc new file mode 100644 index 000000000..8dee294df --- /dev/null +++ b/rtgui/cursormanager.cc @@ -0,0 +1,72 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +CursorManager cursorManager; + +void CursorManager::init (Glib::RefPtr mainWin) { + + cResizeWidth = new Gdk::Cursor (Gdk::SB_H_DOUBLE_ARROW); + cResizeHeight = new Gdk::Cursor (Gdk::SB_V_DOUBLE_ARROW); + cResizeDiag = new Gdk::Cursor (Gdk::BOTTOM_RIGHT_CORNER); + cCropMove = new Gdk::Cursor (Gdk::FLEUR); + cCropMoving = new Gdk::Cursor (Gdk::HAND2); + cCropSelection = new Gdk::Cursor (Gdk::CROSSHAIR); +#ifdef _WIN32 + cNormal = new Gdk::Cursor (Gdk::LAST_CURSOR); +#else + cNormal = new Gdk::Cursor (Gdk::ARROW); +#endif + Glib::RefPtr hand = safe_create_from_file(argv0+"/images/openhand22.png"); + Glib::RefPtr close_hand = safe_create_from_file(argv0+"/images/closedhand22.png"); + Glib::RefPtr wbpick = safe_create_from_file(argv0+"/images/wbpicker16.png"); + cHand = hand ? new Gdk::Cursor (cNormal->get_display(), hand, 10, 10) : new Gdk::Cursor (Gdk::HAND2); + cClosedHand = close_hand ? new Gdk::Cursor (cNormal->get_display(), close_hand, 10, 10) : new Gdk::Cursor (Gdk::HAND2); + cWB = wbpick ? new Gdk::Cursor (cNormal->get_display(), wbpick, 1, 12) : new Gdk::Cursor (Gdk::ARROW); + + mainWindow = mainWin; +} + +void CursorManager::setCursor (Glib::RefPtr window, CursorShape shape) { + + if (shape==CSArrow) + window->set_cursor (*cNormal); + else if (shape==CSOpenHand) + window->set_cursor (*cHand); + else if (shape==CSClosedHand) + window->set_cursor (*cClosedHand); + else if (shape==CSMove) + window->set_cursor (*cCropMove); + else if (shape==CSResizeWidth) + window->set_cursor (*cResizeWidth); + else if (shape==CSResizeHeight) + window->set_cursor (*cResizeHeight); + else if (shape==CSResizeDiagonal) + window->set_cursor (*cResizeDiag); + else if (shape==CSSpotWB) + window->set_cursor (*cWB); + else if (shape==CSCropSelect) + window->set_cursor (*cCropSelection); + else if (shape==CSStraighten) + window->set_cursor (*cCropSelection); +} + + diff --git a/rtgui/cursormanager.h b/rtgui/cursormanager.h new file mode 100644 index 000000000..f214416c0 --- /dev/null +++ b/rtgui/cursormanager.h @@ -0,0 +1,49 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _CURSORMANAGER_ +#define _CURSORMANAGER_ + +#include + +enum CursorShape {CSArrow, CSOpenHand, CSClosedHand, CSMove, CSResizeWidth, CSResizeHeight, CSResizeDiagonal, CSSpotWB, CSCropSelect, CSStraighten}; + +class CursorManager { + + protected: + Gdk::Cursor* cResizeWidth; + Gdk::Cursor* cResizeHeight; + Gdk::Cursor* cResizeDiag; + Gdk::Cursor* cCropMove; + Gdk::Cursor* cCropMoving; + Gdk::Cursor* cNormal; + Gdk::Cursor* cCropSelection; + Gdk::Cursor* cHand; + Gdk::Cursor* cClosedHand; + Gdk::Cursor* cWB; + Glib::RefPtr mainWindow; + + public: + void init (Glib::RefPtr mainWin); + void setCursor (Glib::RefPtr window, CursorShape shape); +}; + +extern CursorManager cursorManager; + +#endif + diff --git a/rtgui/curveeditor.cc b/rtgui/curveeditor.cc new file mode 100644 index 000000000..0a74b74bb --- /dev/null +++ b/rtgui/curveeditor.cc @@ -0,0 +1,393 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include + +CurveEditor::CurveEditor () : cl(NULL), activeParamControl(-1), realized(false), curveTypeIx(-1) { + + Gtk::HBox* tsbox = Gtk::manage (new Gtk::HBox ()); + Gtk::Label* tslab = Gtk::manage (new Gtk::Label (M("CURVEEDITOR_TYPE"))); + curveType = Gtk::manage (new Gtk::ComboBoxText ()); + + tsbox->pack_start (*tslab, Gtk::PACK_SHRINK, 8); + tsbox->pack_start (*curveType); + + pack_start (*tsbox); + + curveType->append_text ("Linear"); + curveType->append_text ("Parametric"); + curveType->append_text ("Custom"); + curveType->set_active (0); + + // custom curve + customCurveBox = new Gtk::VBox (); + customCurve = Gtk::manage (new MyCurve ()); + Gtk::AspectFrame* af = Gtk::manage (new Gtk::AspectFrame ("",Gtk::ALIGN_CENTER,Gtk::ALIGN_CENTER,1,false)); + af->add (*customCurve); + customCurve->set_size_request (-1, 200); + customCurve->setType (Spline); + customCurveBox->pack_start (*af, Gtk::PACK_EXPAND_WIDGET); + + Gtk::HBox* bbox = Gtk::manage (new Gtk::HBox ()); + save = Gtk::manage (new Gtk::Button ()); + save->add (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-save"), Gtk::ICON_SIZE_BUTTON))); + load = Gtk::manage (new Gtk::Button ()); + load->add (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-open"), Gtk::ICON_SIZE_BUTTON))); + + bbox->pack_end (*save, Gtk::PACK_EXPAND_WIDGET, 4); + bbox->pack_end (*load, Gtk::PACK_EXPAND_WIDGET, 4); + + customCurveBox->pack_end (*bbox, Gtk::PACK_SHRINK, 2); + customCurveBox->show_all (); + + save->signal_clicked().connect( sigc::mem_fun(*this, &CurveEditor::savePressed) ); + load->signal_clicked().connect( sigc::mem_fun(*this, &CurveEditor::loadPressed) ); + save->set_tooltip_text (M("CURVEEDITOR_TOOLTIPSAVE")); + load->set_tooltip_text (M("CURVEEDITOR_TOOLTIPLOAD")); + + // parametric curve + paramCurveBox = new Gtk::VBox (); + paramCurve = Gtk::manage (new MyCurve ()); + Gtk::Table* ctab = Gtk::manage (new Gtk::Table (2,1)); + Gtk::AspectFrame* afp = Gtk::manage (new Gtk::AspectFrame ("",Gtk::ALIGN_CENTER,Gtk::ALIGN_CENTER,1,false)); + afp->add (*paramCurve); + paramCurve->set_size_request (200, 200); + paramCurve->setType (Parametric); + shcSelector = Gtk::manage (new SHCSelector ()); + shcSelector->set_size_request (200, 20); + + ctab->attach (*afp, 0, 1, 0, 1, Gtk::FILL, Gtk::SHRINK, 2, 2); + ctab->attach (*shcSelector, 0, 1, 1, 2, Gtk::FILL, Gtk::SHRINK, 2, 2); + + Gtk::HBox* tmpb = Gtk::manage (new Gtk::HBox ()); + tmpb->pack_start (*ctab, true, false); + + paramCurveBox->pack_start (*tmpb, true, true); + + highlights = Gtk::manage (new Adjuster (M("CURVEEDITOR_HIGHLIGHTS"), -100, 100, 1, 0)); + lights = Gtk::manage (new Adjuster (M("CURVEEDITOR_LIGHTS"), -100, 100, 1, 0)); + darks = Gtk::manage (new Adjuster (M("CURVEEDITOR_DARKS"), -100, 100, 1, 0)); + shadows = Gtk::manage (new Adjuster (M("CURVEEDITOR_SHADOWS"), -100, 100, 1, 0)); + + Gtk::EventBox* evhighlights = Gtk::manage (new Gtk::EventBox ()); + Gtk::EventBox* evlights = Gtk::manage (new Gtk::EventBox ()); + Gtk::EventBox* evdarks = Gtk::manage (new Gtk::EventBox ()); + Gtk::EventBox* evshadows = Gtk::manage (new Gtk::EventBox ()); + + evhighlights->add (*highlights); + evlights->add (*lights); + evdarks->add (*darks); + evshadows->add (*shadows); + + paramCurveBox->pack_start (*Gtk::manage (new Gtk::HSeparator ())); + paramCurveBox->pack_start (*evhighlights); + paramCurveBox->pack_start (*evlights); + paramCurveBox->pack_start (*evdarks); + paramCurveBox->pack_start (*evshadows); + paramCurveBox->show_all (); + + customCurveBox->reference (); + paramCurveBox->reference (); + + customCurve->setCurveListener (this); + paramCurve->setCurveListener (this); + shcSelector->setSHCListener (this); + + highlights->setAdjusterListener (this); + lights->setAdjusterListener (this); + darks->setAdjusterListener (this); + shadows->setAdjusterListener (this); + + evhighlights->set_events(Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK); + evlights->set_events(Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK); + evdarks->set_events(Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK); + evshadows->set_events(Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK); + typeconn = curveType->signal_changed().connect (sigc::mem_fun(*this, &CurveEditor::typeSelectionChanged) ); + evhighlights->signal_enter_notify_event().connect (sigc::bind(sigc::mem_fun(*this, &CurveEditor::adjusterEntered), 4)); + evlights->signal_enter_notify_event().connect (sigc::bind(sigc::mem_fun(*this, &CurveEditor::adjusterEntered), 5)); + evdarks->signal_enter_notify_event().connect (sigc::bind(sigc::mem_fun(*this, &CurveEditor::adjusterEntered), 6)); + evshadows->signal_enter_notify_event().connect (sigc::bind(sigc::mem_fun(*this, &CurveEditor::adjusterEntered), 7)); + evhighlights->signal_leave_notify_event().connect (sigc::bind(sigc::mem_fun(*this, &CurveEditor::adjusterLeft), 4)); + evlights->signal_leave_notify_event().connect (sigc::bind(sigc::mem_fun(*this, &CurveEditor::adjusterLeft), 5)); + evdarks->signal_leave_notify_event().connect (sigc::bind(sigc::mem_fun(*this, &CurveEditor::adjusterLeft), 6)); + evshadows->signal_leave_notify_event().connect (sigc::bind(sigc::mem_fun(*this, &CurveEditor::adjusterLeft), 7)); + + show_all (); +} + +CurveEditor::~CurveEditor () { + + delete customCurveBox; + delete paramCurveBox; +} + +void CurveEditor::savePressed () { + + Gtk::FileChooserDialog dialog(M("CURVEEDITOR_SAVEDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_SAVE); +// if (options.multiUser) +// dialog.set_current_folder (Options::rtdir + "/" + options.profilePath); +// else +// dialog.set_current_folder (argv0 + "/" + options.profilePath); + + dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); + dialog.add_button(Gtk::StockID("gtk-save"), Gtk::RESPONSE_OK); + + Gtk::FileFilter filter_pp; + filter_pp.set_name(M("CURVEEDITOR_FILEDLGFILTERCURVE")); + filter_pp.add_pattern("*.rtc"); + dialog.add_filter(filter_pp); + + Gtk::FileFilter filter_any; + filter_any.set_name(M("CURVEEDITOR_FILEDLGFILTERANY")); + filter_any.add_pattern("*"); + dialog.add_filter(filter_any); + + dialog.set_do_overwrite_confirmation (true); + + int result = dialog.run(); + + if (result==Gtk::RESPONSE_OK) { + + std::string fname = dialog.get_filename(); + + if (getExtension (fname)!="rtc") + fname = fname + ".rtc"; + + if (Glib::file_test (fname, Glib::FILE_TEST_EXISTS)) { + Glib::ustring msg_ = Glib::ustring("") + fname + ": " + M("MAIN_MSG_ALREADYEXISTS") + "\n" + M("MAIN_MSG_QOVERWRITE") + ""; + Gtk::MessageDialog msgd (msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); + int response = msgd.run (); + if (response==Gtk::RESPONSE_NO) + return; + } + + std::ofstream f (fname.c_str()); + std::vector p = customCurve->getPoints (); + int ix = 0; + if (p[ix++]<0) + f << "Linear\n"; + else + f << "Spline\n"; + for (int i=0; i p; + std::string s; + f >> s; + if (s=="Linear") + p.push_back (-1); + else if (s=="Spline") + p.push_back (1); + else return; + double x; + while (f) { + f >> x; + if (f) + p.push_back (x); + } + customCurve->setPoints (p); + customCurve->queue_draw (); + customCurve->notifyListener (); + } + } +} + +void CurveEditor::on_realize () { + + Gtk::VBox::on_realize(); + realized = true; + setCurve (tmpCurve); +} + +void CurveEditor::setCurve (const std::vector& c) { + + tmpCurve = c; + + if (realized && curveType->get_active_row_number()<3) { // if it is not realized or "unchanged" is selected, just store the curve (prev line) and do not change gui + + typeconn.block(true); + if (c.size()==0 || c[0]==0) { + curveType->set_active (0); + curveTypeIx = 0; + } + else if (c[0]==1) { + curveType->set_active (2); + curveTypeIx = 2; + customCurve->setPoints (c); + } + else if (c[0]==2) { + curveType->set_active (1); + curveTypeIx = 1; + paramCurve->setPoints (c); + shcSelector->setPositions (c[1], c[2], c[3]); + highlights->setValue (c[4]); + lights->setValue (c[5]); + darks->setValue (c[6]); + shadows->setValue (c[7]); + } + removeIfThere (this, customCurveBox, false); + removeIfThere (this, paramCurveBox, false); + + if (curveType->get_active_row_number()==1) + pack_start (*paramCurveBox); + else if (curveType->get_active_row_number()==2) + pack_start (*customCurveBox); + + typeconn.block(false); + } +} + +std::vector CurveEditor::getCurve () { + + if (!realized || curveType->get_active_row_number()==3) + return tmpCurve; + + if (curveTypeIx<=0) { + std::vector lcurve (1); + lcurve[0] = 0.0; + return lcurve; + } + else if (curveTypeIx==1) { + std::vector lcurve (8); + lcurve[0] = 2.0; + shcSelector->getPositions (lcurve[1], lcurve[2], lcurve[3]); + lcurve[4] = highlights->getValue (); + lcurve[5] = lights->getValue (); + lcurve[6] = darks->getValue (); + lcurve[7] = shadows->getValue (); + return lcurve; + } + else if (curveTypeIx==2) + return customCurve->getPoints (); +} + +void CurveEditor::typeSelectionChanged () { + + removeIfThere (this, customCurveBox, false); + removeIfThere (this, paramCurveBox, false); + + if (curveType->get_active_row_number()==1) + pack_start (*paramCurveBox); + else if (curveType->get_active_row_number()==2) + pack_start (*customCurveBox); + + if (curveType->get_active_row_number()<3) + curveTypeIx = curveType->get_active_row_number(); + + curveChanged (); +} + +void CurveEditor::curveChanged () { + + if (cl) + cl->curveChanged (); +} + +void CurveEditor::shcChanged () { + + paramCurve->setPoints (getCurve()); + if (cl) + cl->curveChanged (); +} + +void CurveEditor::adjusterChanged (Adjuster* a, double newval) { + + paramCurve->setPoints (getCurve()); + if (cl) + cl->curveChanged (); +} + +bool CurveEditor::adjusterEntered (GdkEventCrossing* ev, int ac) { + + if (ev->detail != GDK_NOTIFY_INFERIOR) { + activeParamControl = ac; + paramCurve->setActiveParam (activeParamControl); + } + return true; +} + +bool CurveEditor::adjusterLeft (GdkEventCrossing* ev, int ac) { + + if (ev->detail != GDK_NOTIFY_INFERIOR) { + activeParamControl = -1; + paramCurve->setActiveParam (activeParamControl); + } + return true; +} + +void CurveEditor::setBatchMode (bool batchMode) { + + curveType->append_text (M("GENERAL_UNCHANGED")); +} + +bool CurveEditor::isUnChanged () { + + return curveType->get_active_row_number()==3; +} + +void CurveEditor::setUnChanged (bool uc) { + + if (uc) { + typeconn.block(true); + removeIfThere (this, customCurveBox, false); + removeIfThere (this, paramCurveBox, false); + curveType->set_active (3); + typeconn.block(false); + } + else { + typeconn.block(true); + curveType->set_active (-1); // hack: if it remains 3 (unchanged), then setcurve does not switch selection in the combo + setCurve (getCurve ()); + typeconn.block(false); + } +} + +void CurveEditor::updateBackgroundHistogram (unsigned int* hist) { + + paramCurve->updateBackgroundHistogram (hist); + customCurve->updateBackgroundHistogram (hist); +} diff --git a/rtgui/curveeditor.h b/rtgui/curveeditor.h new file mode 100644 index 000000000..35fd715e8 --- /dev/null +++ b/rtgui/curveeditor.h @@ -0,0 +1,79 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _CURVEEDITOR_ +#define _CURVEEDITOR_ + +#include +#include +#include +#include + +class CurveEditor : public Gtk::VBox, public CurveListener, public SHCListener, public AdjusterListener { + + Gtk::ComboBoxText* curveType; + Gtk::VBox* paramCurveBox; + Gtk::VBox* customCurveBox; + + MyCurve* customCurve; + MyCurve* paramCurve; + SHCSelector* shcSelector; + + Adjuster* highlights; + Adjuster* lights; + Adjuster* darks; + Adjuster* shadows; + + Gtk::Button* save; + Gtk::Button* load; + + CurveListener* cl; + + bool realized; + std::vector tmpCurve; + int curveTypeIx; + + int activeParamControl; + + sigc::connection typeconn; + + public: + + CurveEditor (); + virtual ~CurveEditor (); + void setBatchMode (bool batchMode); + bool isUnChanged (); + void setUnChanged (bool uc); + + void on_realize (); + void setCurveListener (CurveListener* l) { cl = l; } + void savePressed (); + void loadPressed (); + void typeSelectionChanged (); + void setCurve (const std::vector& c); + std::vector getCurve (); + void curveChanged (); + void shcChanged (); + void adjusterChanged (Adjuster* a, double newval); + bool adjusterEntered (GdkEventCrossing* ev, int ac); + bool adjusterLeft (GdkEventCrossing* ev, int ac); + void updateBackgroundHistogram (unsigned int* hist); +}; + + +#endif diff --git a/rtgui/curvelistener.h b/rtgui/curvelistener.h new file mode 100644 index 000000000..87102db6b --- /dev/null +++ b/rtgui/curvelistener.h @@ -0,0 +1,28 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _CURVELISTENER_ +#define _CURVELISTENER_ + +class CurveListener { + + public: + virtual void curveChanged () {} +}; + +#endif diff --git a/rtgui/dirbrowser.cc b/rtgui/dirbrowser.cc new file mode 100644 index 000000000..8475a09fd --- /dev/null +++ b/rtgui/dirbrowser.cc @@ -0,0 +1,367 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#ifdef WIN32 +#define _WIN32_WINNT 0x0600 +#include +#endif +#include +#include + +#define CHECKTIME 5000 +extern Glib::ustring argv0; + +DirBrowser::DirBrowser () { + + dirtree = new Gtk::TreeView(); + scrolledwindow4 = new Gtk::ScrolledWindow(); + +// dirtree->set_flags(Gtk::CAN_FOCUS); + dirtree->set_headers_visible(false); + dirtree->set_rules_hint(false); + dirtree->set_reorderable(false); + dirtree->set_enable_search(false); + scrolledwindow4->set_flags(Gtk::CAN_FOCUS); + scrolledwindow4->set_border_width(2); + scrolledwindow4->set_shadow_type(Gtk::SHADOW_NONE); + scrolledwindow4->set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS); + scrolledwindow4->property_window_placement().set_value(Gtk::CORNER_TOP_LEFT); + scrolledwindow4->add(*dirtree); + + pack_start (*scrolledwindow4); + dirtree->show (); + scrolledwindow4->show (); +} + +void DirBrowser::fillDirTree () { + + openfolder = safe_create_from_file (argv0+"/images/folder_open.png"); + closedfolder = safe_create_from_file (argv0+"/images/folder.png"); + icdrom = safe_create_from_file (argv0+"/images/cdrom.png"); + ifloppy = safe_create_from_file (argv0+"/images/floppy.png"); + ihdd = safe_create_from_file (argv0+"/images/hdd.png"); + iremovable = safe_create_from_file (argv0+"/images/usbpendrive.png"); + inetwork = safe_create_from_file (argv0+"/images/network.png"); + + //Create the Tree model: + dirTreeModel = Gtk::TreeStore::create(dtColumns); + dirtree->set_model (dirTreeModel); + + fillRoot (); + + Gtk::CellRendererPixbuf* render_pb = new Gtk::CellRendererPixbuf (); + tvc.pack_start (*render_pb, false); + tvc.add_attribute(*render_pb, "pixbuf-expander-closed", 1); + tvc.add_attribute(*render_pb, "pixbuf", 1); + tvc.add_attribute(*render_pb, "pixbuf-expander-open", 0); + tvc.pack_start (crt); + tvc.add_attribute(crt, "text", 2); + + crt.property_ypad() = 0; + render_pb->property_ypad() = 0; + + dirtree->append_column(tvc); + + dirtree->signal_row_expanded().connect(sigc::mem_fun(*this, &DirBrowser::row_expanded)); + dirtree->signal_row_activated().connect(sigc::mem_fun(*this, &DirBrowser::row_activated)); +} + +#ifdef WIN32 +void DirBrowser::addRoot (char letter) { + + char volume[4]; + volume[0] = letter; + strcpy (volume+1, ":\\"); + + Gtk::TreeModel::iterator root = dirTreeModel->append(); + root->set_value (dtColumns.filename, Glib::ustring(volume)); + root->set_value (dtColumns.dirname, Glib::ustring(volume)); + + int type = GetDriveType (volume); + if (type==DRIVE_CDROM) { + root->set_value (0, icdrom); + root->set_value (1, icdrom); + } + else if (type==DRIVE_REMOVABLE) { + if (letter-'A'<2) { + root->set_value (0, ifloppy); + root->set_value (1, ifloppy); + } + else { + root->set_value (0, iremovable); + root->set_value (1, iremovable); + } + } + else if (type==DRIVE_REMOTE) { + root->set_value (0, inetwork); + root->set_value (1, inetwork); + } + else if (type==DRIVE_FIXED) { + root->set_value (0, ihdd); + root->set_value (1, ihdd); + } + + Gtk::TreeModel::iterator child = dirTreeModel->append (root->children()); + child->set_value (dtColumns.filename, Glib::ustring("foo")); +} + +void DirBrowser::updateDirTreeRoot () { + + for (Gtk::TreeModel::iterator i=dirTreeModel->children().begin(); i!=dirTreeModel->children().end(); i++) + updateDirTree (i); +} + +void DirBrowser::updateDirTree (const Gtk::TreeModel::iterator& iter) { + + if (dirtree->row_expanded (dirTreeModel->get_path (iter))) { + updateDir (iter); + for (Gtk::TreeModel::iterator i=iter->children().begin(); i!=iter->children().end(); i++) + updateDirTree (i); + } +} + +void DirBrowser::updateVolumes () { + + int nvolumes = GetLogicalDrives (); + if (nvolumes!=volumes) { + for (int i=0; i<32; i++) + if (((volumes >> i) & 1) && !((nvolumes >> i) & 1)) { // volume i has been deleted + for (Gtk::TreeModel::iterator iter = dirTreeModel->children().begin(); iter!=dirTreeModel->children().end(); iter++) + if (iter->get_value (dtColumns.filename).c_str()[0]-'A' == i) { + dirTreeModel->erase (iter); + break; + } + } + else if (!((volumes >> i) & 1) && ((nvolumes >> i) & 1)) + addRoot ('A'+i); // volume i has been added + volumes = nvolumes; + } +} + +int _updateVolumes (void* br) { + + gdk_threads_enter (); + ((DirBrowser*)br)->updateVolumes (); + gdk_threads_leave (); + return 1; +} +int _updateDirTree (void* br) { + + gdk_threads_enter (); + ((DirBrowser*)br)->updateDirTreeRoot (); + gdk_threads_leave (); + return 0; +} + +void DirBrowser::winDirChanged () { + + g_idle_add (_updateDirTree, this); +} +#endif + +void DirBrowser::fillRoot () { + +#ifdef WIN32 + volumes = GetLogicalDrives (); + for (int i=0; i<32; i++) + if ((volumes >> i) & 1) + addRoot ('A'+i); + // since sigc++ is not thread safe, we have to use the glib function + g_timeout_add (CHECKTIME, _updateVolumes, this); +#else + Gtk::TreeModel::Row rootRow = *(dirTreeModel->append()); + rootRow[dtColumns.filename] = "/"; + rootRow[dtColumns.dirname] = "/"; + Gtk::TreeModel::Row childRow = *(dirTreeModel->append(rootRow.children())); + childRow[dtColumns.filename] = "foo"; +#endif +} + +void DirBrowser::row_expanded (const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path) { + + expandSuccess = false; + + int todel = iter->children().size(); + + std::vector subDirs; + Glib::RefPtr dir = Gio::File::create_for_path (iter->get_value (dtColumns.dirname)); + + safe_build_subdir_list (dir, subDirs, options.fbShowHidden); + + if (subDirs.size() == 0) + dirtree->collapse_row (path); + else { + + std::sort (subDirs.begin(), subDirs.end()); + for (int i=0; ierase (iter->children().begin()); + expandSuccess = true; + } +#ifdef _WIN32 + Glib::RefPtr monitor = Glib::RefPtr(new WinDirMonitor (iter->get_value (dtColumns.dirname), this)); + iter->set_value (dtColumns.monitor, monitor); +#elif defined __APPLE__ + printf("TODO fix dir->monitor_directory () for OSX\n"); +#else + Glib::RefPtr monitor = dir->monitor_directory (); + iter->set_value (dtColumns.monitor, monitor); + monitor->signal_changed().connect (sigc::bind(sigc::mem_fun(*this, &DirBrowser::file_changed), iter, dir->get_parse_name())); +#endif +} + +void DirBrowser::updateDir (const Gtk::TreeModel::iterator& iter) { + + // first test if some files are deleted + bool change = true; + while (change) { + change = false; + for (Gtk::TreeModel::iterator it=iter->children().begin(); it!=iter->children().end(); it++) + if (!Glib::file_test (it->get_value (dtColumns.dirname), Glib::FILE_TEST_EXISTS) + || !Glib::file_test (it->get_value (dtColumns.dirname), Glib::FILE_TEST_IS_DIR)) { + dirTreeModel->erase (it); + change = true; + break; + } + } + // test if new files are created + std::vector subDirs; + Glib::RefPtr dir = Gio::File::create_for_path (iter->get_value (dtColumns.dirname)); + safe_build_subdir_list (dir, subDirs, options.fbShowHidden); + + for (int i=0; ichildren().begin(); it!=iter->children().end() && !found ; it++) + found = (it->get_value (dtColumns.filename)==subDirs[i]); + + if (!found) + addDir (iter, subDirs[i]); + } +} + +void DirBrowser::addDir (const Gtk::TreeModel::iterator& iter, const Glib::ustring& dirname) { + + Gtk::TreeModel::iterator child = dirTreeModel->append(iter->children()); + child->set_value (dtColumns.filename, dirname); + child->set_value (0, openfolder); + child->set_value (1, closedfolder); + Glib::ustring fullname = Glib::build_filename (iter->get_value (dtColumns.dirname), dirname); + child->set_value (dtColumns.dirname, fullname); + Glib::RefPtr f = Gio::File::create_for_path (fullname); + Gtk::TreeModel::iterator fooRow = dirTreeModel->append(child->children()); + fooRow->set_value (dtColumns.filename, Glib::ustring("foo")); +} + +void DirBrowser::row_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column) { + + Glib::ustring dname = dirTreeModel->get_iter (path)->get_value (dtColumns.dirname); + if (Glib::file_test (dname, Glib::FILE_TEST_IS_DIR)) + for (int i=0; idirSelected (dname); +} + +Gtk::TreePath DirBrowser::expandToDir (const Glib::ustring& absDirPath) { + + Gtk::TreeModel::Path path; + path.append_index(0); + + int end = 0; + int beg = 0; + char* dcpy = strdup (absDirPath.c_str()); + char* dir = strtok (dcpy, "/\\"); + int count = 0; + expandSuccess = true; + +#ifndef _WIN32 + Gtk::TreeModel::iterator j = dirTreeModel->get_iter (path); + path.up (); + path.append_index (0); + row_expanded(j, path); + path.append_index (0); +#endif + + while (dir) { + Glib::ustring dirstr = dir; +#ifdef _WIN32 + if (count==0) + dirstr = dirstr + "\\"; +#endif + Gtk::TreeModel::iterator i = dirTreeModel->get_iter (path); + int ix = 0; + while (i && expandSuccess) { + Gtk::TreeModel::Row crow = *i; + Glib::ustring str =crow[dtColumns.filename]; +#ifdef _WIN32 + if (str.casefold()==dirstr.casefold()) { +#else + if (str==dirstr) { +#endif + path.up (); + path.append_index (ix); + row_expanded(i, path); + path.append_index (0); + break; + } + ix++; + i++; + } + count++; + dir = strtok(NULL, "/\\"); + } + + free(dcpy); + + path.up (); + dirtree->expand_to_path (path); + + return path; +} + +void DirBrowser::open (const Glib::ustring& dirname, const Glib::ustring& fileName) { + + dirtree->collapse_all (); + + Glib::ustring absDirPath = Gio::File::create_for_path(dirname)->get_parse_name (); + Gtk::TreePath path = expandToDir (absDirPath); + + if (expandSuccess) { + dirtree->scroll_to_row (path); + dirtree->get_selection()->select (path); + for (int i=0; idirSelected (absDirPath, Glib::build_filename (absDirPath, fileName)); + } +} + +void DirBrowser::file_changed (const Glib::RefPtr& file, const Glib::RefPtr& other_file, Gio::FileMonitorEvent event_type, const Gtk::TreeModel::iterator& iter, const Glib::ustring& dirName) { + + if (!file || !Glib::file_test (dirName, Glib::FILE_TEST_IS_DIR) || event_type==Gio::FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED) + return; + + gdk_threads_enter(); + updateDir (iter); + gdk_threads_leave(); +} + +void DirBrowser::selectDir (Glib::ustring dir) { + + open (dir, ""); +} + diff --git a/rtgui/dirbrowser.h b/rtgui/dirbrowser.h new file mode 100644 index 000000000..3c9ba970b --- /dev/null +++ b/rtgui/dirbrowser.h @@ -0,0 +1,103 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _DIRBROWSER_ +#define _DIRBROWSER_ + +#include +#include +#ifdef _WIN32 +#include +#endif +#include +#include + +class DirBrowser : public Gtk::VBox, public DirBrowserRemoteInterface +#ifdef _WIN32 + , public WinDirChangeListener +#endif + { + + private: + + Glib::RefPtr dirTreeModel; + + struct DirTreeColumns : public Gtk::TreeModelColumnRecord { + public: + Gtk::TreeModelColumn filename; + Gtk::TreeModelColumn > icon1; + Gtk::TreeModelColumn > icon2; + Gtk::TreeModelColumn dirname; + #ifdef _WIN32 + Gtk::TreeModelColumn > monitor; + #else + Gtk::TreeModelColumn > monitor; + #endif + + DirTreeColumns() { add(icon1); add(icon2); add(filename); add(dirname); add(monitor); } + }; + + Gtk::TreeViewColumn tvc; + Gtk::CellRendererText crt; + Gtk::CellRendererPixbuf crb; + DirTreeColumns dtColumns; + + Gtk::TreeView *dirtree; + Gtk::ScrolledWindow *scrolledwindow4; + std::vector dllisteners; + + void fillRoot (); + + Glib::RefPtr openfolder; + Glib::RefPtr closedfolder; + Glib::RefPtr icdrom; + Glib::RefPtr ifloppy; + Glib::RefPtr ihdd; + Glib::RefPtr inetwork; + Glib::RefPtr iremovable; + + bool expandSuccess; + + #ifdef WIN32 + int volumes; + public: + void updateVolumes (); + void updateDirTree (const Gtk::TreeModel::iterator& iter); + void updateDirTreeRoot (); + void winDirChanged (); + private: + void addRoot (char letter); + #endif + void addDir (const Gtk::TreeModel::iterator& iter, const Glib::ustring& dirname); + Gtk::TreePath expandToDir (const Glib::ustring& dirName); + void updateDir (const Gtk::TreeModel::iterator& iter); + void notifyListeners (); + + public: + DirBrowser (); + + void fillDirTree (); + void row_expanded (const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path); + void row_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column); + void file_changed (const Glib::RefPtr& file, const Glib::RefPtr& other_file, Gio::FileMonitorEvent event_type, const Gtk::TreeModel::iterator& iter, const Glib::ustring& dirName); + void open (const Glib::ustring& dirName, const Glib::ustring& fileName=""); // goes to dir "dirName" and selects file "fileName" + void addDirSelectionListener (DirSelectionListener* l) { dllisteners.push_back (l); } + void selectDir (Glib::ustring dir); +}; + +#endif diff --git a/rtgui/dirbrowserremoteinterface.h b/rtgui/dirbrowserremoteinterface.h new file mode 100644 index 000000000..7e435a93f --- /dev/null +++ b/rtgui/dirbrowserremoteinterface.h @@ -0,0 +1,31 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _DIRBROWSERREMOTEINTERFACE_ +#define _DIRBROWSERREMOTEINTERFACE_ + +#include + +class DirBrowserRemoteInterface { + + public: + virtual void selectDir (Glib::ustring dir) {} +}; + +#endif + diff --git a/rtgui/dirselectionlistener.h b/rtgui/dirselectionlistener.h new file mode 100644 index 000000000..b68238727 --- /dev/null +++ b/rtgui/dirselectionlistener.h @@ -0,0 +1,30 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _DIRSELECTIONLISTENER_ +#define _DIRSELECTIONLISTENER_ + +#include + +class DirSelectionListener { + + public: + virtual void dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile="") {} +}; + +#endif diff --git a/rtgui/distortion.cc b/rtgui/distortion.cc new file mode 100644 index 000000000..e16711181 --- /dev/null +++ b/rtgui/distortion.cc @@ -0,0 +1,83 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +Distortion::Distortion () { + + distor = Gtk::manage (new Adjuster (M("TP_DISTORTION_AMOUNT"), -0.5, 0.5, 0.001, 0)); + distor->setAdjusterListener (this); + distor->show(); + pack_start (*distor); + distAdd = false; +} + +void Distortion::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) + distor->setEditedState (pedited->distortion.amount ? Edited : UnEdited); + + distor->setValue (pp->distortion.amount); + + enableListener (); +} + +void Distortion::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->distortion.amount = distor->getValue (); + + if (pedited) + pedited->distortion.amount = distor->getEditedState (); +} + +void Distortion::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + distor->setDefault (defParams->distortion.amount); + + if (pedited) + distor->setDefaultEditedState (pedited->distortion.amount ? Edited : UnEdited); + else + distor->setDefaultEditedState (Irrelevant); +} + +void Distortion::adjusterChanged (Adjuster* a, double newval) { + + if (listener) + listener->panelChanged (EvDISTAmount, Glib::ustring::format (std::setw(4), std::fixed, std::setprecision(3), a->getValue())); +} + +void Distortion::setAdjusterBehavior (bool bvadd) { + + if (!distAdd && bvadd || distAdd && !bvadd) + distor->setLimits (-0.5, 0.5, 0.001, 0); + + distAdd = bvadd; +} + +void Distortion::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + distor->showEditedCB (); +} + diff --git a/rtgui/distortion.h b/rtgui/distortion.h new file mode 100644 index 000000000..c4160bf94 --- /dev/null +++ b/rtgui/distortion.h @@ -0,0 +1,45 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _DISTORTION_H_ +#define _DISTORTION_H_ + +#include +#include +#include + +class Distortion : public Gtk::VBox, public AdjusterListener, public ToolPanel { + + protected: + Adjuster* distor; + bool distAdd; + + public: + + Distortion (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void setAdjusterBehavior (bool bvadd); +}; + +#endif diff --git a/rtgui/editedstate.h b/rtgui/editedstate.h new file mode 100644 index 000000000..1409f1237 --- /dev/null +++ b/rtgui/editedstate.h @@ -0,0 +1,25 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _EDITEDSTATE_ +#define _EDITEDSTATE_ + +enum EditedState { UnEdited=0, Edited=1, Irrelevant=2 }; + +#endif + diff --git a/rtgui/editenums.h b/rtgui/editenums.h new file mode 100644 index 000000000..adfc1e2a5 --- /dev/null +++ b/rtgui/editenums.h @@ -0,0 +1,25 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _EDITENUMS_ +#define _EDITENUMS_ + +enum ImgEditState {SNormal, SCropMove, SHandMove, SResizeW1, SResizeW2, SResizeH1, SResizeH2, SCropSelecting, SRotateSelecting, SCropWinMove, SCropFrameMove, SCropImgMove, SCropWinResize, SObservedMove}; +enum CursorArea {CropWinButtons, CropToolBar, CropImage, CropBorder, CropTop, CropBottom, CropLeft, CropRight, CropInside, CropResize, CropObserved}; + +#endif diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc new file mode 100644 index 000000000..aba24a1e5 --- /dev/null +++ b/rtgui/editorpanel.cc @@ -0,0 +1,792 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include + +using namespace rtengine::procparams; + +EditorPanel::EditorPanel (Thumbnail* tmb, rtengine::InitialImage* isrc) : parent(NULL), beforeIarea(NULL), beforePreviewHandler(NULL), beforeIpc(NULL) { + + epih = new EditorPanelIdleHelper; + epih->epanel = this; + epih->destroyed = false; + epih->pending = 0; + +// construct toolpanelcoordinator + tpc = new ToolPanelCoordinator (); + +// build GUI + // build left side panel + leftbox = Gtk::manage (new Gtk::VBox ()); + leftbox->set_border_width (4); + + histogramPanel = Gtk::manage (new HistogramPanel ()); + histogramPanel->set_size_request (-1, 150); +// leftbox->pack_start (*histogramPanel, Gtk::PACK_SHRINK, 4); + + profilep = Gtk::manage (new ProfilePanel ()); + Gtk::Frame* ppframe = Gtk::manage (new Gtk::Frame ()); + ppframe->add (*profilep); + ppframe->set_label (M("PROFILEPANEL_LABEL")); +// leftbox->pack_start (*ppframe, Gtk::PACK_SHRINK, 4); + + navigator = Gtk::manage (new Navigator ()); + navigator->previewWindow->set_size_request (-1, 150); + leftbox->pack_start (*navigator, Gtk::PACK_SHRINK, 4); + + history = Gtk::manage (new History ()); + leftbox->pack_start (*history); + + leftbox->show_all (); + + // build the middle of the screen + Gtk::VBox* editbox = Gtk::manage (new Gtk::VBox ()); + + info = Gtk::manage (new Gtk::ToggleButton ()); + Gtk::Image* infoimg = Gtk::manage (new Gtk::Image (argv0+"/images/info.png")); + info->add (*infoimg); + info->set_relief(Gtk::RELIEF_NONE); + info->set_tooltip_text (M("MAIN_TOOLTIP_QINFO")); + + beforeAfter = Gtk::manage (new Gtk::ToggleButton (M("MAIN_TOGGLE_BEFORE_AFTER"))); + beforeAfter->set_tooltip_text (M("MAIN_TOOLTIP_TOGGLE")); + + + Gtk::VSeparator* vsept = Gtk::manage (new Gtk::VSeparator ()); + Gtk::VSeparator* vsepz = Gtk::manage (new Gtk::VSeparator ()); + Gtk::VSeparator* vsepi = Gtk::manage (new Gtk::VSeparator ()); + Gtk::VSeparator* vseph = Gtk::manage (new Gtk::VSeparator ()); + + hidehp = Gtk::manage (new Gtk::ToggleButton ()); + Gtk::Label* hidehpLabel = Gtk::manage (new Gtk::Label ()); + hidehpLabel->set_markup ("H"); + Gtk::Image* hpimg = Gtk::manage (new Gtk::Image (argv0+"/images/left.png")); + Gtk::HBox* hidehpBox = Gtk::manage (new Gtk::HBox ()); + hidehpBox->pack_start (*hpimg, Gtk::PACK_SHRINK, 2); + hidehpBox->pack_start (*hidehpLabel, Gtk::PACK_SHRINK, 2); + hidehp->add (*hidehpBox); + hidehp->set_relief(Gtk::RELIEF_NONE); + hidehp->set_active (options.showHistory); + hidehp->set_tooltip_text (M("MAIN_TOOLTIP_HIDEHP")); + + Gtk::VSeparator* vsepcl = Gtk::manage (new Gtk::VSeparator ()); + Gtk::VSeparator* vsepz2 = Gtk::manage (new Gtk::VSeparator ()); + + iarea = new ImageAreaPanel (); + + Gtk::HBox* toolBarPanel = Gtk::manage (new Gtk::HBox ()); + toolBarPanel->pack_start (*hidehp, Gtk::PACK_SHRINK, 1); + toolBarPanel->pack_start (*vseph, Gtk::PACK_SHRINK, 2); + toolBarPanel->pack_start (*info, Gtk::PACK_SHRINK, 1); + toolBarPanel->pack_start (*beforeAfter, Gtk::PACK_SHRINK, 1); + toolBarPanel->pack_start (*vsepi, Gtk::PACK_SHRINK, 2); + toolBarPanel->pack_start (*tpc->getToolBar(), Gtk::PACK_SHRINK, 1); + toolBarPanel->pack_start (*vsept, Gtk::PACK_SHRINK, 2); + toolBarPanel->pack_end (*tpc->coarse, Gtk::PACK_SHRINK, 4); + toolBarPanel->pack_end (*vsepcl, Gtk::PACK_SHRINK, 4); + toolBarPanel->pack_end (*iarea->imageArea->indClippedPanel, Gtk::PACK_SHRINK, 0); + toolBarPanel->pack_end (*vsepz, Gtk::PACK_SHRINK, 2); + + afterBox = Gtk::manage (new Gtk::VBox ()); + afterBox->pack_start (*iarea); + + beforeAfterBox = Gtk::manage (new Gtk::HBox()); + beforeAfterBox->pack_start (*afterBox); + + editbox->pack_start (*toolBarPanel, Gtk::PACK_SHRINK); + editbox->pack_start (*beforeAfterBox); + + // build right side panel + vboxright = Gtk::manage (new Gtk::VBox (false, 0)); + vboxright->set_border_width (4); + vboxright->pack_start (*histogramPanel, Gtk::PACK_SHRINK, 4); + vboxright->pack_start (*ppframe, Gtk::PACK_SHRINK, 4); + // main notebook + vboxright->pack_start (*tpc->toolPanelNotebook); + + // buttons & status + Gtk::HBox* iops = Gtk::manage (new Gtk::HBox ()); + saveimgas = Gtk::manage (new Gtk::Button (M("MAIN_BUTTON_SAVE"))); + saveimgas->set_image (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-save"), Gtk::ICON_SIZE_BUTTON))); + queueimg = Gtk::manage (new Gtk::Button (M("MAIN_BUTTON_PUTTOQUEUE"))); + queueimg->set_image (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-execute"), Gtk::ICON_SIZE_BUTTON))); + sendtogimp = Gtk::manage (new Gtk::Button (M("MAIN_BUTTON_SENDTOEDITOR"))); + sendtogimp->set_image (*Gtk::manage(new Gtk::Image (argv0+"/images/gimp.png"))); + iops->pack_start (*saveimgas, Gtk::PACK_SHRINK); + iops->pack_start (*queueimg, Gtk::PACK_SHRINK); + iops->pack_start (*sendtogimp, Gtk::PACK_SHRINK); + + statusBox = Gtk::manage (new Gtk::HBox ()); + progressLabel = Gtk::manage (new Gtk::Label("")); + statusBox->pack_start (*progressLabel); + red = new Gtk::Image (argv0+"/images/red.png"); + green = new Gtk::Image (argv0+"/images/green.png"); + red->show (); + green->show (); + statusBox->pack_end (*green, Gtk::PACK_SHRINK, 4); + iops->pack_start(*statusBox, Gtk::PACK_SHRINK, 4); + + iops->pack_end (*iarea->imageArea->zoomPanel, Gtk::PACK_SHRINK, 1); + iops->pack_end (*vsepz2, Gtk::PACK_SHRINK, 2); + + + editbox->pack_start (*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_SHRINK, 4); + editbox->pack_start (*iops, Gtk::PACK_SHRINK, 4); + editbox->show_all (); + + // build screen + hpanedl = Gtk::manage (new Gtk::HPaned()); + hpanedr = Gtk::manage (new Gtk::HPaned()); + leftbox->reference (); + vboxright->reference (); + if (options.showHistory) { + hpanedl->pack1(*leftbox, false, true); + hpanedl->set_position (options.historyPanelWidth); + } + + Gtk::Frame* vbfr = Gtk::manage (new Gtk::Frame ()); + vbfr->add (*editbox); + hpanedl->pack2(*vbfr, true, true); + + hpanedr->pack1(*hpanedl, true, true); + hpanedr->pack2(*vboxright, false, true); + + pack_start (*hpanedr); + show_all (); + + // save as dialog + if (Glib::file_test (options.lastSaveAsPath, Glib::FILE_TEST_IS_DIR)) + saveAsDialog = new SaveAsDialog (options.lastSaveAsPath); + else + saveAsDialog = new SaveAsDialog (Glib::get_user_special_dir (G_USER_DIRECTORY_PICTURES)); + + +// connect listeners + profilep->setProfileChangeListener (tpc); + history->setProfileChangeListener (tpc); + history->setHistoryBeforeLineListener (this); + tpc->addPParamsChangeListener (profilep); + tpc->addPParamsChangeListener (history); + tpc->addPParamsChangeListener (this); + iarea->imageArea->setCropGUIListener (tpc->getCropGUIListener()); + iarea->imageArea->setPointerMotionListener (navigator); + iarea->imageArea->setImageAreaToolListener (tpc); + +// initialize components + info->set_active (options.showInfo); + tpc->readOptions (); + +// connect event handlers + info->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::info_toggled) ); + beforeAfter->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::beforeAfterToggled) ); + hidehp->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::hideHistoryActivated) ); + saveimgas->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::saveAsPressed) ); + queueimg->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::queueImgPressed) ); + sendtogimp->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::sendToGimpPressed) ); + +// open image + open (tmb, isrc); +} + +bool EditorPanel::beforeClosing () { + + options.toolPanelWidth = vboxright->get_width (); + return true; +} + +EditorPanel::~EditorPanel () { + + history->setHistoryBeforeLineListener (NULL); + // the order is important! + delete iarea; + delete beforeIarea; + + if (ipc) + ipc->setPreviewImageListener (NULL); + if (beforeIpc) + beforeIpc->setPreviewImageListener (NULL); + + delete previewHandler; + delete beforePreviewHandler; + + if (ipc) + close (); + + if (epih->pending) + epih->destroyed = true; + else + delete epih; + + delete tpc; + + delete red; + delete green; + delete leftbox; + delete vboxright; + + delete saveAsDialog; +} + +void EditorPanel::on_realize () { + + Gtk::VBox::on_realize (); + vboxright->set_size_request (options.toolPanelWidth, -1); +} + +rtengine::InitialImage* EditorPanel::loadImage (Thumbnail* tmb) { + + // try to load the image + Glib::ustring filename = tmb->getFileName (); + int error; +// InitialImage* isrc = InitialImage::load (filename, tmb->getType()==FT_Raw, error, this); + ProgressDialog* pdload = new ProgressDialog (M("PROGRESSDLG_LOADING")); + rtengine::InitialImage* isrc; + pdload->setFunc (sigc::bind(sigc::ptr_fun(&rtengine::InitialImage::load), filename, tmb->getType()==FT_Raw, &error, pdload->getProgressListener()), &isrc); + pdload->start (); + delete pdload; + + if (error) + return NULL; + else + return isrc; +} + +void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) { + + // initialize everything + openThm = tmb; + openThm->increaseRef (); + + previewHandler = new PreviewHandler (); + + this->isrc = isrc; + ipc = rtengine::StagedImageProcessor::create (isrc); + ipc->setProgressListener (this); + ipc->setPreviewImageListener (previewHandler); + ipc->setPreviewScale (10); + tpc->initImage (ipc, tmb->getType()==FT_Raw); + ipc->setHistogramListener (this); + +// iarea->fitZoom (); // tell to the editorPanel that the next image has to be fitted to the screen + iarea->imageArea->setPreviewHandler (previewHandler); + iarea->imageArea->setImProcCoordinator (ipc); + navigator->previewWindow->setPreviewHandler (previewHandler); + navigator->previewWindow->setImageArea (iarea->imageArea); + + // try to load the last saved parameters from the cache or from the pp2 file + ProcParams* ldprof = NULL; + if (openThm->hasProcParams()) { + ldprof = new ProcParams (); + *ldprof = openThm->getProcParams (); + } + + // initialize profile + if (openThm->getType()!=FT_Raw) + profilep->initProfile (options.defProfImg, ldprof, NULL); + else + profilep->initProfile (options.defProfRaw, ldprof, NULL); + + openThm->addThumbnailListener (this); + info_toggled (); +} + +void EditorPanel::close () { + + saveProfile (); + + // close image processor and the current thumbnail + tpc->closeImage (); // this call stops image processing + tpc->writeOptions (); + + if (ipc) + rtengine::StagedImageProcessor::destroy (ipc); + if (beforeIpc) + rtengine::StagedImageProcessor::destroy (beforeIpc); + + openThm->removeThumbnailListener (this); + openThm->decreaseRef (); +} + +void EditorPanel::saveProfile () { + + ProcParams params; + ipc->getParams (¶ms); + + if (options.saveParamsFile) + params.save (openThm->getFileName() + ".pp2"); + if (openThm && options.saveParamsCache) + openThm->setProcParams (params, EDITOR); +} + +Glib::ustring EditorPanel::getShortName () { + + return Glib::path_get_basename (openThm->getFileName ()); +} + +Glib::ustring EditorPanel::getFileName () { + + return openThm->getFileName (); +} + +// TODO!!! +void EditorPanel::procParamsChanged (rtengine::procparams::ProcParams* params, rtengine::ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited) { + +// if (ev!=EvPhotoLoaded) +// saveLabel->set_markup (Glib::ustring("") + M("MAIN_BUTTON_SAVE") + ""); +} + +struct spsparams { + bool state; + EditorPanelIdleHelper* epih; +}; + +int setprocstate (void* data) { + + gdk_threads_enter (); + spsparams* p = (spsparams*)data; + + if (p->epih->destroyed) { + if (p->epih->pending == 1) + delete p->epih; + else + p->epih->pending--; + delete p; + gdk_threads_leave (); + return 0; + } + + p->epih->epanel->refreshProcessingState (p->state); + p->epih->pending--; + delete p; + gdk_threads_leave (); + return 0; +} + +void EditorPanel::setProgressState (int state) { + + epih->pending++; + + spsparams* p = new spsparams; + p->state = state; + p->epih = epih; + g_idle_add (setprocstate, p); +} + +void EditorPanel::refreshProcessingState (bool state) { + + // Set proc params of thumbnail. It saves it into the cache and updates the file browser. + if (ipc && openThm && !state && tpc->getChangedState()) { + rtengine::procparams::ProcParams pparams; + ipc->getParams (&pparams); + openThm->setProcParams (pparams, EDITOR, false); + } + + // change state of the led + std::vector children = (std::vector) statusBox->get_children(); + if (children.size()>=1) { + Gtk::Widget* wlast = children[children.size()-1]; + if (wlast) + statusBox->remove (*wlast); + } + if (state) + statusBox->pack_end (*red, Gtk::PACK_SHRINK, 4); + else + statusBox->pack_end (*green, Gtk::PACK_SHRINK, 4); +} + +struct errparams { + Glib::ustring descr; + EditorPanelIdleHelper* epih; +}; + +void EditorPanel::displayError (Glib::ustring descr) { + + if (parent) { + Gtk::MessageDialog* msgd = new Gtk::MessageDialog (*parent, descr, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + msgd->set_title (M("MAIN_MSG_CANNOTSAVE")); + msgd->run (); + delete msgd; + } +} + +int disperror (void* data) { + + gdk_threads_enter (); + errparams* p = (errparams*)data; + + if (p->epih->destroyed) { + if (p->epih->pending == 1) + delete p->epih; + else + p->epih->pending--; + delete p; + gdk_threads_leave (); + return 0; + } + + p->epih->epanel->displayError (p->descr); + p->epih->pending--; + delete p; + gdk_threads_leave (); + return 0; +} + +void EditorPanel::error (Glib::ustring descr) { + + epih->pending++; + errparams* p = new errparams; + p->descr = descr; + p->epih = epih; + g_idle_add (disperror, p); +} + +void EditorPanel::info_toggled () { + + Glib::ustring infoString; + + const rtengine::ImageMetaData* idata = ipc->getInitialImage()->getMetaData(); + if (idata && idata->hasExif()) + infoString = Glib::ustring::compose ("%1 %2\nF/%3 %4 sec\n%5: %6\n%7: %8 mm\n", + Glib::ustring(idata->getMake()), Glib::ustring(idata->getModel()), + Glib::ustring(idata->apertureToString(idata->getFNumber())), Glib::ustring(idata->shutterToString(idata->getShutterSpeed())), + M("QINFO_ISO"), idata->getISOSpeed(), + M("QINFO_FOCALLENGTH"), idata->getFocalLen()) + + Glib::ustring::compose ("%1: %2", M("QINFO_LENS"), Glib::ustring(idata->getLens())); + else + infoString = M("QINFO_NOEXIF"); + + iarea->imageArea->setInfoText (infoString); + iarea->imageArea->infoEnabled (info->get_active ()); +} + +void EditorPanel::hideHistoryActivated () { + + removeIfThere (hpanedl, leftbox, false); + if (hidehp->get_active()) + hpanedl->pack1 (*leftbox, false, true); +} + +bool EditorPanel::handleShortcutKey (GdkEventKey* event) { + + if (event->keyval==GDK_H || event->keyval==GDK_h) { + hidehp->set_active (!hidehp->get_active()); + return true; + } + else if ((event->keyval==GDK_Z || event->keyval==GDK_z) && event->state & GDK_CONTROL_MASK && !(event->state & GDK_SHIFT_MASK)) { + history->undo (); + return true; + } + else if ((event->keyval==GDK_Z || event->keyval==GDK_z) && event->state & GDK_CONTROL_MASK && event->state & GDK_SHIFT_MASK) { + history->redo (); + return true; + } + else if (event->keyval==GDK_w || event->keyval==GDK_W) { + tpc->getToolBar()->wb_pressed (); + return true; + } + else if (event->keyval==GDK_c || event->keyval==GDK_C) { + tpc->getToolBar()->crop_pressed (); + return true; + } + else if (event->keyval==GDK_s || event->keyval==GDK_S) { + tpc->getToolBar()->stra_pressed (); + return true; + } + else if (event->keyval==GDK_n || event->keyval==GDK_N) { + tpc->getToolBar()->hand_pressed (); + return true; + } + else + return false; +} + +void EditorPanel::procParamsChanged (Thumbnail* thm, int whoChangedIt) { + + if (whoChangedIt!=EDITOR) + tpc->profileChange (&openThm->getProcParams(), rtengine::EvProfileChangeNotification, M("PROGRESSDLG_PROFILECHANGEDINBROWSER")); +} + +rtengine::IImage16* EditorPanel::processImage () { + + rtengine::procparams::ProcParams pparams; + ipc->getParams (&pparams); + rtengine::ProcessingJob* job = rtengine::ProcessingJob::create (ipc->getInitialImage(), pparams); + int err = 0; + ProgressDialog* pdproc = new ProgressDialog (M("PROGRESSDLG_PROCESSING")); + rtengine::IImage16* img; + pdproc->setFunc (sigc::bind(sigc::ptr_fun(&rtengine::processImage), job, err, pdproc->getProgressListener()), &img); + pdproc->start (); + delete pdproc; + return img; +} + +BatchQueueEntry* EditorPanel::createBatchQueueEntry () { + + rtengine::procparams::ProcParams pparams; + ipc->getParams (&pparams); + rtengine::ProcessingJob* job = rtengine::ProcessingJob::create (ipc->getInitialImage(), pparams); + int prevh = options.maxThumbnailHeight; + int prevw = prevh; + guint8* prev = NULL;//(guint8*) previewHandler->getImagePreview (prevw, prevh); + return new BatchQueueEntry (job, pparams, openThm->getFileName(), prev, prevw, prevh, openThm); +} + +int EditorPanel::saveImage (rtengine::IImage16* img, Glib::ustring& fname, SaveFormat sf, bool findNewNameIfNeeded) { + + Glib::ustring fileName = Glib::ustring::compose ("%1.%2", fname, sf.format); + if (findNewNameIfNeeded) { + int tries = 1; + while (Glib::file_test (fileName, Glib::FILE_TEST_EXISTS) && tries<1000) { + fileName = Glib::ustring::compose("%1-%2.%3", fname, tries, sf.format); + tries++; + } + if (tries==1000) + return -1000; + } + + ProgressDialog* pdsave = new ProgressDialog (M("PROGRESSDLG_SAVING")); + img->setSaveProgressListener (pdsave->getProgressListener()); + + int err; + if (sf.format=="tif") + pdsave->setFunc (sigc::bind(sigc::mem_fun(img, &rtengine::IImage16::saveAsTIFF), fileName, sf.tiffBits), &err); + else if (sf.format=="png") + pdsave->setFunc (sigc::bind(sigc::mem_fun(img, &rtengine::IImage16::saveAsPNG), fileName, sf.pngCompression, sf.pngBits), &err); + else if (sf.format=="jpg") + pdsave->setFunc (sigc::bind(sigc::mem_fun(img, &rtengine::IImage16::saveAsJPEG), fileName, sf.jpegQuality), &err); + pdsave->start (); + delete pdsave; + + fname = fileName; + return err; +} + +void EditorPanel::saveAsPressed () { + + // obtaining short name without extension + saveAsDialog->setInitialFileName (removeExtension (Glib::path_get_basename (openThm->getFileName()))); + saveAsDialog->run (); + Glib::ustring fname = saveAsDialog->getFileName (); + if (fname=="") + return; + + SaveFormat sf = saveAsDialog->getFormat (); + if (getExtension (fname)!=sf.format) + fname = fname + "." + sf.format; + + if (saveAsDialog->getImmediately ()) { + // check if it exists + if (Glib::file_test (fname, Glib::FILE_TEST_EXISTS)) { + Glib::ustring msg_ = Glib::ustring("") + fname + ": " + M("MAIN_MSG_ALREADYEXISTS") + "\n" + M("MAIN_MSG_QOVERWRITE") + ""; + Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); + int response = msgd.run (); + if (response==Gtk::RESPONSE_NO) + return; + } + // save image + rtengine::IImage16* img = processImage (); + int err = 0; + if (img) { + fname = removeExtension (fname); + err = saveImage (img, fname, sf, false); + img->free (); + if (!err) { + openThm->imageDeveloped (); + // save processing parameters, if needed + if (sf.saveParams) { + rtengine::procparams::ProcParams pparams; + ipc->getParams (&pparams); + pparams.save (removeExtension (fname) + ".out.pp2"); + } + } + } + if (!img || err) { + Glib::ustring msg_ = Glib::ustring("") + fname + ": " + M("MAIN_MSG_ERRORDURINGIMAGESAVING") + "\n"; + Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + msgd.run (); + } + } + else { + BatchQueueEntry* bqe = createBatchQueueEntry (); + bqe->outFileName = fname; + bqe->saveFormat = saveAsDialog->getFormat (); + parent->addBatchQueueJob (bqe, saveAsDialog->getToHeadOfQueue ()); + } + // ask parent to redraw file browser + // ... or does it automatically when the tab is switched to it +} + +void EditorPanel::queueImgPressed () { + + saveProfile (); + parent->addBatchQueueJob (createBatchQueueEntry ()); +} + +void EditorPanel::sendToGimpPressed () { + + // develop image + rtengine::IImage16* img = processImage (); + if (img) { + // get file name base + Glib::ustring shortname = removeExtension (Glib::path_get_basename (openThm->getFileName())); + Glib::ustring dirname = Glib::get_tmp_dir (); + Glib::ustring filename = Glib::build_filename (dirname, shortname); + + SaveFormat sf; + sf.format = "tif"; + sf.tiffBits = 16; + int err = saveImage (img, filename, sf, true); + img->free (); + if (!err) { + bool success=false; + Glib::ustring cmdLine; + // start gimp + if (options.editorToSendTo==1) { +#ifdef _WIN32 + cmdLine = Glib::ustring("\"") + Glib::build_filename (Glib::build_filename(options.gimpDir,"bin"), "gimp-win-remote") + "\" gimp-2.4.exe" + " \"" + filename + "\""; +#else + cmdLine = Glib::ustring("gimp-remote ") + " \"" + filename + "\""; +#endif + success = safe_spawn_command_line_async (cmdLine); + if (!success){ +#ifdef _WIN32 + int ver = 12; + while (!success && ver) { + cmdLine = Glib::ustring("\"") + Glib::build_filename (Glib::build_filename(options.gimpDir,"bin"), Glib::ustring::compose("gimp-2.%1.exe",ver)) + "\" \"" + filename + "\""; + ver--; + success = safe_spawn_command_line_async (cmdLine); + } +#elif defined __APPLE__ + cmdLine = Glib::ustring("gimp ") + " \"" + filename + "\""; + success = safe_spawn_command_line_async (cmdLine); +#else + cmdLine = Glib::ustring("gimp ") + " \"" + filename + "\""; + success = safe_spawn_command_line_async (cmdLine); +#endif + } + } + else if (options.editorToSendTo==2) { +#ifdef __APPLE__ + cmdLine = Glib::ustring("open -a \'") + Glib::build_filename(options.psDir,"Photoshop.app\' ") + "\'" + filename + "\'"; +#else + cmdLine = Glib::ustring("\"") + Glib::build_filename(options.psDir,"Photoshop.exe") + "\" \"" + filename + "\""; +#endif + success = safe_spawn_command_line_async (cmdLine); + } + else if (options.editorToSendTo==3) { +#ifdef __APPLE__ + cmdLine = Glib::ustring("") + options.customEditorProg + filename; +#else + cmdLine = Glib::ustring("\"") + options.customEditorProg + "\" \"" + filename + "\""; +#endif + success = safe_spawn_command_line_async (cmdLine); + } + + if (!success) { + Gtk::MessageDialog* msgd = new Gtk::MessageDialog (*parent, M("MAIN_MSG_CANNOTSTARTEDITOR"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + msgd->set_secondary_text (M("MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY")); + msgd->set_title (M("MAIN_BUTTON_SENDTOEDITOR")); + msgd->run (); + delete msgd; + } + } + } +} + +void EditorPanel::saveOptions () { + + options.historyPanelWidth = hpanedl->get_position (); + options.toolPanelWidth = vboxright->get_width (); +} + +void EditorPanel::historyBeforeLineChanged (const rtengine::procparams::ProcParams& params) { + + if (beforeIpc) { + ProcParams* pparams = beforeIpc->getParamsForUpdate (rtengine::EvProfileChanged); + *pparams = params; + beforeIpc->paramsUpdateReady (); + } +} + +void EditorPanel::beforeAfterToggled () { + + removeIfThere (beforeAfterBox, beforeBox, false); + removeIfThere (afterBox, afterLabel, false); + + if (beforeIarea) { + if (beforeIpc) + beforeIpc->stopProcessing (); + iarea->setBeforeAfterViews (NULL, iarea); + delete beforeIarea; + beforeIarea = NULL; + if (beforeIpc) + beforeIpc->setPreviewImageListener (NULL); + delete beforePreviewHandler; + beforePreviewHandler = NULL; + if (beforeIpc) + rtengine::StagedImageProcessor::destroy (beforeIpc); + beforeIpc = NULL; + } + + if (beforeAfter->get_active ()) { + + beforeIarea = new ImageAreaPanel (); + + beforeLabel = Gtk::manage (new Gtk::Label ()); + beforeLabel->set_markup (Glib::ustring("") + M("GENERAL_BEFORE") + ""); + beforeBox = Gtk::manage (new Gtk::VBox ()); + beforeBox->pack_start (*beforeLabel, Gtk::PACK_SHRINK, 2); + beforeBox->pack_start (*beforeIarea); + + afterLabel = Gtk::manage (new Gtk::Label ()); + afterLabel->set_markup (Glib::ustring("") + M("GENERAL_AFTER") + ""); + afterBox->pack_start (*afterLabel, Gtk::PACK_SHRINK, 2); + afterBox->reorder_child (*afterLabel, 0); + + beforeAfterBox->pack_start (*beforeBox); + beforeAfterBox->reorder_child (*beforeBox, 0); + beforeAfterBox->show_all (); + + beforePreviewHandler = new PreviewHandler (); + isrc->increaseRef (); + beforeIpc = rtengine::StagedImageProcessor::create (isrc); + beforeIpc->setPreviewScale (10); + beforeIpc->setPreviewImageListener (beforePreviewHandler); + beforeIarea->imageArea->setPreviewHandler (beforePreviewHandler); + beforeIarea->imageArea->setImProcCoordinator (beforeIpc); + + iarea->setBeforeAfterViews (beforeIarea, iarea); + beforeIarea->setBeforeAfterViews (beforeIarea, iarea); + + rtengine::procparams::ProcParams params; + if (history->getBeforeLineParams (params)) + historyBeforeLineChanged (params); + } +} + +void EditorPanel::histogramChanged (unsigned int* rh, unsigned int* gh, unsigned int* bh, unsigned int* lh, unsigned int* bcrgb, unsigned int* bcl) { + + histogramPanel->histogramChanged (rh, gh, bh, lh); + tpc->updateCurveBackgroundHistogram (bcrgb, bcl); +} diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h new file mode 100644 index 000000000..e55c64bc7 --- /dev/null +++ b/rtgui/editorpanel.h @@ -0,0 +1,145 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _EDITORPANEL_ +#define _EDITORPANEL_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class EditorPanel; +struct EditorPanelIdleHelper { + EditorPanel* epanel; + bool destroyed; + int pending; +}; + +class RTWindow; +class EditorPanel : public Gtk::VBox, + public PParamsChangeListener, + public rtengine::ProgressListener, + public ThumbnailListener, + public HistoryBeforeLineListener, + public rtengine::HistogramListener { + + protected: + Gtk::Label *progressLabel; + Gtk::ToggleButton* info; + Gtk::ToggleButton* hidehp; + Gtk::ToggleButton* beforeAfter; + Gtk::HPaned* hpanedl; + Gtk::HPaned* hpanedr; + Gtk::HBox* statusBox; + Gtk::Image* red; + Gtk::Image* green; + Gtk::VBox* leftbox, *vboxright; + + Gtk::Button* queueimg; + Gtk::Button* saveimgas; + Gtk::Button* sendtogimp; + + ImageAreaPanel* iarea; + PreviewHandler* previewHandler; + PreviewHandler* beforePreviewHandler; // for the before-after view + Navigator* navigator; + ImageAreaPanel* beforeIarea; // for the before-after view + Gtk::VBox* beforeBox; + Gtk::VBox* afterBox; + Gtk::Label* beforeLabel; + Gtk::Label* afterLabel; + Gtk::HBox* beforeAfterBox; + + ProfilePanel* profilep; + History* history; + HistogramPanel* histogramPanel; + ToolPanelCoordinator* tpc; + RTWindow* parent; + SaveAsDialog* saveAsDialog; + + Thumbnail* openThm; + rtengine::InitialImage* isrc; + rtengine::StagedImageProcessor* ipc; + rtengine::StagedImageProcessor* beforeIpc; // for the before-after view + + EditorPanelIdleHelper* epih; + + void open (Thumbnail* tmb, rtengine::InitialImage* isrc); + void close (); + + rtengine::IImage16* processImage (); + BatchQueueEntry* createBatchQueueEntry (); + int saveImage (rtengine::IImage16* img, Glib::ustring& fname, SaveFormat sf, bool findNewNameIfNeeded); + + public: + + static rtengine::InitialImage* loadImage (Thumbnail* tmb); + + EditorPanel (Thumbnail* tmb, rtengine::InitialImage* isrc); + virtual ~EditorPanel (); + + bool beforeClosing (); + void on_realize (); + + void setParent (RTWindow* p) { parent = p; } + + // progresslistener interface + void setProgressState (int state); + void error (Glib::ustring descr); + void refreshProcessingState (bool state); // this is called by setProcessingState in the gtk thread + void displayError (Glib::ustring descr); // this is called by error in the gtk thread + + // PParamsChangeListener interface + void procParamsChanged (rtengine::procparams::ProcParams* params, rtengine::ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited=NULL); + + // thumbnaillistener interface + void procParamsChanged (Thumbnail* thm, int whoChangedIt); + + // HistoryBeforeLineListener + void historyBeforeLineChanged (const rtengine::procparams::ProcParams& params); + + // HistogramListener + void histogramChanged (unsigned int* rh, unsigned int* gh, unsigned int* bh, unsigned int* lh, unsigned int* bcrgb, unsigned int* bcl); + + // event handlers + void info_toggled (); + void hideHistoryActivated (); + void beforeAfterToggled (); + void saveAsPressed (); + void queueImgPressed (); + void sendToGimpPressed (); + + void saveProfile (); + Glib::ustring getShortName (); + Glib::ustring getFileName (); + bool handleShortcutKey (GdkEventKey* event); + + void saveOptions (); +}; + +#endif + diff --git a/rtgui/exiffiltersettings.cc b/rtgui/exiffiltersettings.cc new file mode 100644 index 000000000..5a5fcd856 --- /dev/null +++ b/rtgui/exiffiltersettings.cc @@ -0,0 +1,44 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include + +ExifFilterSettings::ExifFilterSettings () { + + clear (); +} + +void ExifFilterSettings::clear () { + fnumberFrom = 100; + fnumberTo = 0; + shutterFrom = 100; + shutterTo = 0; + isoFrom = 100000000; + isoTo = 0; + focalFrom = 1e8; + focalTo = 0; + lenses.clear (); + cameras.clear (); + + filterFNumber = false; + filterShutter = false; + filterFocalLen = false; + filterISO = false; + filterCamera = false; + filterLens = false; +} diff --git a/rtgui/exiffiltersettings.h b/rtgui/exiffiltersettings.h new file mode 100644 index 000000000..cfcfce8b2 --- /dev/null +++ b/rtgui/exiffiltersettings.h @@ -0,0 +1,51 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _EXIFFILTERSETTINGS_ +#define _EXIFFILTERSETTINGS_ + +#include +#include + +class ExifFilterSettings { + + public: + std::set cameras; + std::set lenses; + double fnumberFrom; + double fnumberTo; + double shutterFrom; + double shutterTo; + double focalFrom; + double focalTo; + int isoFrom; + int isoTo; + + bool filterFNumber; + bool filterShutter; + bool filterFocalLen; + bool filterISO; + bool filterCamera; + bool filterLens; + + ExifFilterSettings (); + void clear (); +}; + +#endif + diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc new file mode 100644 index 000000000..5a51eb0f3 --- /dev/null +++ b/rtgui/exifpanel.cc @@ -0,0 +1,569 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; +using namespace rtexif; +extern Glib::ustring argv0; + +ExifPanel::ExifPanel () : idata(NULL) { + + recursiveOp = true; + + exifTree = Gtk::manage(new Gtk::TreeView()); + scrolledWindow = Gtk::manage(new Gtk::ScrolledWindow()); + + exifTree->set_headers_visible(false); + exifTree->set_rules_hint(false); + exifTree->set_reorderable(false); + exifTree->set_enable_search(true); + exifTree->get_selection()->set_mode (Gtk::SELECTION_MULTIPLE); + scrolledWindow->set_border_width(2); + scrolledWindow->set_shadow_type(Gtk::SHADOW_NONE); + scrolledWindow->set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS); + scrolledWindow->property_window_placement().set_value(Gtk::CORNER_TOP_LEFT); + scrolledWindow->add(*exifTree); + + exifTreeModel = Gtk::TreeStore::create(exifColumns); + exifTree->set_model (exifTreeModel); + + delicon = safe_create_from_file (argv0+"/images/deltags.png"); + keepicon = safe_create_from_file (argv0+"/images/addtags.png"); + editicon = safe_create_from_file (argv0+"/images/logoicon16.png"); + + Gtk::TreeView::Column *viewcol = Gtk::manage(new Gtk::TreeView::Column ("Field Name")); + Gtk::CellRendererPixbuf* render_pb = Gtk::manage(new Gtk::CellRendererPixbuf ()); + Gtk::CellRendererText *render_txt = Gtk::manage(new Gtk::CellRendererText()); + viewcol->pack_start (*render_pb, false); + viewcol->pack_start (*render_txt, true); + viewcol->add_attribute (*render_pb, "pixbuf", exifColumns.icon); + viewcol->add_attribute (*render_txt, "markup", exifColumns.field); + + render_pb->property_ypad() = 0; + render_txt->property_ypad() = 0; + render_pb->property_yalign() = 0; + render_txt->property_yalign() = 0; + + exifTree->append_column (*viewcol); + + Gtk::TreeView::Column *viewcolv = Gtk::manage(new Gtk::TreeView::Column ("Value")); + Gtk::CellRendererText *render_txtv = Gtk::manage(new Gtk::CellRendererText()); + viewcolv->pack_start (*render_txtv, true); + viewcolv->add_attribute (*render_txtv, "markup", exifColumns.value); + + render_txtv->property_ypad() = 0; + + exifTree->append_column (*viewcolv); + + pack_start (*scrolledWindow); + + Gtk::HBox* buttons1 = Gtk::manage(new Gtk::HBox ()); + Gtk::HBox* buttons2 = Gtk::manage(new Gtk::HBox ()); + + remove = Gtk::manage(new Gtk::Button (M("EXIFPANEL_REMOVE"))); + remove->set_image (*Gtk::manage(new Gtk::Image (delicon))); + remove->set_tooltip_text (M("EXIFPANEL_REMOVEHINT")); + buttons1->pack_start (*remove); + + keep = Gtk::manage(new Gtk::Button (M("EXIFPANEL_KEEP"))); + keep->set_image (*Gtk::manage(new Gtk::Image (keepicon))); + keep->set_tooltip_text (M("EXIFPANEL_KEEPHINT")); + buttons1->pack_start (*keep); + + add = Gtk::manage(new Gtk::Button (M("EXIFPANEL_ADDEDIT"))); + add->set_image (*Gtk::manage(new Gtk::Image (editicon))); + add->set_tooltip_text (M("EXIFPANEL_ADDEDITHINT")); + buttons1->pack_start (*add); + + reset = Gtk::manage(new Gtk::Button (M("EXIFPANEL_RESET"))); + reset->set_image (*Gtk::manage(new Gtk::Image (Gtk::StockID ("gtk-undo"), Gtk::IconSize (2)))); + reset->set_tooltip_text (M("EXIFPANEL_RESETHINT")); + buttons2->pack_start (*reset); + + resetAll = Gtk::manage(new Gtk::Button (M("EXIFPANEL_RESETALL"))); + resetAll->set_image (*Gtk::manage(new Gtk::Image (argv0+"/images/gtk-undo-ltr.png"))); + resetAll->set_tooltip_text (M("EXIFPANEL_RESETALLHINT")); + buttons2->pack_start (*resetAll); + + pack_end (*buttons2, Gtk::PACK_SHRINK); + pack_end (*buttons1, Gtk::PACK_SHRINK); + + exifTree->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &ExifPanel::exifSelectionChanged)); + exifTree->signal_row_activated().connect(sigc::mem_fun(*this, &ExifPanel::row_activated)); + + remove->signal_clicked().connect( sigc::mem_fun(*this, &ExifPanel::removePressed) ); + keep->signal_clicked().connect( sigc::mem_fun(*this, &ExifPanel::keepPressed) ); + reset->signal_clicked().connect( sigc::mem_fun(*this, &ExifPanel::resetPressed) ); + resetAll->signal_clicked().connect( sigc::mem_fun(*this, &ExifPanel::resetAllPressed) ); + add->signal_clicked().connect( sigc::mem_fun(*this, &ExifPanel::addPressed) ); + + show_all (); +} + +ExifPanel::~ExifPanel () { +} + +void ExifPanel::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + changeList = pp->exif; + setImageData (idata); + applyChangeList (); + exifSelectionChanged (); + + enableListener (); +} + +void ExifPanel::write (ProcParams* pp, ParamsEdited* pedited) { + +// updateChangeList (); + pp->exif = changeList; +} + +void ExifPanel::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + defChangeList = defParams->exif; +} + +void ExifPanel::setImageData (const ImageMetaData* id) { + + idata = id; + exifTreeModel->clear (); + + const std::vector& defTags = ExifManager::getDefaultTIFFTags (NULL); + for (int i=0; inameToString() == "ImageWidth" || defTags[i]->nameToString() == "ImageHeight" || defTags[i]->nameToString() == "BitsPerSample") + addTag (exifTreeModel->children(), defTags[i]->nameToString(), "?", SYSTEM, false); + else + addTag (exifTreeModel->children(), defTags[i]->nameToString(), defTags[i]->valueToString(), SYSTEM, false); + + if (id && id->getExifData ()) { +// id->getExifData ()->printAll (); + addDirectory (id->getExifData (), exifTreeModel->children()); + } +} + +Gtk::TreeModel::Children ExifPanel::addTag (const Gtk::TreeModel::Children& root, Glib::ustring field, Glib::ustring value, int action, bool editable) { + + Gtk::TreeModel::Row row = *(exifTreeModel->append(root)); + row[exifColumns.action] = action; + row[exifColumns.editable] = editable; + row[exifColumns.edited] = false; + row[exifColumns.field_nopango] = field; + row[exifColumns.value_nopango] = value; + row[exifColumns.orig_value] = value; + + if (action==WRITE) + row[exifColumns.icon] = keepicon; + else if (action==DONTWRITE) + row[exifColumns.icon] = delicon; + + if (editable) { + row[exifColumns.field] = Glib::ustring("") + field + ""; + row[exifColumns.value] = Glib::ustring("") + value + ""; + } + else if (action==SYSTEM) { + row[exifColumns.field] = Glib::ustring("") + field + ""; + row[exifColumns.value] = Glib::ustring("") + value + ""; + } + else { + row[exifColumns.field] = field; + row[exifColumns.value] = value; + } + + return row.children(); +} + +void ExifPanel::addDirectory (const TagDirectory* dir, Gtk::TreeModel::Children root) { + + for (int i=0; igetCount(); i++) { + Tag* t = ((TagDirectory*)dir)->getTagByIndex (i); + if (t->getAttrib() && t->getAttrib()->action==SYSTEM) + continue; + if (t->isDirectory()) + for (int j=0; t->getDirectory(j); j++) { + Gtk::TreeModel::Children ch = addTag (root, t->nameToString (j), M("EXIFPANEL_SUBDIRECTORY"), t->getAttrib() ? t->getAttrib()->action : 0, t->getAttrib() && t->getAttrib()->editable); + addDirectory (t->getDirectory(j), ch); + } + else + addTag (root, t->nameToString (), t->valueToString (), t->getAttrib() ? t->getAttrib()->action : 0, t->getAttrib() && t->getAttrib()->editable); + } +} + +void ExifPanel::exifSelectionChanged () { + + Glib::RefPtr selection = exifTree->get_selection(); + std::vector sel = selection->get_selected_rows(); + if (sel.size()>1) { + remove->set_sensitive (1); + keep->set_sensitive (1); + reset->set_sensitive (1); + } + else if (sel.size()==1) { + Gtk::TreeModel::iterator iter = exifTreeModel->get_iter (sel[0]); + if (iter->get_value (exifColumns.action)==SYSTEM) { + remove->set_sensitive (0); + keep->set_sensitive (0); + reset->set_sensitive (0); + } + else if (iter->children().size()>0) { + remove->set_sensitive (1); + keep->set_sensitive (1); + reset->set_sensitive (1); + } + else if (iter->get_value(exifColumns.icon)==delicon) { + remove->set_sensitive (0); + keep->set_sensitive (1); + reset->set_sensitive (1); + } + else if (iter->get_value(exifColumns.icon)==keepicon || iter->get_value(exifColumns.icon)==editicon) { + keep->set_sensitive (0); + remove->set_sensitive (1); + reset->set_sensitive (1); + } + } + else { + remove->set_sensitive (0); + keep->set_sensitive (0); + reset->set_sensitive (0); + } +} + +void ExifPanel::delIt (Gtk::TreeModel::iterator iter) { + + if (!iter) + return; + + if (iter->get_value (exifColumns.action) != SYSTEM) + iter->set_value (exifColumns.icon, delicon); + if (recursiveOp) + for (Gtk::TreeModel::iterator i=iter->children().begin(); i!=iter->children().end(); i++) + delIt (i); +} + +void ExifPanel::removePressed () { + + std::vector sel = exifTree->get_selection()->get_selected_rows(); + for (int i=0; iget_iter (sel[i])); + + exifSelectionChanged (); + updateChangeList (); + notifyListener (); +} + +void ExifPanel::keepIt (Gtk::TreeModel::iterator iter) { + + if (!iter) + return; + + if (iter->get_value (exifColumns.action) != SYSTEM) + iter->set_value (exifColumns.icon, iter->get_value (exifColumns.edited) ? editicon : keepicon); + if (recursiveOp) + for (Gtk::TreeModel::iterator i=iter->children().begin(); i!=iter->children().end(); i++) + keepIt (i); +} + +void ExifPanel::keepPressed () { + + std::vector sel = exifTree->get_selection()->get_selected_rows(); + for (int i=0; iget_iter (sel[i])); + + exifSelectionChanged (); + updateChangeList (); + notifyListener (); +} + +/*void ExifPanel::resetIt (Gtk::TreeModel::iterator iter) { + + if (!iter) + return; + + if (iter->get_value (exifColumns.action)!=SYSTEM) + iter->set_value (exifColumns.icon, iter->get_value (exifColumns.action) ? keepicon : delicon); + if (iter->get_value (exifColumns.edited)) { + iter->set_value (exifColumns.value, Glib::ustring("") + iter->get_value(exifColumns.orig_value) + ""); + iter->set_value (exifColumns.value_nopango, iter->get_value(exifColumns.orig_value)); + iter->set_value (exifColumns.edited, false); + } + if (iter->get_value (exifColumns.action)==100) + exifTreeModel->erase (iter); + else + if (recursiveOp) + for (Gtk::TreeModel::iterator i=iter->children().begin(); i!=iter->children().end(); i++) + resetIt (i); +}*/ +Gtk::TreeModel::iterator ExifPanel::resetIt (Gtk::TreeModel::iterator iter) { + + if (!iter) + return iter; + + if (iter->get_value (exifColumns.action)!=SYSTEM) + iter->set_value (exifColumns.icon, iter->get_value (exifColumns.action) ? keepicon : delicon); + if (iter->get_value (exifColumns.edited)) { + iter->set_value (exifColumns.value, Glib::ustring("") + iter->get_value(exifColumns.orig_value) + ""); + iter->set_value (exifColumns.value_nopango, iter->get_value(exifColumns.orig_value)); + iter->set_value (exifColumns.edited, false); + } + if (iter->get_value (exifColumns.action)==100) { + return exifTreeModel->erase (iter); + } + else + if (recursiveOp) { + Gtk::TreeModel::iterator i = iter->children().begin(); + while (i && i != iter->children().end()) + i = resetIt (i); + } + return ++iter; +} +void ExifPanel::resetPressed () { + + std::vector sel = exifTree->get_selection()->get_selected_rows(); + for (int i=0; iget_iter (sel[i])); + + exifSelectionChanged (); + updateChangeList (); + notifyListener (); +} + +void ExifPanel::resetAllPressed () { + + setImageData (idata); + changeList = defChangeList; + applyChangeList (); + exifSelectionChanged (); + notifyListener (); +} + +void ExifPanel::addPressed () { + + Gtk::Dialog* dialog = new Gtk::Dialog (M("EXIFPANEL_ADDTAGDLG_TITLE"), *((Gtk::Window*)get_toplevel()), true, true); + dialog->add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK); + dialog->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + + Gtk::HBox* hb1 = new Gtk::HBox (); + Gtk::HBox* hb2 = new Gtk::HBox (); + + Gtk::Label* tlabel = new Gtk::Label (M("EXIFPANEL_ADDTAGDLG_SELECTTAG")+":"); + Gtk::ComboBoxText* tcombo = new Gtk::ComboBoxText (); + + tcombo->append_text ("Artist"); + tcombo->append_text ("Copyright"); + tcombo->append_text ("ImageDescription"); + tcombo->append_text ("Exif.UserComment"); + + hb1->pack_start (*tlabel, Gtk::PACK_SHRINK, 4); + hb1->pack_start (*tcombo); + + Gtk::Label* vlabel = new Gtk::Label (M("EXIFPANEL_ADDTAGDLG_ENTERVALUE")+":"); + Gtk::Entry* ventry = new Gtk::Entry (); + hb2->pack_start (*vlabel, Gtk::PACK_SHRINK, 4); + hb2->pack_start (*ventry); + + Glib::ustring sel = getSelection (true); + if (sel=="") + tcombo->set_active_text ("Exif.UserComment"); + else { + tcombo->set_active_text (sel); + if (tcombo->get_active ()<0) { + tcombo->append_text (sel); + tcombo->set_active_text (sel); + } + ventry->set_text (getSelectedValue ()); + } + + ventry->set_activates_default (true); + dialog->set_default_response (Gtk::RESPONSE_OK); + dialog->get_vbox()->pack_start (*hb1, Gtk::PACK_SHRINK); + dialog->get_vbox()->pack_start (*hb2, Gtk::PACK_SHRINK, 4); + tlabel->show (); + tcombo->show (); + vlabel->show (); + ventry->show (); + hb1->show (); + hb2->show (); + + if (dialog->run ()== Gtk::RESPONSE_OK) { + editTag (exifTreeModel->children(), tcombo->get_active_text(), ventry->get_text()); + updateChangeList (); + notifyListener (); + } + + delete dialog; + delete tlabel; + delete tcombo; + delete vlabel; + delete ventry; + delete hb1; + delete hb2; +} + +void ExifPanel::editTag (Gtk::TreeModel::Children root, Glib::ustring name, Glib::ustring value) { + + Glib::ustring::size_type dp = name.find_first_of ('.'); + Glib::ustring fseg = name.substr (0,dp); + // look up first segment of the path + Gtk::TreeModel::iterator iter; + for (iter = root.begin(); iter!=root.end(); iter++) + if (iter->get_value (exifColumns.field_nopango) == fseg) + break; + + if (iter==root.end() && value!="#keep" && value!="#delete") { + iter = exifTreeModel->append(root); + iter->set_value (exifColumns.field_nopango, fseg); + iter->set_value (exifColumns.action, 100); + if (dp==Glib::ustring::npos) { + iter->set_value (exifColumns.value, Glib::ustring("") + value + ""); + iter->set_value (exifColumns.value_nopango, value); + iter->set_value (exifColumns.orig_value, value); + iter->set_value (exifColumns.field, Glib::ustring("") + fseg + ""); + iter->set_value (exifColumns.edited, true); + iter->set_value (exifColumns.editable, true); + iter->set_value (exifColumns.icon, editicon); + } + else { + iter->set_value (exifColumns.value, Glib::ustring(M("EXIFPANEL_SUBDIRECTORY"))); + iter->set_value (exifColumns.value_nopango, Glib::ustring(M("EXIFPANEL_SUBDIRECTORY"))); + iter->set_value (exifColumns.field, fseg); + iter->set_value (exifColumns.icon, keepicon); + iter->set_value (exifColumns.orig_value, Glib::ustring(M("EXIFPANEL_SUBDIRECTORY"))); + } + } + + if (dp==Glib::ustring::npos) { + if (value=="#keep" && iter->get_value (exifColumns.action)!=SYSTEM) + iter->set_value (exifColumns.icon, iter->get_value (exifColumns.edited) ? editicon : keepicon); + else if (value=="#delete" && iter->get_value (exifColumns.action)!=SYSTEM) + iter->set_value (exifColumns.icon, delicon); + else { + iter->set_value (exifColumns.value, Glib::ustring("") + value + ""); + iter->set_value (exifColumns.value_nopango, value); + iter->set_value (exifColumns.edited, true); + iter->set_value (exifColumns.icon, editicon); + } + } + else + editTag (iter->children(), name.substr (dp+1, Glib::ustring::npos), value); +} + +Glib::ustring ExifPanel::getSelectedValue () { + + Glib::RefPtr selection = exifTree->get_selection(); + std::vector rows = selection->get_selected_rows(); + if (rows.size()!=1) + return ""; + Gtk::TreeModel::iterator iter = exifTreeModel->get_iter (rows[0]); + if (iter) + return iter->get_value (exifColumns.value_nopango); + return ""; +} + +Glib::ustring ExifPanel::getSelection (bool onlyeditable) { + + Glib::RefPtr selection = exifTree->get_selection(); + std::vector rows = selection->get_selected_rows(); + + if (rows.size()!=1) + return ""; + Gtk::TreeModel::iterator iter = exifTreeModel->get_iter (rows[0]); + + Glib::ustring ret = ""; + bool first = true; + bool editable = false; + while (iter) { + if (first) + ret = iter->get_value (exifColumns.field_nopango); + else + ret = iter->get_value (exifColumns.field_nopango) + "." + ret; + editable = iter->get_value (exifColumns.editable); + iter = iter->parent (); + first = false; + } + if (!editable && onlyeditable) + return ""; + return ret; +} + +void ExifPanel::updateChangeList (Gtk::TreeModel::Children root, std::string prefix) { + + if (prefix!="") + prefix = prefix + "."; + + Gtk::TreeModel::iterator iter; + for (iter = root.begin(); iter!=root.end(); iter++) { + if (iter->get_value (exifColumns.edited) == true) { + ExifPair ec; + ec.field = prefix + iter->get_value (exifColumns.field_nopango); + ec.value = iter->get_value (exifColumns.value_nopango); + changeList.push_back (ec); + } + else if (iter->get_value (exifColumns.action) == WRITE && iter->get_value (exifColumns.icon) == delicon) { + ExifPair ec; + ec.field = prefix + iter->get_value (exifColumns.field_nopango); + ec.value = "#delete"; + changeList.push_back (ec); + } + else if (iter->get_value (exifColumns.action) == DONTWRITE && iter->get_value (exifColumns.icon) == keepicon) { + ExifPair ec; + ec.field = prefix + iter->get_value (exifColumns.field_nopango); + ec.value = "#keep"; + changeList.push_back (ec); + } + if (iter->get_value (exifColumns.icon) == keepicon) + updateChangeList (iter->children(), prefix + iter->get_value (exifColumns.field_nopango)); + } +} + +void ExifPanel::updateChangeList () { + + changeList.clear (); + updateChangeList (exifTreeModel->children(), ""); +} + +void ExifPanel::applyChangeList () { + + for (int i=0; ichildren(), changeList[i].field, changeList[i].value); +} + +void ExifPanel::row_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column) { + + Gtk::TreeModel::iterator iter = exifTreeModel->get_iter (path); + if (iter) { + if (iter->children().size()>0) + if (exifTree->row_expanded (path)) + exifTree->collapse_row (path); + else + exifTree->expand_row (path, false); + else if (iter->get_value (exifColumns.editable)) + addPressed (); + } +} + + +void ExifPanel::notifyListener () { + + if (listener) + listener->panelChanged (EvExif, M("HISTORY_CHANGED")); +} diff --git a/rtgui/exifpanel.h b/rtgui/exifpanel.h new file mode 100644 index 000000000..54e310db0 --- /dev/null +++ b/rtgui/exifpanel.h @@ -0,0 +1,97 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _EXIFPANEL_ +#define _EXIFPANEL_ + +#include +#include + +class ExifPanel : public Gtk::VBox, public ToolPanel { + + private: + const rtengine::ImageMetaData* idata; + int fullw, fullh, cx, cy, cw, ch; + bool crenabled; + std::vector changeList; + std::vector defChangeList; + bool recursiveOp; + + class ExifColumns : public Gtk::TreeModelColumnRecord { + public: + Gtk::TreeModelColumn > icon; + Gtk::TreeModelColumn field; + Gtk::TreeModelColumn field_nopango; + Gtk::TreeModelColumn value; + Gtk::TreeModelColumn value_nopango; + Gtk::TreeModelColumn orig_value; + Gtk::TreeModelColumn action; // = 0: dont write to output, =1: write to output, =2: chagned by RT (not editable/deletable), =3: new addition + Gtk::TreeModelColumn editable; + Gtk::TreeModelColumn edited; + + ExifColumns() { add(field); add(value); add(icon); add(action); add(edited); add(field_nopango); add(value_nopango); add(editable); add(orig_value); } + }; + Glib::RefPtr delicon; + Glib::RefPtr keepicon; + Glib::RefPtr editicon; + + ExifColumns exifColumns; + Gtk::TreeView* exifTree; + Gtk::ScrolledWindow* scrolledWindow; + Glib::RefPtr exifTreeModel; + + Gtk::Button* remove; + Gtk::Button* keep; + Gtk::Button* add; + Gtk::Button* reset; + Gtk::Button* resetAll; + + Gtk::TreeModel::Children addTag (const Gtk::TreeModel::Children& root, Glib::ustring field, Glib::ustring value, int action, bool editable); + void editTag (Gtk::TreeModel::Children root, Glib::ustring name, Glib::ustring value); + void updateChangeList (Gtk::TreeModel::Children root, std::string prefix); + void addDirectory (const rtexif::TagDirectory* dir, Gtk::TreeModel::Children root); + Glib::ustring getSelection (bool onlyifeditable=false); + Glib::ustring getSelectedValue (); + void updateChangeList (); + void applyChangeList (); + void keepIt (Gtk::TreeModel::iterator iter); + void delIt (Gtk::TreeModel::iterator iter); + Gtk::TreeModel::iterator resetIt (Gtk::TreeModel::iterator iter); + public: + ExifPanel (); + virtual ~ExifPanel (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + + void setImageData (const rtengine::ImageMetaData* id); + + void exifSelectionChanged (); + void removePressed (); + void keepPressed (); + void resetPressed (); + void resetAllPressed (); + void addPressed (); + void row_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column); + + void notifyListener (); + +}; + +#endif diff --git a/rtgui/favoritbrowser.cc b/rtgui/favoritbrowser.cc new file mode 100644 index 000000000..706fbdcd8 --- /dev/null +++ b/rtgui/favoritbrowser.cc @@ -0,0 +1,113 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +FavoritBrowser::FavoritBrowser () : listener (NULL), lastSelectedDir ("") { + + scrollw = Gtk::manage (new Gtk::ScrolledWindow ()); + scrollw->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); + + Gtk::Frame* frame = Gtk::manage (new Gtk::Frame ("Favorite Folders")); + frame->add (*scrollw); + + pack_start (*frame); + + treeView = Gtk::manage (new Gtk::TreeView ()); + scrollw->add (*treeView); + + favoritModel = Gtk::ListStore::create (favoritColumns); + treeView->set_model (favoritModel); + treeView->set_headers_visible (false); + + Gtk::TreeView::Column *iviewcol = Gtk::manage (new Gtk::TreeView::Column ("icon")); + Gtk::CellRendererPixbuf *iconCR = Gtk::manage (new Gtk::CellRendererPixbuf()); + iviewcol->pack_start (*iconCR, false); + iviewcol->add_attribute (*iconCR, "gicon", 0); + + treeView->append_column (*iviewcol); + treeView->append_column ("text", favoritColumns.shortdir); + + treeView->set_tooltip_column (2); + treeView->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &FavoritBrowser::selectionChanged)); + + add = Gtk::manage (new Gtk::Button (M("MAIN_FRAME_PLACES_ADD"))); + del = Gtk::manage (new Gtk::Button (M("MAIN_FRAME_PLACES_DEL"))); + add->set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::ADD, Gtk::ICON_SIZE_MENU))); + del->set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::REMOVE, Gtk::ICON_SIZE_MENU))); + Gtk::HBox* buttonBox = Gtk::manage (new Gtk::HBox ()); + buttonBox->pack_start (*add); + buttonBox->pack_start (*del); + + pack_start (*buttonBox, Gtk::PACK_SHRINK, 2); + + add->signal_clicked().connect(sigc::mem_fun(*this, &FavoritBrowser::addPressed)); + del->signal_clicked().connect(sigc::mem_fun(*this, &FavoritBrowser::delPressed)); + + show_all (); +} + +void FavoritBrowser::selectionChanged () { + + Glib::RefPtr selection = treeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + if (iter && listener) + listener->selectDir (iter->get_value (favoritColumns.fulldir)); +} + +void FavoritBrowser::dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile) { + + lastSelectedDir = dirname; +} + +void FavoritBrowser::addPressed () { + + if (lastSelectedDir=="") + return; + + // check if the dirname is already in the list. If yes, return. + Gtk::TreeModel::iterator iter = favoritModel->children ().begin(); + while (iter != favoritModel->children().end()) { + if (iter->get_value (favoritColumns.fulldir) == lastSelectedDir) + return; + iter++; + } + + Glib::RefPtr hfile = Gio::File::create_for_parse_name (lastSelectedDir); + if (hfile) { + Glib::RefPtr info = hfile->query_info (); + if (info) { + Gtk::TreeModel::Row newrow = *(favoritModel->append()); + newrow[favoritColumns.shortdir] = info->get_display_name (); + newrow[favoritColumns.fulldir] = lastSelectedDir; + newrow[favoritColumns.icon] = info->get_icon (); + } + } +} + +void FavoritBrowser::delPressed () { + + // lookup the selected item in the bookmark + Glib::RefPtr selection = treeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + + if (iter) + favoritModel->erase (iter); +} + diff --git a/rtgui/favoritbrowser.h b/rtgui/favoritbrowser.h new file mode 100644 index 000000000..b50cc5cba --- /dev/null +++ b/rtgui/favoritbrowser.h @@ -0,0 +1,58 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _FAVORITBROWSER_ +#define _FAVORITBROWSER_ + +#include +#include +#include + +class FavoritBrowser : public Gtk::VBox, public DirSelectionListener { + + class FavoritColumns : public Gtk::TreeModel::ColumnRecord { + public: + Gtk::TreeModelColumn > icon; + Gtk::TreeModelColumn shortdir; + Gtk::TreeModelColumn fulldir; + FavoritColumns() { add(icon); add(shortdir), add(fulldir); } + }; + + FavoritColumns favoritColumns; + Gtk::ScrolledWindow* scrollw; + Gtk::TreeView* treeView; + Glib::RefPtr favoritModel; + DirBrowserRemoteInterface* listener; + Glib::ustring lastSelectedDir; + Gtk::Button* add; + Gtk::Button* del; + public: + + FavoritBrowser (); + + void setDirBrowserRemoteInterface (DirBrowserRemoteInterface* l) { listener = l; } + void dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile=""); + + void addPressed (); + void delPressed (); + void selectionChanged (); +}; + +#endif + + diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc new file mode 100644 index 000000000..3298cd32c --- /dev/null +++ b/rtgui/filebrowser.cc @@ -0,0 +1,586 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include + +FileBrowser::FileBrowser () + : tbl(NULL) { + + fbih = new FileBrowserIdleHelper; + fbih->fbrowser = this; + fbih->destroyed = false; + fbih->pending = 0; + + profileStore.parseProfiles (); + + signal_style_changed().connect( sigc::mem_fun(*this, &FileBrowser::styleChanged) ); + + int p = 0; + pmenu = new Gtk::Menu (); + pmenu->attach (*(open = new Gtk::MenuItem (M("FILEBROWSER_POPUPOPEN"))), 0, 1, p, p+1); p++; + pmenu->attach (*(develop = new Gtk::MenuItem (M("FILEBROWSER_POPUPPROCESS"))), 0, 1, p, p+1); p++; + pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + pmenu->attach (*(rank[0] = new Gtk::MenuItem (M("FILEBROWSER_POPUPUNRANK"))), 0, 1, p, p+1); p++; + pmenu->attach (*(rank[1] = new Gtk::MenuItem (M("FILEBROWSER_POPUPRANK1"))), 0, 1, p, p+1); p++; + pmenu->attach (*(rank[2] = new Gtk::MenuItem (M("FILEBROWSER_POPUPRANK2"))), 0, 1, p, p+1); p++; + pmenu->attach (*(rank[3] = new Gtk::MenuItem (M("FILEBROWSER_POPUPRANK3"))), 0, 1, p, p+1); p++; + pmenu->attach (*(rank[4] = new Gtk::MenuItem (M("FILEBROWSER_POPUPRANK4"))), 0, 1, p, p+1); p++; + pmenu->attach (*(rank[5] = new Gtk::MenuItem (M("FILEBROWSER_POPUPRANK5"))), 0, 1, p, p+1); p++; + pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + pmenu->attach (*(trash = new Gtk::MenuItem (M("FILEBROWSER_POPUPTRASH"))), 0, 1, p, p+1); p++; + pmenu->attach (*(untrash = new Gtk::MenuItem (M("FILEBROWSER_POPUPUNTRASH"))), 0, 1, p, p+1); p++; + pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + pmenu->attach (*(rename = new Gtk::MenuItem (M("FILEBROWSER_POPUPRENAME"))), 0, 1, p, p+1); p++; + pmenu->attach (*(remove = new Gtk::MenuItem (M("FILEBROWSER_POPUPREMOVE"))), 0, 1, p, p+1); p++; + pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + pmenu->attach (*(selall = new Gtk::MenuItem (M("FILEBROWSER_POPUPSELECTALL"))), 0, 1, p, p+1); p++; + pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + pmenu->attach (*(copyprof = new Gtk::MenuItem (M("FILEBROWSER_COPYPROFILE"))), 0, 1, p, p+1); p++; + pmenu->attach (*(pasteprof = new Gtk::MenuItem (M("FILEBROWSER_PASTEPROFILE"))), 0, 1, p, p+1); p++; + pmenu->attach (*(partpasteprof = new Gtk::MenuItem (M("FILEBROWSER_PARTIALPASTEPROFILE"))), 0, 1, p, p+1); p++; + pmenu->attach (*(applyprof = new Gtk::MenuItem (M("FILEBROWSER_APPLYPROFILE"))), 0, 1, p, p+1); p++; + pmenu->attach (*(clearprof = new Gtk::MenuItem (M("FILEBROWSER_CLEARPROFILE"))), 0, 1, p, p+1); p++; + pmenu->show_all (); + + pmaccelgroup = Gtk::AccelGroup::create (); + pmenu->set_accel_group (pmaccelgroup); + selall->add_accelerator ("activate", pmenu->get_accel_group(), GDK_a, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); + trash->add_accelerator ("activate", pmenu->get_accel_group(), GDK_Delete, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); + untrash->add_accelerator ("activate", pmenu->get_accel_group(), GDK_Delete, Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE); + develop->add_accelerator ("activate", pmenu->get_accel_group(), GDK_Q, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); + copyprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_C, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); + pasteprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_V, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); + partpasteprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_V, Gdk::CONTROL_MASK | Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE); + + profmenu = new Gtk::Menu (); + + open->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), open)); + for (int i=0; i<6; i++) + rank[i]->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), rank[i])); + trash->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), trash)); + untrash->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), untrash)); + develop->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), develop)); + rename->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), rename)); + remove->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), remove)); + selall->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), selall)); + copyprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), copyprof)); + pasteprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), pasteprof)); + partpasteprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), partpasteprof)); + applyprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), applyprof)); + clearprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), clearprof)); +} + +void FileBrowser::rightClicked (ThumbBrowserEntryBase* entry) { + + trash->set_sensitive (false); + untrash->set_sensitive (false); + for (int i=0; ithumbnail->getStage()==1) { + untrash->set_sensitive (true); + break; + } + for (int i=0; ithumbnail->getStage()==0) { + trash->set_sensitive (true); + break; + } + + pasteprof->set_sensitive (clipboard.hasProcParams()); + partpasteprof->set_sensitive (clipboard.hasProcParams()); + copyprof->set_sensitive (selected.size()==1); + clearprof->set_sensitive (selected.size()>0); + + int p = 0; + Gtk::Menu* applmenu = Gtk::manage (new Gtk::Menu ()); + std::vector profnames = profileStore.getProfileNames (); + for (int i=0; iattach (*mi, 0, 1, p, p+1); p++; + mi->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::applyMenuItemActivated), profnames[i])); + mi->show (); + } + applyprof->set_submenu (*applmenu); + + pmenu->popup (3, this->eventTime); +} + +void FileBrowser::doubleClicked (ThumbBrowserEntryBase* entry) { + + if (tbl && entry) { + std::vector entries; + entries.push_back (((FileBrowserEntry*)entry)->thumbnail); + tbl->openRequested (entries); + } +} + +struct addparams { + FileBrowserIdleHelper* fbih; + FileBrowserEntry* entry; +}; + +int addfl (void* data) { + + addparams* ap = (addparams*) data; + FileBrowserIdleHelper* fbih = ap->fbih; + + gdk_threads_enter(); + + if (fbih->destroyed) { + if (fbih->pending == 1) + delete fbih; + else + fbih->pending--; + delete ap->entry; + delete ap; + gdk_threads_leave (); + return 0; + } + + ap->fbih->fbrowser->addEntry_ (ap->entry); + delete ap; + fbih->pending--; + gdk_threads_leave(); + return 0; +} + +void FileBrowser::addEntry (FileBrowserEntry* entry) { + + fbih->pending++; + entry->setParent (this); + addparams* ap = new addparams; + ap->fbih = fbih; + ap->entry = entry; + g_idle_add (addfl, ap); +} + +void FileBrowser::addEntry_ (FileBrowserEntry* entry) { + + entry->selected = false; + entry->drawable = false; + entry->framed = editedFiles.find (entry->filename)!=editedFiles.end(); + + // add button set to the thumbbrowserentry + entry->addButtonSet (new FileThumbnailButtonSet (entry)); + entry->getThumbButtonSet()->setRank (entry->thumbnail->getRank()); + entry->getThumbButtonSet()->setInTrash (entry->thumbnail->getStage()==1); + entry->getThumbButtonSet()->setButtonListener (this); + entry->resize (options.thumbSize); + + // find place in abc order + std::vector::iterator i = fd.begin(); + while (i!=fd.end() && *entry < *((FileBrowserEntry*)*i)) + i++; + + fd.insert (i, entry); + + initEntry (entry); + redraw (); +} + +FileBrowserEntry* FileBrowser::delEntry (const Glib::ustring& fname) { + + for (std::vector::iterator i=fd.begin(); i!=fd.end(); i++) + if ((*i)->filename==fname) { + ThumbBrowserEntryBase* entry = *i; + entry->selected = false; + fd.erase (i); + std::vector::iterator j = std::find (selected.begin(), selected.end(), entry); + if (j!=selected.end()) { + selected.erase (j); + notifySelectionListener (); + } + if (lastClicked==entry) + lastClicked = NULL; + redraw (); + return (FileBrowserEntry*)entry; + } + return NULL; +} + +FileBrowserEntry* FileBrowser::findEntry (const Glib::ustring& fname) { + + for (std::vector::iterator i=fd.begin(); i!=fd.end(); i++) + if ((*i)->filename==fname) + return (FileBrowserEntry*)*i; + return NULL; +} + +void FileBrowser::close () { + if (fbih->pending) + fbih->destroyed = true; + else + delete fbih; + + fbih = new FileBrowserIdleHelper; + fbih->fbrowser = this; + fbih->destroyed = false; + fbih->pending = 0; + + for (int i=0; ithumbnail->decreaseRef (); +} + +void FileBrowser::menuItemActivated (Gtk::MenuItem* m) { + + std::vector mselected; + for (int i=0; i entries; + for (int i=0; ithumbnail); + tbl->openRequested (entries); + } + else if (m==remove) + tbl->deleteRequested (mselected); + else if (m==trash) + toTrashRequested (mselected); + else if (m==untrash) + fromTrashRequested (mselected); + else if (m==develop) + tbl->developRequested (mselected); + else if (m==rename) + tbl->renameRequested (mselected); + else if (m==selall) { + lastClicked = NULL; + selected.clear (); + for (int i=0; iselected = true; + selected.push_back (fd[i]); + } + queue_draw (); + notifySelectionListener (); + } + else if (m==copyprof) + copyProfile (); + else if (m==pasteprof) + pasteProfile (); + else if (m==partpasteprof) + partPasteProfile (); + else if (m==clearprof) { + for (int i=0; ithumbnail->clearProcParams (FILEBROWSER); + queue_draw (); + } +} + +void FileBrowser::copyProfile () { + + if (selected.size()==1) + clipboard.setProcParams (((FileBrowserEntry*)selected[0])->thumbnail->getProcParams()); +} + +void FileBrowser::pasteProfile () { + + std::vector mselected; + for (int i=0; ithumbnail->setProcParams (clipboard.getProcParams(), FILEBROWSER); + + queue_draw (); +} + +void FileBrowser::partPasteProfile () { + + std::vector mselected; + for (int i=0; ithumbnail->getProcParams (); + partialPasteDlg.applyPaste (¶ms, &clipboard.getProcParams()); + mselected[i]->thumbnail->setProcParams (params, FILEBROWSER); + } + + queue_draw (); + } + partialPasteDlg.hide (); +} + +bool FileBrowser::keyPressed (GdkEventKey* event) { + + if ((event->keyval==GDK_C || event->keyval==GDK_c) && event->state & GDK_CONTROL_MASK) { + copyProfile (); + return true; + } + else if ((event->keyval==GDK_V || event->keyval==GDK_v) && event->state & GDK_CONTROL_MASK && !(event->state & GDK_SHIFT_MASK)) { + pasteProfile (); + return true; + } + else if ((event->keyval==GDK_V || event->keyval==GDK_v) && event->state & GDK_CONTROL_MASK && event->state & GDK_SHIFT_MASK) { + partPasteProfile (); + return true; + } + else if (event->keyval==GDK_Delete && !(event->state & GDK_SHIFT_MASK)) { + menuItemActivated (trash); + return true; + } + else if (event->keyval==GDK_Delete && event->state & GDK_SHIFT_MASK) { + menuItemActivated (untrash); + return true; + } + else if ((event->keyval==GDK_Q || event->keyval==GDK_q) && event->state & GDK_CONTROL_MASK) { + menuItemActivated (develop); + return true; + } + else if ((event->keyval==GDK_A || event->keyval==GDK_a) && event->state & GDK_CONTROL_MASK) { + menuItemActivated (selall); + return true; + } + + return false; +} + +void FileBrowser::applyMenuItemActivated (Glib::ustring ppname) { + + rtengine::procparams::ProcParams* pparams = profileStore.getProfile (ppname); + if (pparams && selected.size()>0) { + for (int i=0; ithumbnail->setProcParams (*pparams, FILEBROWSER); + queue_draw (); + } +} + +void FileBrowser::applyFilter (const BrowserFilter& filter) { + + this->filter = filter; + + // remove items not complying the filter from the selection + bool selchanged = false; + for (int i=0; iselected && !checkFilter (fd[i])) { + fd[i]->selected = false; + std::vector::iterator j = std::find (selected.begin(), selected.end(), fd[i]); + selected.erase (j); + if (lastClicked==fd[i]) + lastClicked = NULL; + selchanged = true; + } + if (selchanged) + notifySelectionListener (); + redraw (); +} + +bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) { // true -> entry complies filter + + FileBrowserEntry* entry = (FileBrowserEntry*)entryb; + // return false if basic filter settings are not satisfied + if (filter.showRanked[entry->thumbnail->getRank()]==false || (entry->thumbnail->getStage()==1 && !filter.showTrash) || (entry->thumbnail->getStage()==0 && !filter.showNotTrash)) + return false; + + // check exif filter + const CacheImageData* cfs = entry->thumbnail->getCacheImageData(); + double tol = 0.01; + double tol2 = 1e-8; + + if (!filter.exifFilterEnabled) + return true; + + if (!cfs->exifValid) + return (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(cfs->camera)>0) + && (!filter.exifFilter.filterLens || filter.exifFilter.lenses.count(cfs->lens)>0); + + return + (!filter.exifFilter.filterShutter || (rtengine::ImageMetaData::shutterFromString(rtengine::ImageMetaData::shutterToString(cfs->shutter)) >= filter.exifFilter.shutterFrom-tol2 && rtengine::ImageMetaData::shutterFromString(rtengine::ImageMetaData::shutterToString(cfs->shutter)) <= filter.exifFilter.shutterTo+tol2)) + && (!filter.exifFilter.filterFNumber || (rtengine::ImageMetaData::apertureFromString(rtengine::ImageMetaData::apertureToString(cfs->fnumber)) >= filter.exifFilter.fnumberFrom-tol2 && rtengine::ImageMetaData::apertureFromString(rtengine::ImageMetaData::apertureToString(cfs->fnumber)) <= filter.exifFilter.fnumberTo+tol2)) + && (!filter.exifFilter.filterFocalLen || (cfs->focalLen >= filter.exifFilter.focalFrom-tol && cfs->focalLen <= filter.exifFilter.focalTo+tol)) + && (!filter.exifFilter.filterISO || (cfs->iso >= filter.exifFilter.isoFrom && cfs->iso <= filter.exifFilter.isoTo)) + && (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(cfs->camera)>0) + && (!filter.exifFilter.filterLens || filter.exifFilter.lenses.count(cfs->lens)>0); +} + +void FileBrowser::toTrashRequested (std::vector tbe) { + + for (int i=0; ithumbnail->getStage()==1) + continue; + tbe[i]->thumbnail->setStage (1); + if (tbe[i]->getThumbButtonSet()) { + tbe[i]->getThumbButtonSet()->setRank (tbe[i]->thumbnail->getRank()); + tbe[i]->getThumbButtonSet()->setInTrash (true); + } + } + trash_changed().emit(); + applyFilter (filter); +} + +void FileBrowser::fromTrashRequested (std::vector tbe) { + + for (int i=0; ithumbnail->getStage()==0) + continue; + tbe[i]->thumbnail->setStage (0); + if (tbe[i]->getThumbButtonSet()) { + tbe[i]->getThumbButtonSet()->setRank (tbe[i]->thumbnail->getRank()); + tbe[i]->getThumbButtonSet()->setInTrash (false); + } + } + trash_changed().emit(); + applyFilter (filter); +} + +void FileBrowser::rankingRequested (std::vector tbe, int rank) { + + for (int i=0; ithumbnail->setRank (rank); + if (tbe[i]->getThumbButtonSet()) + tbe[i]->getThumbButtonSet()->setRank (tbe[i]->thumbnail->getRank()); + } + applyFilter (filter); +} + +void FileBrowser::buttonPressed (LWButton* button, int actionCode, void* actionData) { + + if (actionCode>=0 && actionCode<=5) { // rank + std::vector tbe; + tbe.push_back ((FileBrowserEntry*)actionData); + rankingRequested (tbe, actionCode); + } + else if (actionCode==6 && tbl) { // to processin queue + std::vector tbe; + tbe.push_back ((FileBrowserEntry*)actionData); + tbl->developRequested (tbe); + } + else if (actionCode==7) { // to trash / undelete + std::vector tbe; + FileBrowserEntry* entry = (FileBrowserEntry*)actionData; + tbe.push_back (entry); + if (entry->thumbnail->getStage()==0) + toTrashRequested (tbe); + else + fromTrashRequested (tbe); + } +} + +void FileBrowser::openNextImage () { + + if (fd.size()>0) { + for (int i=fd.size()-1; i>=0; i--) + if (editedFiles.find (fd[i]->filename)!=editedFiles.end()) + if (i entries; + entries.push_back (((FileBrowserEntry*)fd[i+1])->thumbnail); + tbl->openRequested (entries); + return; + } + if (tbl) { + std::vector entries; + entries.push_back (((FileBrowserEntry*)fd[0])->thumbnail); + tbl->openRequested (entries); + } + } +} + +void FileBrowser::openPrevImage () { + + if (fd.size()>0) { + for (int i=0; ifilename)!=editedFiles.end()) + if (i>0 && tbl) { + std::vector entries; + entries.push_back (((FileBrowserEntry*)fd[i-1])->thumbnail); + tbl->openRequested (entries); + return; + } + if (tbl) { + std::vector entries; + entries.push_back (((FileBrowserEntry*)fd[fd.size()-1])->thumbnail); + tbl->openRequested (entries); + } + } +} + +int redrawtb (void* data) { + + ((FileBrowser*)data)->_thumbRearrangementNeeded (); + return 0; +} + +void FileBrowser::_thumbRearrangementNeeded () { + + refreshThumbImages (); +} + +void FileBrowser::thumbRearrangementNeeded () { + + g_idle_add (redrawtb, this); +} +void FileBrowser::selectionChanged () { + + notifySelectionListener (); +} + +void FileBrowser::notifySelectionListener () { + + if (tbl) { + std::vector thm; + for (int i=0; ithumbnail); + tbl->selectionChanged (thm); + } +} + +void FileBrowser::redrawNeeded (ThumbBrowserEntryBase* entry) { + + if (entry->insideWindow (0, 0, internal.get_width(), internal.get_height())) { + if (!internal.isDirty ()) { + internal.setDirty (); + internal.queue_draw (); + } + } +} + +void FileBrowser::redrawNeeded (LWButton* button) { + + queue_draw (); +} +FileBrowser::type_trash_changed FileBrowser::trash_changed () { + return m_trash_changed; +} diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h new file mode 100644 index 000000000..8b3e99a6d --- /dev/null +++ b/rtgui/filebrowser.h @@ -0,0 +1,122 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _FILEBROWSER_ +#define _FILEBROWSER_ + +#include +#include +#include +#include +#include +#include + +class FileBrowser; +class FileBrowserEntry; +class FileBrowserListener { + + public: + virtual void openRequested (std::vector tbe) {} + virtual void developRequested (std::vector tbe) {} + virtual void renameRequested (std::vector tbe) {} + virtual void deleteRequested (std::vector tbe) {} + virtual void selectionChanged (std::vector tbe) {} +}; + +struct FileBrowserIdleHelper { + FileBrowser* fbrowser; + bool destroyed; + int pending; +}; + +class FileBrowser : public ThumbBrowserBase, public LWButtonListener { + + typedef sigc::signal type_trash_changed; + + protected: + + Gtk::MenuItem* rank[6]; + Gtk::MenuItem* trash; + Gtk::MenuItem* untrash; + Gtk::MenuItem* develop; + Gtk::MenuItem* rename; + Gtk::MenuItem* remove; + Gtk::MenuItem* open; + Gtk::MenuItem* selall; + Gtk::MenuItem* copyprof; + Gtk::MenuItem* pasteprof; + Gtk::MenuItem* partpasteprof; + Gtk::MenuItem* applyprof; + Gtk::MenuItem* clearprof; + Gtk::Menu* pmenu; + Gtk::Menu* profmenu; + Glib::RefPtr pmaccelgroup; + + FileBrowserListener* tbl; + BrowserFilter filter; + PartialPasteDlg partialPasteDlg; + + FileBrowserIdleHelper* fbih; + + void toTrashRequested (std::vector tbe); + void fromTrashRequested (std::vector tbe); + void rankingRequested (std::vector tbe, int rank); + void notifySelectionListener (); + + type_trash_changed m_trash_changed; + + public: + + FileBrowser (); + + void addEntry (FileBrowserEntry* entry); // can be called from any thread + void addEntry_ (FileBrowserEntry* entry); // this must be executed inside the gtk thread + FileBrowserEntry* delEntry (const Glib::ustring& fname); // return the entry if found here return NULL otherwise + FileBrowserEntry* findEntry (const Glib::ustring& fname); // return the entry if found here return NULL otherwise + void close (); + + void setFileBrowserListener (FileBrowserListener* l) { tbl = l; } + + void menuItemActivated (Gtk::MenuItem* m); + void applyMenuItemActivated (Glib::ustring ppname); + + void applyFilter (const BrowserFilter& filter); + + void buttonPressed (LWButton* button, int actionCode, void* actionData); + void redrawNeeded (LWButton* button); + bool checkFilter (ThumbBrowserEntryBase* entry); + void rightClicked (ThumbBrowserEntryBase* entry); + void doubleClicked (ThumbBrowserEntryBase* entry); + bool keyPressed (GdkEventKey* event); + + void openNextImage (); + void openPrevImage (); + void copyProfile (); + void pasteProfile (); + void partPasteProfile (); + + void redrawNeeded (ThumbBrowserEntryBase* entry); + void thumbRearrangementNeeded (); + void _thumbRearrangementNeeded (); + + void selectionChanged (); + + type_trash_changed trash_changed(); +}; + +#endif diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc new file mode 100644 index 000000000..7b955c00b --- /dev/null +++ b/rtgui/filebrowserentry.cc @@ -0,0 +1,558 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include +#include + +#define CROPRESIZEBORDER 4 + +bool FileBrowserEntry::iconsLoaded = false; +Glib::RefPtr FileBrowserEntry::editedIcon; +Glib::RefPtr FileBrowserEntry::recentlySavedIcon; +Glib::RefPtr FileBrowserEntry::enqueuedIcon; + +FileBrowserEntry::FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname) + : ThumbBrowserEntryBase (fname), thumbnail(thm), iatlistener(NULL), state(SNormal), cropgl(NULL) { + + feih = new FileBrowserEntryIdleHelper; + feih->fbentry = this; + feih->destroyed = false; + feih->pending = 0; + + italicstyle = thumbnail->getType() != FT_Raw; + datetimeline = thumbnail->getDateTimeString (); + exifline = thumbnail->getExifString (); + + scale = 1; + + if (!iconsLoaded) { + editedIcon = safe_create_from_file (argv0+"/images/edited.png"); + recentlySavedIcon = safe_create_from_file (argv0+"/images/saved.png"); + enqueuedIcon = safe_create_from_file (argv0+"/images/processing.png"); + } + + if (thm) + thm->addThumbnailListener (this); +} + +FileBrowserEntry::~FileBrowserEntry () { + + thumbImageUpdater.removeJobs (this); + if (thumbnail) + thumbnail->removeThumbnailListener (this); + + if (feih->pending) + feih->destroyed = true; + else + delete feih; +} + +void FileBrowserEntry::refreshThumbnailImage () { + + if (!thumbnail) + return; + + thumbImageUpdater.add (thumbnail, thumbnail->getProcParams(), preh, &updatepriority, this); + thumbImageUpdater.process (); +} + +void FileBrowserEntry::calcThumbnailSize () { + + if (thumbnail) + thumbnail->getThumbnailSize (prew, preh); +} + +std::vector > FileBrowserEntry::getIconsOnImageArea () { + + std::vector > ret; + + if (!thumbnail) + return ret; + + if (thumbnail->hasProcParams() && editedIcon) + ret.push_back (editedIcon); + if (thumbnail->isRecentlySaved() && recentlySavedIcon) + ret.push_back (recentlySavedIcon); + if (thumbnail->isEnqueued () && enqueuedIcon) + ret.push_back (enqueuedIcon); + + return ret; +} + +void FileBrowserEntry::customBackBufferUpdate (Cairo::RefPtr c) { + + if (state==SCropSelecting || state==SResizeH1 || state==SResizeH2 || state==SResizeW1 || state==SResizeW2 || state==SCropMove) + drawCrop (c, prex, prey, prew, preh, 0, 0, scale, cropParams); + else { + rtengine::procparams::CropParams cparams = thumbnail->getProcParams().crop; + if (cparams.enabled) + drawCrop (c, prex, prey, prew, preh, 0, 0, scale, cparams); + } +} + +void FileBrowserEntry::getIconSize (int& w, int& h) { + + w = editedIcon->get_width (); + h = editedIcon->get_height (); +} + +FileThumbnailButtonSet* FileBrowserEntry::getThumbButtonSet () { + + return (FileThumbnailButtonSet*)buttonSet; +} + +void FileBrowserEntry::procParamsChanged (Thumbnail* thm, int whoChangedIt) { + + refreshThumbnailImage (); +} + +struct tiupdate { + FileBrowserEntryIdleHelper* feih; + rtengine::IImage8* img; + double scale; + rtengine::procparams::CropParams cropParams; +}; + +int fbeupdate (void* data) { + + gdk_threads_enter (); + tiupdate* params = (tiupdate*)data; + FileBrowserEntryIdleHelper* feih = params->feih; + + if (feih->destroyed) { + if (feih->pending == 1) + delete feih; + else + feih->pending--; + params->img->free (); + delete params; + gdk_threads_leave (); + return 0; + } + + feih->fbentry->_updateImage (params->img, params->scale, params->cropParams); + feih->pending--; + + gdk_threads_leave (); + delete params; + + return 0; +} + +void FileBrowserEntry::updateImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cropParams) { + + redrawRequests++; + feih->pending++; + tiupdate* param = new tiupdate (); + param->feih = feih; + param->img = img; + param->scale = scale; + param->cropParams = cropParams; + g_idle_add (fbeupdate, param); +} + +void FileBrowserEntry::_updateImage (rtengine::IImage8* img, double s, rtengine::procparams::CropParams cropParams) { + + redrawRequests--; + scale = s; + this->cropParams = cropParams; + if (preh == img->getHeight ()) { + prew = img->getWidth (); + guint8* temp = preview; + preview = NULL; + delete [] temp; + temp = new guint8 [prew*preh*3]; + memcpy (temp, img->getData(), prew*preh*3); + preview = temp; + updateBackBuffer (); + } + if (redrawRequests==0 && parent) + parent->redrawNeeded (this); + img->free (); +} + +bool FileBrowserEntry::motionNotify (int x, int y) { + + bool b = ThumbBrowserEntryBase::motionNotify (x, y); + + int ix = x - startx - ofsX; + int iy = y - starty - ofsY; + + if (inside (x,y)) + updateCursor (ix, iy); + + if (state==SRotateSelecting) { + action_x = x; + action_y = y; + parent->redrawNeeded (this); + } + else if (state==SResizeH1 && cropgl) { + int oy = cropParams.y; + cropParams.y = action_y + (y-press_y) / scale; + cropParams.h += oy - cropParams.y; + cropgl->cropHeight1Resized (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + updateBackBuffer (); + parent->redrawNeeded (this); + } + else if (state==SResizeH2 && cropgl) { + cropParams.h = action_y + (y-press_y) / scale; + cropgl->cropHeight2Resized (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + updateBackBuffer (); + parent->redrawNeeded (this); + } + else if (state==SResizeW1 && cropgl) { + int ox = cropParams.x; + cropParams.x = action_x + (x-press_x) / scale; + cropParams.w += ox - cropParams.x; + cropgl->cropWidth1Resized (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + updateBackBuffer (); + parent->redrawNeeded (this); + } + else if (state==SResizeW2 && cropgl) { + cropParams.w = action_x + (x-press_x) / scale; + cropgl->cropWidth2Resized (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + updateBackBuffer (); + parent->redrawNeeded (this); + } + else if (state==SCropMove && cropgl) { + cropParams.x = action_x + (x-press_x) / scale; + cropParams.y = action_y + (y-press_y) / scale; + cropgl->cropMoved (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + updateBackBuffer (); + parent->redrawNeeded (this); + } + else if (state==SCropSelecting && cropgl) { + int cx1 = press_x, cy1 = press_y; + int cx2 = (ix-prex) / scale, cy2 = (iy-prey) / scale; + cropgl->cropResized (cx1, cy1, cx2, cy2); + if (cx2 > cx1) { + cropParams.x = cx1; + cropParams.w = cx2 - cx1 + 1; + } + else { + cropParams.x = cx2; + cropParams.w = cx1 - cx2 + 1; + } + if (cy2 > cy1) { + cropParams.y = cy1; + cropParams.h = cy2 - cy1 + 1; + } + else { + cropParams.y = cy2; + cropParams.h = cy1 - cy2 + 1; + } + updateBackBuffer (); + parent->redrawNeeded (this); + } + + return b; +} + +bool FileBrowserEntry::pressNotify (int button, int type, int bstate, int x, int y) { + + bool b = ThumbBrowserEntryBase::pressNotify (button, type, bstate, x, y); + + ToolMode tm = iatlistener->getToolBar()->getTool (); + int ix = x - startx - ofsX; + int iy = y - starty - ofsY; + if (!b && selected && inside (x,y)) { + if (button==1 && type==GDK_BUTTON_PRESS && state==SNormal) { + if (onArea (CropTop, ix, iy)) { + state = SResizeH1; + press_y = y; + action_y = cropParams.y; + cropgl = iatlistener->startCropEditing (thumbnail); + b = true; + } + else if (onArea (CropBottom, ix, iy)) { + state = SResizeH2; + press_y = y; + action_y = cropParams.h; + cropgl = iatlistener->startCropEditing (thumbnail); + b = true; + } + else if (onArea (CropLeft, ix, iy)) { + state = SResizeW1; + press_x = x; + action_x = cropParams.x; + cropgl = iatlistener->startCropEditing (thumbnail); + b = true; + } + else if (onArea (CropRight, ix, iy)) { + state = SResizeW2; + press_x = x; + action_x = cropParams.w; + cropgl = iatlistener->startCropEditing (thumbnail); + b = true; + } + else if ((bstate & GDK_SHIFT_MASK) && onArea (CropInside, ix, iy)) { + state = SCropMove; + press_x = x; + press_y = y; + action_x = cropParams.x; + action_y = cropParams.y; + cropgl = iatlistener->startCropEditing (thumbnail); + b = true; + } + else if (onArea (CropImage, ix, iy)) { + if (tm == TMStraighten) { + state = SRotateSelecting; + press_x = x; + press_y = y; + action_x = x; + action_y = y; + rot_deg = 0; + b = true; + } + else if (tm == TMSpotWB) { + iatlistener->spotWBselected ((ix-prex)/scale, (iy-prey)/scale, thumbnail); + b = true; + } + else if (tm == TMCropSelect) { + cropgl = iatlistener->startCropEditing (thumbnail); + if (cropgl) { + state = SCropSelecting; + press_x = cropParams.x = (ix-prex) / scale; + press_y = cropParams.y = (iy-prey) / scale; + cropParams.w = cropParams.h = 1; + cropgl->cropInit (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + b = true; + } + } + } + } + updateCursor (ix, iy); + } + return b; +} + +bool FileBrowserEntry::releaseNotify (int button, int type, int bstate, int x, int y) { + + bool b = ThumbBrowserEntryBase::releaseNotify (button, type, bstate, x, y); + + int ix = x - startx - ofsX; + int iy = y - starty - ofsY; + if (!b) { + if (state==SRotateSelecting) { + iatlistener->rotateSelectionReady (rot_deg, thumbnail); + iatlistener->getToolBar()->setTool (TMHand); + } + else if (cropgl && (state==SCropSelecting || state==SResizeH1 || state==SResizeH2 || state==SResizeW1 || state==SResizeW2 || state==SCropMove)) { + cropgl->cropManipReady (); + cropgl = NULL; + iatlistener->cropSelectionReady (); + iatlistener->getToolBar()->setTool (TMHand); + } + state = SNormal; + if (parent) + parent->redrawNeeded (this); + updateCursor (ix, iy); + } + + return b; +} + +bool FileBrowserEntry::onArea (CursorArea a, int x, int y) { + + if (!drawable || !preview) + return false; + + int x1 = (x-prex) / scale; + int y1 = (y-prey) / scale; + int cropResizeBorder = CROPRESIZEBORDER / scale; + switch (a) { + case CropImage: + return x>=prex && x=prey && ycropParams.x+cropResizeBorder && + x1cropParams.y-cropResizeBorder && + y1cropParams.x+cropResizeBorder && + x1cropParams.y+cropParams.h-1-cropResizeBorder && + y1cropParams.y+cropResizeBorder && + y1cropParams.x-cropResizeBorder && + x1cropParams.y+cropResizeBorder && + y1cropParams.x+cropParams.w-1-cropResizeBorder && + x1cropParams.y && + y1cropParams.x && + x1getToolBar()->getTool (); + Glib::RefPtr w = parent->getDrawingArea ()->get_window(); + + if (!selected) { + cursorManager.setCursor (w, CSArrow); + return; + } + + if (state==SNormal) { + if (tm==TMHand && (onArea (CropTop, x, y) || onArea (CropBottom, x, y))) + cursorManager.setCursor (w, CSResizeHeight); + else if (tm==TMHand && (onArea (CropLeft, x, y) || onArea (CropRight, x, y))) + cursorManager.setCursor (w, CSResizeWidth); + else if (onArea (CropImage, x, y)) { + if (tm==TMHand) + cursorManager.setCursor (w, CSArrow); + else if (tm==TMSpotWB) + cursorManager.setCursor (w, CSSpotWB); + else if (tm==TMCropSelect) + cursorManager.setCursor (w, CSCropSelect); + else if (tm==TMStraighten) + cursorManager.setCursor (w, CSStraighten); + } + else + cursorManager.setCursor (w, CSArrow); + } + else if (state==SCropSelecting) + cursorManager.setCursor (w, CSCropSelect); + else if (state==SRotateSelecting) + cursorManager.setCursor (w, CSStraighten); + else if (state==SCropMove) + cursorManager.setCursor (w, CSMove); + else if (state==SResizeW1 || state==SResizeW2) + cursorManager.setCursor (w, CSResizeWidth); + else if (state==SResizeH1 || state==SResizeH2) + cursorManager.setCursor (w, CSResizeHeight); +} + +void FileBrowserEntry::draw () { + + ThumbBrowserEntryBase::draw (); + if (state==SRotateSelecting) { + Cairo::RefPtr cr = parent->getDrawingArea ()->get_window()->create_cairo_context(); + drawStraightenGuide (cr); + } +} + +void FileBrowserEntry::drawStraightenGuide (Cairo::RefPtr cr) { + + if (action_x!=press_x || action_y!=press_y) { + double arg = (press_x-action_x) / sqrt(double((press_x-action_x)*(press_x-action_x)+(press_y-action_y)*(press_y-action_y))); + double sol1, sol2; + double pi = M_PI; + if (press_y>action_y) { + sol1 = acos(arg)*180/pi; + sol2 = -acos(-arg)*180/pi; + } + else { + sol1 = acos(-arg)*180/pi; + sol2 = -acos(arg)*180/pi; + } + if (fabs(sol1)45) + rot_deg = - 90.0 + rot_deg; + } + else + rot_deg = 0; + + Glib::RefPtr context = parent->getDrawingArea()->get_pango_context () ; + Pango::FontDescription fontd = context->get_font_description (); + fontd.set_weight (Pango::WEIGHT_BOLD); + fontd.set_size (8*Pango::SCALE); + context->set_font_description (fontd); + Glib::RefPtr deglayout = parent->getDrawingArea()->create_pango_layout(Glib::ustring::compose ("%1 deg", Glib::ustring::format(std::setprecision(2), rot_deg))); + + int x1 = press_x; + int y1 = press_y; + int y2 = action_y; + int x2 = action_x; + + if (x2=prew+prex+ofsX+startx) { + y2 = y1 - (double)(y1-y2)*(x1 - (prew+prex+ofsX+startx-1)) / (x1-x2); + x2 = prew+prex+ofsX+startx-1; + } + if (y2=preh+prey+ofsY+starty) { + x2 = x1 - (double)(x1-x2)*(y1 - (preh+prey+ofsY+starty-1)) / (y1-y2); + y2 = preh+prey+ofsY+starty-1; + } + + cr->set_line_width (1.5); + cr->set_source_rgb (1.0, 1.0, 1.0); + cr->move_to (x1, y1); + cr->line_to (x2, y2); + cr->stroke (); + cr->set_source_rgb (0.0, 0.0, 0.0); + std::valarray ds (1); + ds[0] = 4; + cr->set_dash (ds, 0); + cr->move_to (x1, y1); + cr->line_to (x2, y2); + cr->stroke (); + + if (press_x!=action_x && press_y!=action_y) { + cr->set_source_rgb (0.0, 0.0, 0.0); + cr->move_to ((x1+x2)/2+1, (y1+y2)/2+1); + deglayout->add_to_cairo_context (cr); + cr->move_to ((x1+x2)/2+1, (y1+y2)/2-1); + deglayout->add_to_cairo_context (cr); + cr->move_to ((x1+x2)/2-1, (y1+y2)/2+1); + deglayout->add_to_cairo_context (cr); + cr->move_to ((x1+x2)/2+1, (y1+y2)/2+1); + deglayout->add_to_cairo_context (cr); + cr->fill (); + cr->set_source_rgb (1.0, 1.0, 1.0); + cr->move_to ((x1+x2)/2, (y1+y2)/2); + deglayout->add_to_cairo_context (cr); + cr->fill (); + } +} + diff --git a/rtgui/filebrowserentry.h b/rtgui/filebrowserentry.h new file mode 100644 index 000000000..6c503ed4f --- /dev/null +++ b/rtgui/filebrowserentry.h @@ -0,0 +1,95 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _FILEBROWSERENTRY_ +#define _FILEBROWSERENTRY_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +class FileBrowserEntry; +struct FileBrowserEntryIdleHelper { + FileBrowserEntry* fbentry; + bool destroyed; + int pending; +}; + +class FileThumbnailButtonSet; +class FileBrowserEntry : public ThumbBrowserEntryBase, + public ThumbnailListener, + public ThumbImageUpdateListener { + + double scale; + static bool iconsLoaded; + ImageAreaToolListener* iatlistener; + int press_x, press_y, action_x, action_y; + double rot_deg; + rtengine::procparams::CropParams cropParams; + CropGUIListener* cropgl; + FileBrowserEntryIdleHelper* feih; + + ImgEditState state; + + bool onArea (CursorArea a, int x, int y); + void updateCursor (int x, int y); + void drawStraightenGuide (Cairo::RefPtr c); + void customBackBufferUpdate (Cairo::RefPtr c); + +public: + + static Glib::RefPtr editedIcon; + static Glib::RefPtr recentlySavedIcon; + static Glib::RefPtr enqueuedIcon; + + Thumbnail* thumbnail; + + FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname); + ~FileBrowserEntry (); + void draw (); + + void setImageAreaToolListener (ImageAreaToolListener* l) { iatlistener = l; } + + FileThumbnailButtonSet* getThumbButtonSet (); + + void refreshThumbnailImage (); + void calcThumbnailSize (); + + std::vector > getIconsOnImageArea (); + void getIconSize (int& w, int& h); + + // thumbnaillistener interface + void procParamsChanged (Thumbnail* thm, int whoChangedIt); + // thumbimageupdatelistener interface + void updateImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cropParams); + void _updateImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cropParams); // inside gtk thread + + bool motionNotify (int x, int y); + bool pressNotify (int button, int type, int bstate, int x, int y); + bool releaseNotify (int button, int type, int bstate, int x, int y); +}; + +#endif diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc new file mode 100644 index 000000000..a567a8cbb --- /dev/null +++ b/rtgui/filecatalog.cc @@ -0,0 +1,819 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CHECKTIME 2000 + +extern Glib::ustring argv0; + +#ifdef _WIN32 +int _directoryUpdater (void* cat) { + + ((FileCatalog*)cat)->checkCounter++; + if (((FileCatalog*)cat)->checkCounter==2) { + gdk_threads_enter (); + ((FileCatalog*)cat)->reparseDirectory (); + gdk_threads_leave (); + } + return 1; +} +#endif + +FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb) : listener(NULL), fslistener(NULL), hasValidCurrentEFS(false), coarsePanel(cp), filterPanel(NULL), toolBar(tb) { + + previewLoader.setPreviewLoaderListener (this); + + // construct and initialize thumbnail browsers + fileBrowser = new FileBrowser(); + fileBrowser->setFileBrowserListener (this); + fileBrowser->setArrangement (ThumbBrowserBase::TB_Vertical); + fileBrowser->show (); + + // construct trash panel with the extra "empty trash" button + trashButtonBox = new Gtk::VBox; + Gtk::Button* emptyT = new Gtk::Button (M("FILEBROWSER_EMPTYTRASH")); + emptyT->set_tooltip_text (M("FILEBROWSER_EMPTYTRASHHINT")); + emptyT->set_image (*(new Gtk::Image (Gtk::StockID("gtk-delete"), Gtk::ICON_SIZE_BUTTON))); + emptyT->signal_pressed().connect (sigc::mem_fun(*this, &FileCatalog::emptyTrash)); + trashButtonBox->pack_start (*emptyT, Gtk::PACK_SHRINK, 4); + emptyT->show (); + trashButtonBox->show (); + + // setup button bar + buttonBar = new Gtk::HBox (); + pack_start (*buttonBar, Gtk::PACK_SHRINK); + + buttonBar->pack_start (*(new Gtk::VSeparator), Gtk::PACK_SHRINK); + bDir = new Gtk::ToggleButton (); + bDir->set_active (true); + bDir->set_image (*(new Gtk::Image (argv0+"/images/folder.png"))); + bDir->set_relief (Gtk::RELIEF_NONE); + bDir->set_tooltip_text (M("FILEBROWSER_SHOWDIRHINT")); + bCateg[0] = bDir->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bDir)); + buttonBar->pack_start (*bDir, Gtk::PACK_SHRINK); + buttonBar->pack_start (*(new Gtk::VSeparator), Gtk::PACK_SHRINK); + + bUnRanked = new Gtk::ToggleButton (); + bUnRanked->set_active (false); + bUnRanked->set_image (*(new Gtk::Image (argv0+"/images/unrated.png"))); + bUnRanked->set_relief (Gtk::RELIEF_NONE); + bUnRanked->set_tooltip_text (M("FILEBROWSER_SHOWUNRANKHINT")); + bCateg[1] = bUnRanked->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bUnRanked)); + buttonBar->pack_start (*bUnRanked, Gtk::PACK_SHRINK); + buttonBar->pack_start (*(new Gtk::VSeparator), Gtk::PACK_SHRINK); + + for (int i=0; i<5; i++) { + iranked[i] = new Gtk::Image (argv0+"/images/rated.png"); + igranked[i] = new Gtk::Image (argv0+"/images/grayrated.png"); + iranked[i]->show (); + igranked[i]->show (); + bRank[i] = new Gtk::ToggleButton (); + bRank[i]->set_image (*igranked[i]); + bRank[i]->set_relief (Gtk::RELIEF_NONE); + buttonBar->pack_start (*bRank[i], Gtk::PACK_SHRINK); + bCateg[i+2] = bRank[i]->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bRank[i])); + } + bRank[0]->set_tooltip_text (M("FILEBROWSER_SHOWRANK1HINT")); + bRank[1]->set_tooltip_text (M("FILEBROWSER_SHOWRANK2HINT")); + bRank[2]->set_tooltip_text (M("FILEBROWSER_SHOWRANK3HINT")); + bRank[3]->set_tooltip_text (M("FILEBROWSER_SHOWRANK4HINT")); + bRank[4]->set_tooltip_text (M("FILEBROWSER_SHOWRANK5HINT")); + buttonBar->pack_start (*(new Gtk::VSeparator), Gtk::PACK_SHRINK); + + iTrashEmpty = new Gtk::Image(argv0+"/images/trash-show-empty.png"); + iTrashFull = new Gtk::Image(argv0+"/images/trash-show-full.png"); + + bTrash = new Gtk::ToggleButton (); + bTrash->set_image (*iTrashEmpty); + bTrash->set_relief (Gtk::RELIEF_NONE); + bTrash->set_tooltip_text (M("FILEBROWSER_SHOWTRASHHINT")); + bCateg[7] = bTrash->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bTrash)); + buttonBar->pack_start (*bTrash, Gtk::PACK_SHRINK); + buttonBar->pack_start (*(new Gtk::VSeparator), Gtk::PACK_SHRINK); + fileBrowser->trash_changed().connect( sigc::mem_fun(*this, &FileCatalog::trashChanged) ); + + categoryButtons[0] = bDir; + categoryButtons[1] = bUnRanked; + for (int i=0; i<5; i++) + categoryButtons[i+2] = bRank[i]; + categoryButtons[7] = bTrash; + + exifInfo = Gtk::manage(new Gtk::ToggleButton ()); + exifInfo->set_image (*(new Gtk::Image (argv0+"/images/info.png"))); + exifInfo->set_relief (Gtk::RELIEF_NONE); + exifInfo->set_active( options.showFileNames ); + exifInfo->signal_toggled().connect(sigc::mem_fun(*this, &FileCatalog::exifInfoButtonToggled)); + buttonBar->pack_start (*exifInfo, Gtk::PACK_SHRINK); + + // thumbnail zoom + Gtk::HBox* zoomBox = new Gtk::HBox (); + zoomInButton = new Gtk::Button (); + zoomInButton->set_image (*(new Gtk::Image (Gtk::StockID("gtk-zoom-in"), Gtk::ICON_SIZE_SMALL_TOOLBAR))); + zoomInButton->signal_pressed().connect (sigc::mem_fun(*this, &FileCatalog::zoomIn)); + zoomInButton->set_relief (Gtk::RELIEF_NONE); + zoomInButton->set_tooltip_text (M("FILEBROWSER_ZOOMINHINT")); + zoomBox->pack_end (*zoomInButton, Gtk::PACK_SHRINK); + zoomOutButton = new Gtk::Button (); + zoomOutButton->set_image (*(new Gtk::Image (Gtk::StockID("gtk-zoom-out"), Gtk::ICON_SIZE_SMALL_TOOLBAR))); + zoomOutButton->signal_pressed().connect (sigc::mem_fun(*this, &FileCatalog::zoomOut)); + zoomOutButton->set_relief (Gtk::RELIEF_NONE); + zoomOutButton->set_tooltip_text (M("FILEBROWSER_ZOOMOUTHINT")); + zoomBox->pack_end (*zoomOutButton, Gtk::PACK_SHRINK); + + // add default panel + hBox = new Gtk::HBox (); + hBox->show (); + hBox->pack_end (*fileBrowser); + fileBrowser->applyFilter (getFilter()); + pack_start (*hBox); + + buttonBar2 = new Gtk::HBox (); + pack_end (*buttonBar2, Gtk::PACK_SHRINK); + progressBar = new Gtk::ProgressBar (); + buttonBar2->pack_start (*progressBar, Gtk::PACK_SHRINK, 4); + progressBar->set_size_request (-1, 16); + + buttonBar->pack_start (*zoomBox, Gtk::PACK_SHRINK); + + buttonBar->pack_end (*coarsePanel, Gtk::PACK_SHRINK); + buttonBar->pack_end (*Gtk::manage(new Gtk::VSeparator), Gtk::PACK_SHRINK, 4); + buttonBar->pack_end (*toolBar, Gtk::PACK_SHRINK); + buttonBar->pack_end (*Gtk::manage(new Gtk::VSeparator), Gtk::PACK_SHRINK, 4); + + enabled = true; + + lastScrollPos = 0; + for (int i=0; i<8; i++) { + hScrollPos[i] = 0; + vScrollPos[i] = 0; + } + + selectedDirectory = ""; +#ifdef _WIN32 + wdMonitor = NULL; + checkCounter = 2; + g_timeout_add (CHECKTIME, _directoryUpdater, this); +#endif +} + +void FileCatalog::exifInfoButtonToggled() +{ + options.showFileNames = exifInfo->get_active(); + fileBrowser->refreshThumbImages (); +} + +void FileCatalog::on_realize() { + + Gtk::VBox::on_realize(); + Pango::FontDescription fontd = get_pango_context()->get_font_description (); + fileBrowser->get_pango_context()->set_font_description (fontd); +// batchQueue->get_pango_context()->set_font_description (fontd); +} + +void FileCatalog::closeDir () { + + if (filterPanel) + filterPanel->set_sensitive (false); + +#ifndef _WIN32 + if (dirMonitor) + dirMonitor->cancel (); +#else + if (wdMonitor) { + delete wdMonitor; + wdMonitor = NULL; + } +#endif + // terminate thumbnail preview loading + previewLoader.terminate (); + + // terminate thumbnail updater + thumbImageUpdater.terminate (); + + // remove entries + fileBrowser->close (); + fileNameList.clear (); + + dirEFS.clear (); + hasValidCurrentEFS = false; + selectedDirectory = ""; + redrawAll (); +} + +std::vector FileCatalog::getFileList () { + + std::vector names; + Glib::RefPtr dir = Gio::File::create_for_path (selectedDirectory); + safe_build_file_list (dir, names, selectedDirectory); + return names; +} + +void FileCatalog::dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile) { + + try { + Glib::RefPtr dir = Gio::File::create_for_path (dirname); + + if (!dir) + return; + closeDir (); + previewsToLoad = 0; + previewsLoaded = 0; + // if openfile exists, we have to open it first (it is a command line argument) + if (openfile!="") + addAndOpenFile (openfile); + + selectedDirectory = dir->get_parse_name(); + fileNameList = getFileList (); + + for (int i=0; i f = Gio::File::create_for_path(fileNameList[i]); + if (f->get_parse_name() != openfile) // if we opened a file at the beginning dont add it again + checkAndAddFile (f); + } + + _refreshProgressBar (); + previewLoader.process (); + +#ifdef _WIN32 + wdMonitor = new WinDirMonitor (selectedDirectory, this); +#elif defined __APPLE__ + printf("TODO fix dir->monitor_directory () for OSX\n"); +#else + dirMonitor = dir->monitor_directory (); + dirMonitor->signal_changed().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::on_dir_changed), false)); +#endif + } + catch (Glib::Exception& ex) { + std::cout << ex.what(); + } +} + +void FileCatalog::_refreshProgressBar () { + + // check if progress bar is visible +/* Glib::ListHandle list = buttonBar2->get_children (); + Glib::ListHandle::iterator i = list.begin (); + for (; i!=list.end() && *i!=progressBar; i++); + if (i==list.end()) { + buttonBar2->pack_start (*progressBar, Gtk::PACK_SHRINK, 4); + buttonBar2->reorder_child (*progressBar, 2); + } +*/ + progressBar->show (); + if (previewsToLoad>0) + progressBar->set_fraction ((double)previewsLoaded / previewsToLoad); + else + progressBar->set_fraction (1.0); +} + +int refreshpb (void* data) { + + gdk_threads_enter (); + ((FileCatalog*)data)->_refreshProgressBar (); + gdk_threads_leave (); + return 0; +} + +void FileCatalog::previewReady (FileBrowserEntry* fdn) { + + // put it into the "full directory" browser + fdn->setImageAreaToolListener (iatlistener); + fileBrowser->addEntry (fdn); + + // update exif filter settings (minimal & maximal values of exif tags, cameras, lenses, etc...) + const CacheImageData* cfs = fdn->thumbnail->getCacheImageData(); + if (cfs->exifValid) { + if (cfs->fnumber < dirEFS.fnumberFrom) + dirEFS.fnumberFrom = cfs->fnumber; + if (cfs->fnumber > dirEFS.fnumberTo) + dirEFS.fnumberTo = cfs->fnumber; + if (cfs->shutter < dirEFS.shutterFrom) + dirEFS.shutterFrom = cfs->shutter; + if (cfs->shutter > dirEFS.shutterTo) + dirEFS.shutterTo = cfs->shutter; + if (cfs->iso>0 && cfs->iso < dirEFS.isoFrom) + dirEFS.isoFrom = cfs->iso; + if (cfs->iso>0 && cfs->iso > dirEFS.isoTo) + dirEFS.isoTo = cfs->iso; + if (cfs->focalLen < dirEFS.focalFrom) + dirEFS.focalFrom = cfs->focalLen; + if (cfs->focalLen > dirEFS.focalTo) + dirEFS.focalTo = cfs->focalLen; + } + dirEFS.cameras.insert (cfs->camera); + dirEFS.lenses.insert (cfs->lens); + previewsLoaded++; + g_idle_add (refreshpb, this); +} + +int prevfinished (void* data) { + + gdk_threads_enter(); + ((FileCatalog*)data)->_previewsFinished (); + gdk_threads_leave(); + return 0; +} + +void FileCatalog::_previewsFinished () { + + redrawAll (); + previewsToLoad = 0; + previewsLoaded = 0; +// removeIfThere (buttonBar2, progressBar); + progressBar->hide (); + if (filterPanel) { + filterPanel->set_sensitive (true); + if ( !hasValidCurrentEFS ){ + currentEFS = dirEFS; + filterPanel->setFilter ( dirEFS,true ); + }else { + filterPanel->setFilter ( currentEFS,false ); + } + } +} + +void FileCatalog::previewsFinished () { + + if (!hasValidCurrentEFS) + currentEFS = dirEFS; + g_idle_add (prevfinished, this); +} + +void PreviewLoader::remove (Glib::ustring fname) { + std::list::iterator i; + for (i=jqueue.begin(); i!=jqueue.end(); i++) + if (i->fullName==fname) + break; + if (i!=jqueue.end()) + jqueue.erase (i); +} + +void PreviewLoader::start () { + + jqueue.sort (); +} + +void PreviewLoader::process (DirEntry& current) { + + if (Glib::file_test (current.fullName, Glib::FILE_TEST_EXISTS)) { + Thumbnail* tmb = cacheMgr.getEntry (current.fullName); + if (tmb && pl) + pl->previewReady (new FileBrowserEntry (tmb, current.fullName)); + } +} + +void PreviewLoader::end () { + + if (pl) + pl->previewsFinished (); +} + +void FileCatalog::setEnabled (bool e) { + + enabled = e; +} + +void FileCatalog::redrawAll () { + + fileBrowser->queue_draw (); +} + +void FileCatalog::refreshAll () { + + fileBrowser->refreshThumbImages (); +} + +void FileCatalog::_openImage (std::vector tmb) { + + if (enabled && listener!=NULL) { + previewLoader.stop (); + thumbImageUpdater.stop (); + for (int i=0; igetFileName())==editedFiles.end()) + listener->fileSelected (tmb[i]); + tmb[i]->decreaseRef (); + } + previewLoader.process (); + thumbImageUpdater.process (); + } +} + +struct FCOIParams { + FileCatalog* catalog; + std::vector tmb; +}; + +int fcopenimg (void* p) { + + gdk_threads_enter (); + FCOIParams* params = (FCOIParams*)p; + params->catalog->_openImage (params->tmb); + delete params; + gdk_threads_leave (); + return 0; +} + +void FileCatalog::openRequested (std::vector tmb) { + + FCOIParams* params = new FCOIParams; + params->catalog = this; + params->tmb = tmb; + for (int i=0; iincreaseRef (); + g_idle_add (fcopenimg, params); +} + +void FileCatalog::deleteRequested (std::vector tbe) { + + if (tbe.size()==0) + return; + + Gtk::MessageDialog msd (M("FILEBROWSER_DELETEDLGLABEL"), false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true); + msd.set_secondary_text(Glib::ustring::compose (M("FILEBROWSER_DELETEDLGMSG"), tbe.size())); + + if (msd.run()==Gtk::RESPONSE_YES) { + for (int i=0; ifilename; + // remove from browser + FileBrowserEntry* t = fileBrowser->delEntry (fname); +// t->thumbnail->decreaseRef (); + delete t; + // remove from cache + cacheMgr.deleteEntry (fname); + // delete from file system + ::g_remove (fname.c_str()); + // delete .pp2 if found + ::g_remove (Glib::ustring(fname+".pp2").c_str()); + ::g_remove (Glib::ustring(removeExtension(fname)+".pp2").c_str()); + // delete .thm file + ::g_remove (Glib::ustring(removeExtension(fname)+".thm").c_str()); + ::g_remove (Glib::ustring(removeExtension(fname)+".THM").c_str()); + } + redrawAll (); + } +} + +void FileCatalog::developRequested (std::vector tbe) { + + if (listener) { + thumbImageUpdater.stop (); + for (int i=0; ithumbnail->getProcParams(); + rtengine::ProcessingJob* pjob = rtengine::ProcessingJob::create (tbe[i]->filename, tbe[i]->thumbnail->getType()==FT_Raw, params); + double tmpscale; + rtengine::IImage8* img = tbe[i]->thumbnail->processThumbImage (params, options.maxThumbnailHeight, tmpscale); + if (img) { + int pw = img->getWidth (); + int ph = img->getHeight (); + guint8* prev = new guint8 [pw*ph*3]; + memcpy (prev, img->getData (), pw*ph*3); + listener->addBatchQueueJob (new BatchQueueEntry (pjob, params, tbe[i]->filename, prev, pw, ph, tbe[i]->thumbnail)); + } + else { + int pw, ph; + tbe[i]->thumbnail->getThumbnailSize (pw, ph); + listener->addBatchQueueJob (new BatchQueueEntry (pjob, params, tbe[i]->filename, NULL, pw, ph, tbe[i]->thumbnail)); + } + } + thumbImageUpdater.process (); + } +} + +void FileCatalog::renameRequested (std::vector tbe) { + + RenameDialog* renameDlg = new RenameDialog ((Gtk::Window*)get_toplevel()); + + for (int i=0; iinitName (Glib::path_get_basename (tbe[i]->filename), tbe[i]->thumbnail->getCacheImageData()); + + Glib::ustring ofname = tbe[i]->filename; + Glib::ustring dirName = Glib::path_get_dirname (tbe[i]->filename); + Glib::ustring baseName = Glib::path_get_basename (tbe[i]->filename); + + if (renameDlg->run ()== Gtk::RESPONSE_OK) { + Glib::ustring nBaseName = renameDlg->getNewName (); + // if path has directory components, exit + if (Glib::path_get_dirname (nBaseName) != ".") + continue; + // if no extension is given, concatenate the extension of the original file + Glib::ustring ext = getExtension (nBaseName); + if (ext=="") + nBaseName += "." + getExtension (baseName); + Glib::ustring nfname = Glib::build_filename (dirName, nBaseName); + if (!::g_rename (ofname.c_str(), nfname.c_str())) { + cacheMgr.renameEntry (ofname, tbe[i]->thumbnail->getMD5(), nfname); + reparseDirectory (); + } + renameDlg->hide (); + } + } + delete renameDlg; +/* // ask for new file name + Gtk::Dialog dialog (M("FILEBROWSER_RENAMEDLGLABEL"), *((Gtk::Window*)get_toplevel()), true, true); + + dialog.add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK); + dialog.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + + Gtk::Label l; + dialog.get_vbox()->pack_start (l, Gtk::PACK_SHRINK); + + Gtk::Entry nfentry; + + dialog.get_vbox()->pack_start (nfentry, Gtk::PACK_SHRINK); + dialog.get_vbox()->show_all (); + + nfentry.set_activates_default (true); + dialog.set_default_response (Gtk::RESPONSE_OK); + + for (int i=0; ifilename; + Glib::ustring dirName = Glib::path_get_dirname (tbe[i]->filename); + Glib::ustring baseName = Glib::path_get_basename (tbe[i]->filename); + + l.set_markup (Glib::ustring("") + Glib::ustring::compose (M("FILEBROWSER_RENAMEDLGMSG"), baseName) + Glib::ustring("")); + nfentry.set_text (baseName); + nfentry.select_region (0, baseName.size()); + + if (dialog.run ()== Gtk::RESPONSE_OK) { + Glib::ustring nBaseName = nfentry.get_text (); + // if path has directory components, exit + if (Glib::path_get_dirname (nBaseName) != ".") + continue; + // if no extension is given, concatenate the extension of the original file + if (nBaseName.find ('.')==nBaseName.npos) { + int lastdot = baseName.find_last_of ('.'); + nBaseName += "." + (lastdot!=Glib::ustring::npos ? baseName.substr (lastdot+1) : ""); + } + Glib::ustring nfname = Glib::build_filename (dirName, nBaseName); + if (!::g_rename (ofname.c_str(), nfname.c_str())) { + cacheMgr.renameEntry (ofname, tbe[i]->thumbnail->getMD5(), nfname); + // the remaining part (removing old and adding new entry) is done by the directory monitor + reparseDirectory (); +// on_dir_changed (Gio::File::create_for_path (nfname), Gio::File::create_for_path (nfname), Gio::FILE_MONITOR_EVENT_CHANGED, true); + } + } + } + */ +} + +void FileCatalog::categoryButtonToggled (Gtk::ToggleButton* b) { + + for (int i=0; i<8; i++) + bCateg[i].block (true); + + fileBrowser->getScrollPosition (hScrollPos[lastScrollPos], vScrollPos[lastScrollPos]); + + // seek the one pressed + for (int i=0; i<8; i++) { + categoryButtons[i]->set_active (categoryButtons[i]==b); + if (categoryButtons[i]==b) + lastScrollPos = i; + } + + // change the images of the buttons to reflect current ranking + for (int i=0; i<5; i++) + bRank[i]->set_image (*igranked[i]); + for (int i=0; i<5; i++) + if (b==bRank[i]) + for (int j=0; j<=i; j++) + bRank[j]->set_image (*iranked[j]); + + fileBrowser->applyFilter (getFilter ()); + + // rearrange panels according to the selected filter + removeIfThere (hBox, trashButtonBox); + if (bTrash->get_active ()) + hBox->pack_start (*trashButtonBox, Gtk::PACK_SHRINK, 4); + hBox->queue_draw (); + + fileBrowser->setScrollPosition (hScrollPos[lastScrollPos], vScrollPos[lastScrollPos]); + + for (int i=0; i<8; i++) + bCateg[i].block (false); +} + +BrowserFilter FileCatalog::getFilter () { + + BrowserFilter filter; + filter.showRanked[0] = bDir->get_active() || bUnRanked->get_active () || bTrash->get_active (); + for (int i=1; i<=5; i++) + filter.showRanked[i] = bDir->get_active() || bRank[i-1]->get_active () || bTrash->get_active (); + filter.showTrash = bDir->get_active() || bTrash->get_active (); + filter.showNotTrash = !bTrash->get_active (); + if (!filterPanel) + filter.exifFilterEnabled = false; + else { + if (!hasValidCurrentEFS) + filter.exifFilter = dirEFS; + else + filter.exifFilter = currentEFS; + filter.exifFilterEnabled = filterPanel->isEnabled (); + } + return filter; +} + +void FileCatalog::filterChanged () { + + fileBrowser->applyFilter (getFilter()); +} + +int FileCatalog::reparseDirectory () { + + if (selectedDirectory=="") + return 0; + + if (!Glib::file_test (selectedDirectory, Glib::FILE_TEST_IS_DIR)) { + closeDir (); + return 0; + } + + std::vector nfileNameList = getFileList (); + + // check if a thumbnailed file has been deleted + const std::vector& t = fileBrowser->getEntries (); + std::vector fileNamesToDel; + for (int i=0; ifilename, Glib::FILE_TEST_EXISTS)) + fileNamesToDel.push_back (t[i]->filename); + for (int i=0; idelEntry (fileNamesToDel[i]); + cacheMgr.deleteEntry (fileNamesToDel[i]); + } + + // check if a new file has been added + for (int i=0; i& file, const Glib::RefPtr& other_file, Gio::FileMonitorEvent event_type, bool internal) { + + if (!internal) + gdk_threads_enter(); + + if (event_type == Gio::FILE_MONITOR_EVENT_CREATED || event_type == Gio::FILE_MONITOR_EVENT_DELETED || event_type == Gio::FILE_MONITOR_EVENT_CHANGED) + reparseDirectory (); + + if (!internal) + gdk_threads_leave(); +} + +void FileCatalog::checkAndAddFile (Glib::RefPtr file) { + + if (!file) + return; + Glib::RefPtr info = safe_query_file_info(file); + if (info && info->get_file_type() != Gio::FILE_TYPE_DIRECTORY && (!info->is_hidden() || !options.fbShowHidden)) { + int lastdot = info->get_name().find_last_of ('.'); + if (options.is_extention_enabled(lastdot!=Glib::ustring::npos ? info->get_name().substr (lastdot+1) : "")){ + previewLoader.add (DirEntry (file->get_parse_name())); + previewsToLoad++; + } + } +} + +void FileCatalog::addAndOpenFile (const Glib::ustring& fname) { + + Glib::RefPtr file = Gio::File::create_for_path (fname); + if (!file) + return; + Glib::RefPtr info = safe_query_file_info(file); + int lastdot = info->get_name().find_last_of ('.'); + if (options.is_extention_enabled(lastdot!=Glib::ustring::npos ? info->get_name().substr (lastdot+1) : "")){ + // if supported, load thumbnail first + Thumbnail* tmb = cacheMgr.getEntry (file->get_parse_name()); + if (tmb) { + FileBrowserEntry* entry = new FileBrowserEntry (tmb, file->get_parse_name()); + previewReady (entry); + // open the file + FCOIParams* params = new FCOIParams; + params->catalog = this; + params->tmb.push_back (tmb); + tmb->increaseRef (); + g_idle_add (fcopenimg, params); + } + } +} + +void FileCatalog::emptyTrash () { + + const std::vector t = fileBrowser->getEntries (); + std::vector toDel; + for (int i=0; ithumbnail->getStage()==1) + toDel.push_back (((FileBrowserEntry*)t[i])); + deleteRequested (toDel); + trashChanged(); +} + +bool FileCatalog::trashIsEmpty () { + const std::vector t = fileBrowser->getEntries (); + for (int i=0; ithumbnail->getStage()==1) + return false; + + return true; +} + +void FileCatalog::zoomIn () { + + bool pLoad = previewLoader.runs(); + if (pLoad) + previewLoader.stop (); + + fileBrowser->zoomIn (); + + if (pLoad) + previewLoader.process (); +} +void FileCatalog::zoomOut () { + + bool pLoad = previewLoader.runs(); + if (pLoad) + previewLoader.stop (); + + fileBrowser->zoomOut (); + + if (pLoad) + previewLoader.process (); +} +void FileCatalog::refreshEditedState (const std::set& efiles) { + + editedFiles = efiles; + fileBrowser->refreshEditedState (efiles); +} + +void FileCatalog::selectionChanged (std::vector tbe) { + + if (fslistener) + fslistener->selectionChanged (tbe); +} + +void FileCatalog::exifFilterChanged () { + + currentEFS = filterPanel->getFilter (); + hasValidCurrentEFS = true; + fileBrowser->applyFilter (getFilter ()); +} + +void FileCatalog::setFilterPanel (FilterPanel* fpanel) { + + filterPanel = fpanel; + filterPanel->set_sensitive (false); + filterPanel->setFilterPanelListener (this); +} +void FileCatalog::trashChanged () { + if (trashIsEmpty()) { + bTrash->set_image(*iTrashEmpty); + } + else { + bTrash->set_image(*iTrashFull); + } +} diff --git a/rtgui/filecatalog.h b/rtgui/filecatalog.h new file mode 100644 index 000000000..341f10df0 --- /dev/null +++ b/rtgui/filecatalog.h @@ -0,0 +1,195 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _FILECATALOG_ +#define _FILECATALOG_ + +#ifdef _WIN32 +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class PreviewLoaderListener { + public: + virtual void previewReady (FileBrowserEntry* fd) {} + virtual void previewsFinished () {} +}; + +class DirEntry { + + public: + Glib::ustring fullName; + + DirEntry (const Glib::ustring& n) : fullName (n) {} + + bool operator< (DirEntry& other) { + return fullName.casefold() < other.fullName.casefold(); + } +}; + +class PreviewLoader : public ProcessingThread { + + protected: + PreviewLoaderListener* pl; + + public: + PreviewLoader () : pl(NULL) { ProcessingThread(); } + void setPreviewLoaderListener (PreviewLoaderListener* p) { pl = p; } + void start (); + void process () { ProcessingThread::process (); } + void process (DirEntry& current); + void remove (Glib::ustring fname); + void end (); +}; + +class FileCatalog : public Gtk::VBox, + public DirSelectionListener, + public PreviewLoaderListener, + public FilterPanelListener, + public FileBrowserListener +#ifdef _WIN32 + , public WinDirChangeListener +#endif + { + + // thumbnail browsers + FileBrowser* fileBrowser; + + Gtk::HBox* hBox; + Glib::ustring selectedDirectory; + bool enabled; + + PreviewLoader previewLoader; + FileSelectionListener* listener; + FileSelectionChangeListener* fslistener; + ImageAreaToolListener* iatlistener; + + Gtk::HBox* buttonBar; + Gtk::HBox* buttonBar2; + Gtk::ToggleButton* bDir; + Gtk::ToggleButton* bUnRanked; + Gtk::ToggleButton* bRank[5]; + Gtk::ToggleButton* bTrash; + Gtk::ToggleButton* categoryButtons[8]; + Gtk::ToggleButton* exifInfo; + sigc::connection bCateg[8]; + Gtk::Image* iranked[5], *igranked[5]; + Gtk::Image *iTrashEmpty, *iTrashFull; + + double hScrollPos[8]; + double vScrollPos[8]; + int lastScrollPos; + + Gtk::VBox* trashButtonBox; + + Gtk::Button* zoomInButton; + Gtk::Button* zoomOutButton; + + ExifFilterSettings dirEFS; + ExifFilterSettings currentEFS; + bool hasValidCurrentEFS; + + FilterPanel* filterPanel; + + Glib::RefPtr dirMonitor; + + Gtk::ProgressBar* progressBar; + int previewsToLoad; + int previewsLoaded; + + +#ifdef _WIN32 + WinDirMonitor* wdMonitor; + public: + int checkCounter; + void winDirChanged (); + private: +#endif + std::vector fileNameList; + std::set editedFiles; + + void addAndOpenFile (const Glib::ustring& fname); + void checkAndAddFile (Glib::RefPtr info); + std::vector getFileList (); + BrowserFilter getFilter (); + void trashChanged (); + + public: + CoarsePanel* coarsePanel; + ToolBar* toolBar; + + FileCatalog (CoarsePanel* cp, ToolBar* tb); + void dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile=""); + void closeDir (); + void refreshEditedState (const std::set& efiles); + + // previewloaderlistener interface + void previewReady (FileBrowserEntry* fdn); + void previewsFinished (); + void _previewsFinished (); + void _refreshProgressBar (); + + // filterpanel interface + void exifFilterChanged (); + + Glib::ustring lastSelectedDir () { return selectedDirectory; } + void setEnabled (bool e); // if not enabled, it does not open image + + void redrawAll (); + void refreshAll (); + + void openRequested (std::vector tbe); + void deleteRequested (std::vector tbe); + void developRequested (std::vector tbe); + void renameRequested (std::vector tbe); + void selectionChanged (std::vector tbe); + void emptyTrash (); + bool trashIsEmpty (); + + void setFileSelectionListener (FileSelectionListener* l) { listener = l; } + void setFileSelectionChangeListener (FileSelectionChangeListener* l) { fslistener = l; } + void setImageAreaToolListener (ImageAreaToolListener* l) { iatlistener = l; } + void setFilterPanel (FilterPanel* fpanel); + void exifInfoButtonToggled(); + void categoryButtonToggled (Gtk::ToggleButton* b); + void filterChanged (); + void runFilterDialog (); + + void on_realize(); + void on_dir_changed (const Glib::RefPtr& file, const Glib::RefPtr& other_file, Gio::FileMonitorEvent event_type, bool internal); + int reparseDirectory (); + void _openImage (std::vector tmb); + + void zoomIn (); + void zoomOut (); + + void openNextImage () { fileBrowser->openNextImage(); } + void openPrevImage () { fileBrowser->openPrevImage(); } +}; + +#endif diff --git a/rtgui/filepanel.cc b/rtgui/filepanel.cc new file mode 100644 index 000000000..2b9e75ff0 --- /dev/null +++ b/rtgui/filepanel.cc @@ -0,0 +1,187 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +int fbinit (void* data) { + + gdk_threads_enter (); + ((FilePanel*)data)->init (); + gdk_threads_leave (); + + return 0; +} + +FilePanel::FilePanel () : parent(NULL) { + + dirpaned = new Gtk::HPaned (); + dirpaned->set_position (options.dirBrowserWidth); + + dirBrowser = new DirBrowser (); + placesBrowser = new PlacesBrowser (); + recentBrowser = new RecentBrowser (); + + placespaned = new Gtk::VPaned (); + placespaned->set_position (options.dirBrowserHeight); + + Gtk::VBox* obox = Gtk::manage (new Gtk::VBox ()); + obox->pack_start (*recentBrowser, Gtk::PACK_SHRINK, 4); + obox->pack_start (*dirBrowser); + + placespaned->pack1 (*placesBrowser, false, true); + placespaned->pack2 (*obox, true, true); + + dirpaned->pack1 (*placespaned, Gtk::SHRINK); + + tpc = new BatchToolPanelCoordinator (this); + fileCatalog = new FileCatalog (tpc->coarse, tpc->getToolBar()); + dirpaned->pack2 (*fileCatalog, Gtk::EXPAND|Gtk::SHRINK); + + placesBrowser->setDirBrowserRemoteInterface (dirBrowser); + recentBrowser->setDirBrowserRemoteInterface (dirBrowser); + dirBrowser->addDirSelectionListener (fileCatalog); + dirBrowser->addDirSelectionListener (recentBrowser); + dirBrowser->addDirSelectionListener (placesBrowser); + fileCatalog->setFileSelectionListener (this); + + rightBox = new Gtk::HBox (); + rightNotebook = new Gtk::Notebook (); + Gtk::VBox* taggingBox = new Gtk::VBox (); + + history = new History (false); + + tpc->addPParamsChangeListener (history); + history->setProfileChangeListener (tpc); + + Gtk::ScrolledWindow* sFilterPanel = new Gtk::ScrolledWindow(); + filterPanel = new FilterPanel (); + sFilterPanel->add (*filterPanel); + sFilterPanel->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); + + fileCatalog->setFilterPanel (filterPanel); + fileCatalog->setImageAreaToolListener (tpc); + + //------------------ + + rightNotebook->set_tab_pos (Gtk::POS_LEFT); + + Gtk::Label* devLab = new Gtk::Label (M("MAIN_TAB_DEVELOP")); + devLab->set_angle (90); + Gtk::Label* filtLab = new Gtk::Label (M("MAIN_TAB_FILTER")); + filtLab->set_angle (90); + Gtk::Label* tagLab = new Gtk::Label (M("MAIN_TAB_TAGGING")); + tagLab->set_angle (90); + + Gtk::VPaned* tpcPaned = new Gtk::VPaned (); + tpcPaned->pack1 (*tpc->toolPanelNotebook, true, true); + tpcPaned->pack2 (*history, true, true); + + rightNotebook->append_page (*tpcPaned, *devLab); + rightNotebook->append_page (*sFilterPanel, *filtLab); + rightNotebook->append_page (*taggingBox, *tagLab); + + rightBox->pack_start (*rightNotebook); + + pack1(*dirpaned, true, true); + pack2(*rightBox, false, true); + + fileCatalog->setFileSelectionChangeListener (tpc); + + fileCatalog->setFileSelectionListener (this); + g_idle_add (fbinit, this); + + show_all (); +} + +void FilePanel::on_realize () { + + Gtk::HPaned::on_realize (); + rightBox->set_size_request (options.browserToolPanelWidth, -1); +} + +void FilePanel::init () { + + dirBrowser->fillDirTree (); + placesBrowser->refreshPlacesList (); + + if (argv1!="") + dirBrowser->open (argv1); + else { + if (options.startupDir==STARTUPDIR_HOME) + dirBrowser->open (Glib::get_home_dir()); + else if (options.startupDir==STARTUPDIR_CURRENT) + dirBrowser->open (argv0); + else if (options.startupDir==STARTUPDIR_CUSTOM || options.startupDir==STARTUPDIR_LAST) + dirBrowser->open (options.startupPath); + } +} + +bool FilePanel::fileSelected (Thumbnail* thm) { + + if (!parent) + return false; + + // try to open the file + bool succ = false; + fileCatalog->setEnabled (false); + rtengine::InitialImage* isrc = EditorPanel::loadImage (thm); + if (isrc) { + EditorPanel* epanel = Gtk::manage (new EditorPanel (thm, isrc)); + parent->addEditorPanel (epanel); + succ = true; + } + else { + Glib::ustring msg_ = Glib::ustring("") + M("MAIN_MSG_CANNOTLOAD") + " \"" + thm->getFileName() + "\" .\n"; + Gtk::MessageDialog msgd (msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + msgd.run (); + } + fileCatalog->setEnabled (true); + return succ; +} + +void FilePanel::saveOptions () { + + options.dirBrowserWidth = dirpaned->get_position (); + options.dirBrowserHeight = placespaned->get_position (); + options.browserToolPanelWidth = rightBox->get_width (); + if (options.startupDir==STARTUPDIR_LAST && fileCatalog->lastSelectedDir ()!="") + options.startupPath = fileCatalog->lastSelectedDir (); + fileCatalog->closeDir (); +} + +void FilePanel::open (const Glib::ustring& d) { + + if (Glib::file_test (d, Glib::FILE_TEST_IS_DIR)) + dirBrowser->open (d.c_str()); + else if (Glib::file_test (d, Glib::FILE_TEST_EXISTS)) + dirBrowser->open (Glib::path_get_dirname(d), Glib::path_get_basename(d)); +} + +bool FilePanel::addBatchQueueJob (BatchQueueEntry* bqe) { + + if (parent) + parent->addBatchQueueJob (bqe); + return true; +} + +void FilePanel::optionsChanged () { + + tpc->optionsChanged (); + fileCatalog->refreshAll (); +} diff --git a/rtgui/filepanel.h b/rtgui/filepanel.h new file mode 100644 index 000000000..383590368 --- /dev/null +++ b/rtgui/filepanel.h @@ -0,0 +1,74 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _FILEPANEL_ +#define _FILEPANEL_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class RTWindow; +class FilePanel : public Gtk::HPaned, + public FileSelectionListener, + public PParamsChangeListener +{ + + protected: + Gtk::VPaned* placespaned; + Gtk::HPaned* dirpaned; + DirBrowser* dirBrowser; + PlacesBrowser* placesBrowser; + RecentBrowser* recentBrowser; + FileCatalog* fileCatalog; // filecatalog is the file browser with the button bar above it + Gtk::HBox* rightBox; + BatchToolPanelCoordinator* tpc; + History* history; + FilterPanel* filterPanel; + RTWindow* parent; + Gtk::Notebook* rightNotebook; + + public: + FilePanel (); + + void on_realize (); + + void setParent (RTWindow* p) { parent = p; } + void init (); // dont call it directly, the constructor calls it as idle source + void open (const Glib::ustring& d); // open a file or a directory + void refreshEditedState (const std::set& efiles) { fileCatalog->refreshEditedState (efiles); } + + // call this before closeing rt: it saves file browser relating things into options + void saveOptions (); + + // interface fileselectionlistener + bool fileSelected (Thumbnail* thm); + bool addBatchQueueJob (BatchQueueEntry* bqe); + + void optionsChanged (); +}; + +#endif + diff --git a/rtgui/fileselectionchangelistener.h b/rtgui/fileselectionchangelistener.h new file mode 100644 index 000000000..d03d4215d --- /dev/null +++ b/rtgui/fileselectionchangelistener.h @@ -0,0 +1,31 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _FILESELECTIONCHANGELISTENER_ +#define _FILESELECTIONCHANGELISTENER_ + +#include + +class FileSelectionChangeListener { + + public: + virtual void selectionChanged (const std::vector& selected) {} +}; + +#endif + diff --git a/rtgui/fileselectionlistener.h b/rtgui/fileselectionlistener.h new file mode 100644 index 000000000..97c92c4cd --- /dev/null +++ b/rtgui/fileselectionlistener.h @@ -0,0 +1,33 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _FILESELECTIONLISTENER_ +#define _FILESELECTIONLISTENER_ + +#include +#include + +class FileSelectionListener { + + public: + virtual bool fileSelected (Thumbnail* thm) =0; + virtual bool addBatchQueueJob (BatchQueueEntry* bqe) =0; +}; + +#endif + diff --git a/rtgui/filethumbnailbuttonset.cc b/rtgui/filethumbnailbuttonset.cc new file mode 100644 index 000000000..13c196f11 --- /dev/null +++ b/rtgui/filethumbnailbuttonset.cc @@ -0,0 +1,70 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +extern Glib::ustring argv0; + +bool FileThumbnailButtonSet::iconsLoaded = false; + +Cairo::RefPtr FileThumbnailButtonSet::rankIcon; +Cairo::RefPtr FileThumbnailButtonSet::gRankIcon; +Cairo::RefPtr FileThumbnailButtonSet::unRankIcon; +Cairo::RefPtr FileThumbnailButtonSet::trashIcon; +Cairo::RefPtr FileThumbnailButtonSet::unTrashIcon; +Cairo::RefPtr FileThumbnailButtonSet::processIcon; + +FileThumbnailButtonSet::FileThumbnailButtonSet (FileBrowserEntry* myEntry) { + + if (!iconsLoaded) { + try { + unRankIcon = Cairo::ImageSurface::create_from_png (argv0+"/images/unrated.png"); + rankIcon = Cairo::ImageSurface::create_from_png (argv0+"/images/rated.png"); + gRankIcon = Cairo::ImageSurface::create_from_png (argv0+"/images/grayrated.png"); + trashIcon = Cairo::ImageSurface::create_from_png (argv0+"/images/trash.png"); + unTrashIcon = Cairo::ImageSurface::create_from_png (argv0+"/images/undelete.png"); + processIcon = Cairo::ImageSurface::create_from_png (argv0+"/images/processing.png"); + iconsLoaded = true; + } catch (...) {} + } + + add (new LWButton (unRankIcon, 0, myEntry, LWButton::Left, LWButton::Center, M("FILEBROWSER_POPUPUNRANK"))); + for (int i=0; i<5; i++) + add (new LWButton (rankIcon, i+1, myEntry, LWButton::Left)); + add (new LWButton (processIcon, 6, myEntry, LWButton::Right, LWButton::Center, M("FILEBROWSER_POPUPPROCESS"))); + add (new LWButton (trashIcon, 7, myEntry, LWButton::Right, LWButton::Center, M("FILEBROWSER_POPUPTRASH"))); + + buttons[1]->setToolTip (M("FILEBROWSER_POPUPRANK1")); + buttons[2]->setToolTip (M("FILEBROWSER_POPUPRANK2")); + buttons[3]->setToolTip (M("FILEBROWSER_POPUPRANK3")); + buttons[4]->setToolTip (M("FILEBROWSER_POPUPRANK4")); + buttons[5]->setToolTip (M("FILEBROWSER_POPUPRANK5")); +} + +void FileThumbnailButtonSet::setRank (int stars) { + + for (int i=1; i<=5; i++) + buttons[i]->setIcon (i<=stars ? rankIcon : gRankIcon); +} + +void FileThumbnailButtonSet::setInTrash (bool inTrash) { + + buttons[7]->setIcon (inTrash ? unTrashIcon : trashIcon); + buttons[7]->setToolTip (inTrash ? M("FILEBROWSER_POPUPUNTRASH") : M("FILEBROWSER_POPUPTRASH")); +} diff --git a/rtgui/filethumbnailbuttonset.h b/rtgui/filethumbnailbuttonset.h new file mode 100644 index 000000000..228e9e82f --- /dev/null +++ b/rtgui/filethumbnailbuttonset.h @@ -0,0 +1,45 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _FILETHUMBNAILBUTTONSET_ +#define _FILETHUMBNAILBUTTONSET_ + +#include +#include +#include + +class FileBrowserEntry; +class FileThumbnailButtonSet : public LWButtonSet { + + static bool iconsLoaded; + + public: + static Cairo::RefPtr rankIcon; + static Cairo::RefPtr gRankIcon; + static Cairo::RefPtr unRankIcon; + static Cairo::RefPtr trashIcon; + static Cairo::RefPtr unTrashIcon; + static Cairo::RefPtr processIcon; + + FileThumbnailButtonSet (FileBrowserEntry* myEntry); + void setRank (int stars); + void setInTrash (bool inTrash); + +}; + +#endif diff --git a/rtgui/filterpanel.cc b/rtgui/filterpanel.cc new file mode 100644 index 000000000..67d3c0898 --- /dev/null +++ b/rtgui/filterpanel.cc @@ -0,0 +1,241 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +using namespace rtengine; + +FilterPanel::FilterPanel () : listener (NULL) { + + set_border_width (4); + + enabled = Gtk::manage (new Gtk::CheckButton (M("EXIFFILTER_METADATAFILTER"))); + pack_start (*enabled, Gtk::PACK_SHRINK, 2); + pack_start (*Gtk::manage(new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 2); + + enaFNumber = Gtk::manage (new Gtk::CheckButton (M("EXIFFILTER_APERTURE")+":")); + Gtk::VBox* fnvb = Gtk::manage(new Gtk::VBox ()); + Gtk::HBox* fnhb = Gtk::manage(new Gtk::HBox ()); + fnvb->pack_start (*enaFNumber, Gtk::PACK_SHRINK, 0); + fnumberFrom = Gtk::manage(new Gtk::Entry ()); + fnumberTo = Gtk::manage(new Gtk::Entry ()); + fnhb->pack_start (*fnumberFrom, true, true, 2); + fnhb->pack_start (*Gtk::manage(new Gtk::Label(" - ")), false, false, 4); + fnhb->pack_start (*fnumberTo, true, true, 2); + fnvb->pack_start (*fnhb, Gtk::PACK_SHRINK, 0); + pack_start (*fnvb, Gtk::PACK_SHRINK, 4); + + enaShutter = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_SHUTTER")+":")); + Gtk::VBox* svb = Gtk::manage(new Gtk::VBox ()); + Gtk::HBox* shb = Gtk::manage(new Gtk::HBox ()); + svb->pack_start (*enaShutter, Gtk::PACK_SHRINK, 0); + shutterFrom = Gtk::manage(new Gtk::Entry ()); + shutterTo = Gtk::manage(new Gtk::Entry ()); + shb->pack_start (*shutterFrom, true, true, 2); + shb->pack_start (*Gtk::manage(new Gtk::Label(" - ")), false, false, 4); + shb->pack_start (*shutterTo, true, true, 2); + svb->pack_start (*shb, Gtk::PACK_SHRINK, 0); + pack_start (*svb, Gtk::PACK_SHRINK, 4); + + enaISO = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_ISO")+":")); + Gtk::VBox* ivb = Gtk::manage(new Gtk::VBox ()); + Gtk::HBox* ihb = Gtk::manage(new Gtk::HBox ()); + ivb->pack_start (*enaISO, Gtk::PACK_SHRINK, 0); + isoFrom = Gtk::manage(new Gtk::Entry ()); + isoTo = Gtk::manage(new Gtk::Entry ()); + ihb->pack_start (*isoFrom, true, true, 2); + ihb->pack_start (*Gtk::manage(new Gtk::Label(" - ")), false, false, 4); + ihb->pack_start (*isoTo, true, true, 2); + ivb->pack_start (*ihb, Gtk::PACK_SHRINK, 0); + pack_start (*ivb, Gtk::PACK_SHRINK, 4); + + enaFocalLen = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_FOCALLEN")+":")); + Gtk::VBox* fvb = Gtk::manage(new Gtk::VBox ()); + Gtk::HBox* fhb = Gtk::manage(new Gtk::HBox ()); + fvb->pack_start (*enaFocalLen, Gtk::PACK_SHRINK, 0); + focalFrom = Gtk::manage(new Gtk::Entry ()); + focalTo = Gtk::manage(new Gtk::Entry ()); + fhb->pack_start (*focalFrom, true, true, 2); + fhb->pack_start (*Gtk::manage(new Gtk::Label(" - ")), false, false, 4); + fhb->pack_start (*focalTo, true, true, 2); + fvb->pack_start (*fhb, Gtk::PACK_SHRINK, 0); + pack_start (*fvb, Gtk::PACK_SHRINK, 4); + + enaCamera = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_CAMERA")+":")); + Gtk::VBox* cvb = Gtk::manage(new Gtk::VBox ()); + cvb->pack_start (*enaCamera, Gtk::PACK_SHRINK, 0); + camera = Gtk::manage(new Gtk::ListViewText (1, false, Gtk::SELECTION_MULTIPLE)); + camera->set_headers_visible (false); + Gtk::ScrolledWindow* scamera = Gtk::manage(new Gtk::ScrolledWindow()); + scamera->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); + scamera->add(*camera); + cvb->pack_start (*scamera, Gtk::PACK_SHRINK, 0); + pack_start (*cvb, Gtk::PACK_SHRINK, 4); + + enaLens = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_LENS")+":")); + Gtk::VBox* lvb = Gtk::manage(new Gtk::VBox ()); + lvb->pack_start (*enaLens, Gtk::PACK_SHRINK, 0); + lens = Gtk::manage(new Gtk::ListViewText (1, false, Gtk::SELECTION_MULTIPLE)); + lens->set_headers_visible (false); + Gtk::ScrolledWindow* slens = Gtk::manage(new Gtk::ScrolledWindow()); + slens->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); + slens->add(*lens); + lvb->pack_start (*slens, Gtk::PACK_SHRINK, 0); + pack_start (*lvb, Gtk::PACK_SHRINK, 4); + + conns = 0; + sChange[conns++] = fnumberFrom->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = fnumberTo->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = shutterFrom->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = shutterTo->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = isoFrom->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = isoTo->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = focalFrom->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = focalTo->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = camera->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = lens->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = enaFNumber->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); + sChange[conns++] = enaShutter->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); + sChange[conns++] = enaFocalLen->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); + sChange[conns++] = enaISO->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); + sChange[conns++] = enaCamera->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); + sChange[conns++] = enaLens->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); + sChange[conns++] = enabled->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); + + set_size_request (0, -1); + + show_all (); +} + +void FilterPanel::setFilter (ExifFilterSettings& defefs, bool updateLists) { + + + for (int i=0; iset_active (curefs.filterFNumber); + fnumberFrom->set_text (ImageMetaData::apertureToString (defefs.fnumberFrom)); + curefs.fnumberFrom = defefs.fnumberFrom; + fnumberTo->set_text (ImageMetaData::apertureToString (defefs.fnumberTo)); + curefs.fnumberTo = defefs.fnumberTo; + +// enaShutter->set_active (curefs.filterShutter); + shutterFrom->set_text (ImageMetaData::shutterToString (defefs.shutterFrom)); + curefs.shutterFrom = defefs.shutterFrom; + shutterTo->set_text (ImageMetaData::shutterToString (defefs.shutterTo)); + curefs.shutterTo = defefs.shutterTo; + +// enaISO->set_active (curefs.filterISO); + isoFrom->set_text (Glib::ustring::format (defefs.isoFrom)); + curefs.isoFrom = defefs.isoFrom; + isoTo->set_text (Glib::ustring::format (defefs.isoTo)); + curefs.isoTo = defefs.isoTo; + +// enaFocalLen->set_active (curefs.filterFocalLen); + focalFrom->set_text (Glib::ustring::format (defefs.focalFrom)); + curefs.focalFrom = defefs.focalFrom; + focalTo->set_text (Glib::ustring::format (defefs.focalTo)); + curefs.focalTo = defefs.focalTo; + +// enaCamera->set_active (curefs.filterCamera); + Glib::RefPtr cselection = camera->get_selection (); + +// enaLens->set_active (curefs.filterLens); + Glib::RefPtr lselection = lens->get_selection (); + if( updateLists ){ + lens->clear_items(); + curefs.lenses.clear(); + for (std::set::iterator i = defefs.lenses.begin(); i!=defefs.lenses.end(); i++) { + lens->append_text (*i); + curefs.lenses.insert(*i); + } + lselection->select_all(); + + camera->clear_items(); + curefs.cameras.clear(); + for (std::set::iterator i = defefs.cameras.begin(); i!=defefs.cameras.end(); i++) { + camera->append_text(*i); + curefs.cameras.insert(*i); + } + cselection->select_all(); + }else{ + for( Gtk::TreeModel::Children::iterator iter = lens->get_model()->children().begin(); iter != lens->get_model()->children().end();iter++){ + Glib::ustring v; + iter->get_value(0,v); + if( defefs.lenses.find( v ) != defefs.lenses.end() ) + lselection->select( iter ); + else + lselection->unselect( iter ); + } + for( Gtk::TreeModel::Children::iterator iter = camera->get_model()->children().begin(); iter != camera->get_model()->children().end();iter++){ + Glib::ustring v; + iter->get_value(0,v); + if( defefs.cameras.find( v ) != defefs.cameras.end() ) + cselection->select(iter); + else + cselection->unselect(iter); + } + } + + curefs = defefs; + + for (int i=0; iget_active () && is_sensitive(); +} + +ExifFilterSettings FilterPanel::getFilter () { + + ExifFilterSettings efs; + efs.fnumberFrom = atof (fnumberFrom->get_text().c_str()); + efs.fnumberTo = atof (fnumberTo->get_text().c_str()); + efs.focalFrom = atof (focalFrom->get_text().c_str()); + efs.focalTo = atof (focalTo->get_text().c_str()); + efs.isoFrom = atoi (isoFrom->get_text().c_str()); + efs.isoTo = atoi (isoTo->get_text().c_str()); + efs.shutterFrom = ImageMetaData::shutterFromString (shutterFrom->get_text()); + efs.shutterTo = ImageMetaData::shutterFromString (shutterTo->get_text()); + + efs.filterFNumber = enaFNumber->get_active (); + efs.filterShutter = enaShutter->get_active (); + efs.filterFocalLen = enaFocalLen->get_active (); + efs.filterISO = enaISO->get_active (); + efs.filterCamera = enaCamera->get_active (); + efs.filterLens = enaLens->get_active (); + + std::vector sel = camera->get_selected (); + for (int i=0; iget_text (sel[i])); + sel = lens->get_selected (); + for (int i=0; iget_text (sel[i])); + + return efs; +} + +void FilterPanel::valueChanged () { + + if (listener) + listener->exifFilterChanged (); +} diff --git a/rtgui/filterpanel.h b/rtgui/filterpanel.h new file mode 100644 index 000000000..04a6248b2 --- /dev/null +++ b/rtgui/filterpanel.h @@ -0,0 +1,71 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _FILTERPANEL_ +#define _FILTERPANEL_ + +#include +#include + +class FilterPanelListener { + + public: + virtual void exifFilterChanged () {} +}; + +class FilterPanel : public Gtk::VBox { + + protected: + Gtk::ListViewText* camera; + Gtk::ListViewText* lens; + Gtk::Entry* fnumberFrom; + Gtk::Entry* fnumberTo; + Gtk::Entry* shutterFrom; + Gtk::Entry* shutterTo; + Gtk::Entry* focalFrom; + Gtk::Entry* focalTo; + Gtk::Entry* isoFrom; + Gtk::Entry* isoTo; + Gtk::CheckButton* enabled; + Gtk::CheckButton* enaFNumber; + Gtk::CheckButton* enaShutter; + Gtk::CheckButton* enaFocalLen; + Gtk::CheckButton* enaISO; + Gtk::CheckButton* enaCamera; + Gtk::CheckButton* enaLens; + + int conns; + sigc::connection sChange[20]; + + ExifFilterSettings curefs; + FilterPanelListener* listener; + + public: + FilterPanel (); + + void setFilterPanelListener (FilterPanelListener* l) { listener = l; } + + void setFilter (ExifFilterSettings& defefs, bool updateLists); + ExifFilterSettings getFilter (); + bool isEnabled (); + + + void valueChanged (); +}; + +#endif diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc new file mode 100644 index 000000000..e1f757e0e --- /dev/null +++ b/rtgui/guiutils.cc @@ -0,0 +1,196 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +bool removeIfThere (Gtk::Container* cont, Gtk::Widget* w, bool increference) { + + Glib::ListHandle list = cont->get_children (); + Glib::ListHandle::iterator i = list.begin (); + for (; i!=list.end() && *i!=w; i++); + if (i!=list.end()) { + if (increference) + w->reference (); + cont->remove (*w); + return true; + } + else + return false; +} + +void thumbInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh) { + + if (options.thumbInterp==0) + rtengine::nearestInterp (src, sw, sh, dst, dw, dh); + else if (options.thumbInterp==1) + rtengine::bilinearInterp (src, sw, sh, dst, dw, dh); +} + +Glib::ustring removeExtension (const Glib::ustring& filename) { + + Glib::ustring bname = Glib::path_get_basename(filename); + int lastdot = bname.find_last_of ('.'); + if (lastdot!=bname.npos) + return filename.substr (0, filename.size()-(bname.size()-lastdot)); + else + return filename; +} + +Glib::ustring getExtension (const Glib::ustring& filename) { + + Glib::ustring bname = Glib::path_get_basename(filename); + int lastdot = bname.find_last_of ('.'); + if (lastdot!=bname.npos) + return filename.substr (filename.size()-(bname.size()-lastdot)+1, filename.npos); + else + return ""; +} + +void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int imh, int startx, int starty, double scale, const rtengine::procparams::CropParams& cparams) { + + cr->set_line_width (1.0); + cr->rectangle (imx+0.5, imy+0.5, imw, imh); + cr->clip (); + + double c1x = (cparams.x-startx)*scale; + double c1y = (cparams.y-starty)*scale; + double c2x = (cparams.x+cparams.w-1-startx)*scale; + double c2y = (cparams.y+cparams.h-1-starty)*scale; + + cr->set_source_rgba (0, 0, 0, 2.0/3.0); + cr->rectangle (imx+0.5, imy+0.5, imw, c1y); + cr->rectangle (imx+0.5, imy+0.5+c2y, imw, imh-c2y); + cr->rectangle (imx+0.5, imy+0.5+c1y, c1x, c2y-c1y+1); + cr->rectangle (imx+0.5+c2x, imy+0.5+c1y, imw-c2x, c2y-c1y+1); + cr->fill (); + + // rectangle around the cropped area and guides + if (cparams.guide!="None") { + double rectx1 = c1x + imx + 0.5; + double recty1 = c1y + imy + 0.5; + double rectx2 = c2x + imx + 0.5; + double recty2 = c2y + imy + 0.5; + cr->set_line_width (1.0); + cr->set_source_rgb (1.0, 1.0, 1.0); + cr->move_to (rectx1, recty1); + cr->line_to (rectx2, recty1); + cr->line_to (rectx2, recty2); + cr->line_to (rectx1, recty2); + cr->line_to (rectx1, recty1); + cr->stroke (); + cr->set_source_rgb (0.0, 0.0, 0.0); + std::valarray ds (1); + ds[0] = 4; + cr->set_dash (ds, 0); + cr->move_to (rectx1, recty1); + cr->line_to (rectx2, recty1); + cr->line_to (rectx2, recty2); + cr->line_to (rectx1, recty2); + cr->line_to (rectx1, recty1); + cr->stroke (); + ds.resize (0); + cr->set_dash (ds, 0); + + if (cparams.guide!="Rule of diagonals") { + // draw guide lines + std::vector horiz_ratios; + std::vector vert_ratios; + + if (cparams.guide=="Rule of thirds") { + horiz_ratios.push_back (1.0/3.0); + horiz_ratios.push_back (2.0/3.0); + vert_ratios.push_back (1.0/3.0); + vert_ratios.push_back (2.0/3.0); + } + else if (cparams.guide=="Harmonic means 1") { + horiz_ratios.push_back (1.0-0.618); + vert_ratios.push_back (1.0-0.618); + } + else if (cparams.guide=="Harmonic means 2") { + horiz_ratios.push_back (0.618); + vert_ratios.push_back (1.0-0.618); + } + else if (cparams.guide=="Harmonic means 3") { + horiz_ratios.push_back (1.0-0.618); + vert_ratios.push_back (0.618); + } + else if (cparams.guide=="Harmonic means 4") { + horiz_ratios.push_back (0.618); + vert_ratios.push_back (0.618); + } + for (int i=0; iset_source_rgb (1.0, 1.0, 1.0); + cr->move_to (rectx1 + (rectx2-rectx1) * vert_ratios[i], recty1); + cr->line_to (rectx1 + (rectx2-rectx1) * vert_ratios[i], recty2); + cr->move_to (rectx1, recty1 + (recty2-recty1) * horiz_ratios[i]); + cr->line_to (rectx2, recty1 + (recty2-recty1) * horiz_ratios[i]); + cr->stroke (); + cr->set_source_rgb (0.0, 0.0, 0.0); + std::valarray ds (1); + ds[0] = 4; + cr->set_dash (ds, 0); + cr->move_to (rectx1 + (rectx2-rectx1) * vert_ratios[i], recty1); + cr->line_to (rectx1 + (rectx2-rectx1) * vert_ratios[i], recty2); + cr->move_to (rectx1, recty1 + (recty2-recty1) * horiz_ratios[i]); + cr->line_to (rectx2, recty1 + (recty2-recty1) * horiz_ratios[i]); + cr->stroke (); + ds.resize (0); + cr->set_dash (ds, 0); + } + } + else { + int corners_from[4][2]; + int corners_to[4][2]; + int mindim = MIN (rectx2-rectx1+1, recty2-recty1+1); + corners_from[0][0] = rectx1; + corners_from[0][1] = recty1; + corners_to[0][0] = rectx1 + mindim; + corners_to[0][1] = recty1 + mindim; + corners_from[1][0] = rectx1; + corners_from[1][1] = recty2; + corners_to[1][0] = rectx1 + mindim; + corners_to[1][1] = recty2 - mindim; + corners_from[2][0] = rectx2; + corners_from[2][1] = recty1; + corners_to[2][0] = rectx2 - mindim; + corners_to[2][1] = recty1 + mindim; + corners_from[3][0] = rectx2; + corners_from[3][1] = recty2; + corners_to[3][0] = rectx2 - mindim; + corners_to[3][1] = recty2 - mindim; + for (int i=0; i<4; i++) { + cr->set_source_rgb (1.0, 1.0, 1.0); + cr->move_to (corners_from[i][0], corners_from[i][1]); + cr->line_to (corners_to[i][0], corners_to[i][1]); + cr->stroke (); + cr->set_source_rgb (0.0, 0.0, 0.0); + std::valarray ds (1); + ds[0] = 4; + cr->set_dash (ds, 0); + cr->move_to (corners_from[i][0], corners_from[i][1]); + cr->line_to (corners_to[i][0], corners_to[i][1]); + cr->stroke (); + ds.resize (0); + cr->set_dash (ds, 0); + } + } + } + cr->reset_clip (); +} diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h new file mode 100644 index 000000000..8c170a598 --- /dev/null +++ b/rtgui/guiutils.h @@ -0,0 +1,31 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef __UTILS_ +#define __UTILS_ + +#include +#include + +bool removeIfThere (Gtk::Container* cont, Gtk::Widget* w, bool increference=true); +void thumbInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh); +Glib::ustring removeExtension (const Glib::ustring& filename); +Glib::ustring getExtension (const Glib::ustring& filename); +void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int imh, int startx, int starty, double scale, const rtengine::procparams::CropParams& cparams); + +#endif diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc new file mode 100644 index 000000000..899fbb4c1 --- /dev/null +++ b/rtgui/histogrampanel.cc @@ -0,0 +1,466 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +HistogramPanel::HistogramPanel () { + + histogramArea = Gtk::manage (new HistogramArea ()); + showRed = Gtk::manage (new Gtk::ToggleButton ("R")); + showGreen = Gtk::manage (new Gtk::ToggleButton ("G")); + showBlue = Gtk::manage (new Gtk::ToggleButton ("B")); + showValue = Gtk::manage (new Gtk::ToggleButton ("L")); + Gtk::VBox* vbox = Gtk::manage (new Gtk::VBox (false, 0)); + + showRed->set_active (true); + showGreen->set_active (true); + showBlue->set_active (true); + showValue->set_active (true); + vbox->pack_start (*showRed, Gtk::PACK_SHRINK, 2); + vbox->pack_start (*showGreen, Gtk::PACK_SHRINK, 2); + vbox->pack_start (*showBlue, Gtk::PACK_SHRINK, 2); + vbox->pack_start (*showValue, Gtk::PACK_SHRINK, 2); + pack_start (*histogramArea); + pack_end (*vbox, Gtk::PACK_SHRINK, 2); + + showRed->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::rgbv_toggled) ); + showGreen->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::rgbv_toggled) ); + showBlue->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::rgbv_toggled) ); + showValue->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::rgbv_toggled) ); + + show_all (); + + showRed->set_tooltip_text (M("HISTOGRAM_TOOLTIP_R")); + showGreen->set_tooltip_text (M("HISTOGRAM_TOOLTIP_G")); + showBlue->set_tooltip_text (M("HISTOGRAM_TOOLTIP_B")); + showValue->set_tooltip_text (M("HISTOGRAM_TOOLTIP_L")); + + rconn = signal_size_allocate().connect( sigc::mem_fun(*this, &HistogramPanel::resized) ); +} + +void HistogramPanel::resized (Gtk::Allocation& req) { + + rconn.block (true); + + if (req.get_width()/2>150) + set_size_request (req.get_width(), 150); + else + set_size_request (req.get_width(), req.get_width()/2); + rconn.block (false); + histogramArea->renderHistogram (); + histogramArea->queue_draw (); +} + +void HistogramPanel::rgbv_toggled () { + + histogramArea->updateOptions (showRed->get_active(), showGreen->get_active(), showBlue->get_active(), showValue->get_active()); + histogramArea->queue_draw (); +} + +HistogramArea::HistogramArea () : + needVal(true), needRed(true), needGreen(true), needBlue(true), oldwidth(-1), valid(false), showFull(true) { + + haih = new HistogramAreaIdleHelper; + haih->harea = this; + haih->destroyed = false; + haih->pending = 0; + + signal_style_changed().connect( sigc::mem_fun(*this, &HistogramArea::styleChanged) ); +} + +HistogramArea::~HistogramArea () { + + if (haih->pending) + haih->destroyed = true; + else + delete haih; +} + +void HistogramArea::updateOptions (bool r, bool g, bool b, bool v) { + + needRed = r; + needGreen = g; + needBlue = b; + needVal = v; + + renderHistogram (); +} + +int histupdate (void* data) { + + gdk_threads_enter (); + + HistogramAreaIdleHelper* haih = (HistogramAreaIdleHelper*)data; + + if (haih->destroyed) { + if (haih->pending == 1) + delete haih; + else + haih->pending--; + gdk_threads_leave (); + return 0; + } + + haih->harea->renderHistogram (); + haih->harea->queue_draw (); + + haih->pending--; + gdk_threads_leave (); + return 0; +} + +void HistogramArea::update (unsigned int* rh, unsigned int* gh, unsigned int* bh, unsigned int* lh) { + + if (rh!=NULL) { + memcpy (lhist, lh, 256*sizeof(unsigned int)); + memcpy (rhist, rh, 256*sizeof(unsigned int)); + memcpy (ghist, gh, 256*sizeof(unsigned int)); + memcpy (bhist, bh, 256*sizeof(unsigned int)); + valid = true; + } + else + valid = false; + + haih->pending++; + g_idle_add (histupdate, haih); +} + +void HistogramArea::renderHistogram () { + + if (!is_realized ()) + return; + + Glib::RefPtr window = get_window(); + int winx, winy, winw, winh, wind; + window->get_geometry(winx, winy, winw, winh, wind); + + backBuffer = Gdk::Pixmap::create (window, winw, winh, -1); + + Glib::RefPtr bgc = Gdk::GC::create(backBuffer); + + bgc->set_foreground (white); + backBuffer->draw_rectangle (bgc, true, 0, 0, winw, winh); + + if (valid) { + + // compute height of the full histogram (realheight) and + + int fullhistheight = 0; + for (int i=0; i<256; i++) { + if (needVal && lhist[i]>fullhistheight) + fullhistheight = lhist[i]; + if (needRed && rhist[i]>fullhistheight) + fullhistheight = rhist[i]; + if (needGreen && ghist[i]>fullhistheight) + fullhistheight = ghist[i]; + if (needBlue && bhist[i]>fullhistheight) + fullhistheight = bhist[i]; + } + + // compute two hights, one for the magnified view and one for the threshold + int realhistheight = fullhistheight; + + if (!showFull) { + int area1thres = 0; + int area2thres = 0; + int area = 0; + for (int i=0; ii) || (needRed && rhist[j]>i) || (needGreen && ghist[j]>i) || (needBlue && bhist[j]>i)) + area++; + if (area1thres==0 && (double)area / (256*(i+1)) < 0.3) + area1thres = i; + if (area2thres==0 && (double)area / (256*(i+1)) < 0.3) + area2thres = i; + if (area1thres && area2thres) + break; + } + if (area1thres>0 && area2thres>0 && area1thres cr = backBuffer->create_cairo_context(); + cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + cr->set_line_width (1.0); + double stepSize = (winw-1) / 256.0; + if (needVal) { + cr->move_to (0, winh-1); + cr->set_source_rgb (0.75, 0.75, 0.75); + for (int i=0; i<256; i++) { + double val = lhist[i] * (double)(winh-2) / realhistheight; + if (val>winh-1) + val = winh-1; + if (i>0) + cr->line_to (i*stepSize, winh-1-val); + } + cr->save (); + cr->line_to (winw-1, winh-1); cr->fill_preserve (); + cr->restore (); + cr->set_source_rgb (0.5, 0.5, 0.5); + cr->stroke (); + } + if (needRed) { + cr->move_to (0, winh-1); + cr->set_source_rgb (1.0, 0.0, 0.0); + for (int i=0; i<256; i++) { + double val = rhist[i] * (double)(winh-2) / realhistheight; + if (val>winh-1) + val = winh-1; + if (i>0) + cr->line_to (i*stepSize, winh-1-val); + } + cr->stroke (); + } + if (needGreen) { cr->move_to (0, winh-1); + cr->set_source_rgb (0.0, 1.0, 0.0); + for (int i=0; i<256; i++) { + double val = ghist[i] * (double)(winh-2) / realhistheight; + if (val>winh-1) + val = winh-1; + if (i>0) + cr->line_to (i*stepSize, winh-1-val); + } + cr->stroke (); + } + if (needBlue) { + cr->move_to (0, winh-1); + cr->set_source_rgb (0.0, 0.0, 1.0); + for (int i=0; i<256; i++) { + int val = bhist[i] * (double)(winh-2) / realhistheight; + if (val>winh-1) + val = winh-1; + if (i>0) + cr->line_to (i*stepSize, winh-1-val); + } + cr->stroke (); + } + } + +/* + + // scale histogram to width winw-1 + + int* vval = new int[winw-1]; + int* vred = new int[winw-1]; + int* vgreen = new int[winw-1]; + int* vblue = new int[winw-1]; + + memset (vval, 0, sizeof(int)*(winw-1)); + memset (vred, 0, sizeof(int)*(winw-1)); + memset (vgreen, 0, sizeof(int)*(winw-1)); + memset (vblue, 0, sizeof(int)*(winw-1)); + + int index = 0; + double scale = 256.0 / (winw-2); + for (int i=0; i<=winw-2; i++) { + int samples = 0; + while (index < 256 && (int)(index/scale) == i) { + vval[i] += lhist[index]; + vred[i] += rhist[index]; + vgreen[i] += ghist[index]; + vblue[i] += bhist[index]; + index++; + samples++; + } + if (samples>0) { + vval[i] /= samples; + vred[i] /= samples; + vgreen[i] /= samples; + vblue[i] /= samples; + } + } + + // compute height of the full histogram (realheight) and + + int fullhistheight = 0; + for (int i=0; i<=winw-2; i++) { + if (needVal && vval[i]>fullhistheight) + fullhistheight = vval[i]; + if (needRed && vred[i]>fullhistheight) + fullhistheight = vred[i]; + if (needGreen && vgreen[i]>fullhistheight) + fullhistheight = vgreen[i]; + if (needBlue && vblue[i]>fullhistheight) + fullhistheight = vblue[i]; + } + + // compute two hights, one for the magnified view and one for the threshold + + int realhistheight = fullhistheight; + + if (!showFull) { + int area1thres = 0; + int area2thres = 0; + int area = 0; + for (int i=0; ii) || (needRed && vred[j]>i) || (needGreen && vgreen[j]>i) || (needBlue && vblue[j]>i)) + area++; + if (area1thres==0 && (double)area / ((winw-1)*(i+1)) < 0.3) + area1thres = i; + if (area2thres==0 && (double)area / ((winw-1)*(i+1)) < 0.3) + area2thres = i; + if (area1thres && area2thres) + break; + } + if (area1thres>0 && area2thres>0 && area1thres cr = backBuffer->create_cairo_context(); + cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + cr->set_line_width (1.0); + if (needVal) { + cr->move_to (0, winh-1); + cr->set_source_rgb (0.75, 0.75, 0.75); + for (int i=0; i<=winw-2; i++) { + int val = (int)(vval[i] * (double)(winh-2) / realhistheight); + if (val>winh-1) + val = winh-1; + if (i>0) + cr->line_to (i+1, winh-1-val); + } + cr->fill_preserve (); + cr->set_source_rgb (0.5, 0.5, 0.5); + cr->stroke (); + } + if (needRed) { + cr->move_to (0, winh-1); + cr->set_source_rgb (1.0, 0.0, 0.0); + for (int i=0; i<=winw-2; i++) { + int val = (int)(vred[i] * (double)(winh-2) / realhistheight); + if (val>winh-1) + val = winh-1; + if (i>0) + cr->line_to (i+1, winh-1-val); + } + cr->stroke (); + } + if (needGreen) { + cr->move_to (0, winh-1); + cr->set_source_rgb (0.0, 1.0, 0.0); + for (int i=0; i<=winw-2; i++) { + int val = (int)(vgreen[i] * (double)(winh-2) / realhistheight); + if (val>winh-1) + val = winh-1; + if (i>0) + cr->line_to (i+1, winh-1-val); + } + cr->stroke (); + } + if (needBlue) { + cr->move_to (0, winh-1); + cr->set_source_rgb (0.0, 0.0, 1.0); + for (int i=0; i<=winw-2; i++) { + int val = (int)(vblue[i] * (double)(winh-2) / realhistheight); + if (val>winh-1) + val = winh-1; + if (i>0) + cr->line_to (i+1, winh-1-val); + } + cr->stroke (); + } + + delete [] vval; + delete [] vred; + delete [] vgreen; + delete [] vblue; + } +*/ + bgc->set_foreground (mgray); + backBuffer->draw_rectangle (bgc, false, 0, 0, winw-1, winh-1); + + bgc->set_line_attributes (1, Gdk::LINE_ON_OFF_DASH, Gdk::CAP_NOT_LAST, Gdk::JOIN_MITER); + + backBuffer->draw_line (bgc, winw/3, 0, winw/3, winh-1); + backBuffer->draw_line (bgc, 2*winw/3, 0, 2*winw/3, winh-1); + backBuffer->draw_line (bgc, 0, winh/3, winw-1, winh/3); + backBuffer->draw_line (bgc, 0, 2*winh/3, winw-1, 2*winh/3); + + bgc->set_line_attributes (1, Gdk::LINE_SOLID, Gdk::CAP_NOT_LAST, Gdk::JOIN_MITER); + + oldwidth = winw; + oldheight = winh; +} + +void HistogramArea::on_realize () { + + Gtk::DrawingArea::on_realize(); + Glib::RefPtr window = get_window(); + gc_ = Gdk::GC::create(window); + add_events(Gdk::EXPOSURE_MASK | Gdk::BUTTON_PRESS_MASK); + Glib::RefPtr colormap = get_default_colormap(); + + black = Gdk::Color ("black"); + red = Gdk::Color ("red"); + green = Gdk::Color ("green"); + blue = Gdk::Color ("blue"); + lgray = Gdk::Color ("gray75"); + mgray = Gdk::Color ("gray50"); + dgray = Gdk::Color ("gray25"); + colormap->alloc_color(black); + colormap->alloc_color(white); + colormap->alloc_color(red); + colormap->alloc_color(green); + colormap->alloc_color(blue); + colormap->alloc_color(lgray); + colormap->alloc_color(mgray); + colormap->alloc_color(dgray); + +} + +void HistogramArea::styleChanged (const Glib::RefPtr& style) { + + white = get_style()->get_base(Gtk::STATE_NORMAL); + queue_draw (); +} + +bool HistogramArea::on_expose_event(GdkEventExpose* event) { + + Glib::RefPtr window = get_window(); + + int winx, winy, winw, winh, wind; + window->get_geometry(winx, winy, winw, winh, wind); + + if (winw!=oldwidth && winh!=oldheight) + renderHistogram (); + window->draw_drawable (gc_, backBuffer, 0, 0, 0, 0, -1, -1); + + return true; +} + + +bool HistogramArea::on_button_press_event (GdkEventButton* event) { + + if (event->type==GDK_2BUTTON_PRESS && event->button==1) { + showFull = !showFull; + renderHistogram (); + queue_draw (); + } + return true; +} + + diff --git a/rtgui/histogrampanel.h b/rtgui/histogrampanel.h new file mode 100644 index 000000000..d50ed2838 --- /dev/null +++ b/rtgui/histogrampanel.h @@ -0,0 +1,97 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _HISTOGRAMPANEL_ +#define _HISTOGRAMPANEL_ + +#include +#include + +class HistogramArea; +struct HistogramAreaIdleHelper { + HistogramArea* harea; + bool destroyed; + int pending; +}; + +class HistogramArea : public Gtk::DrawingArea { + + protected: + + Glib::RefPtr gc_; + Glib::RefPtr backBuffer; + + Gdk::Color black; + Gdk::Color white; + Gdk::Color red; + Gdk::Color green; + Gdk::Color blue; + Gdk::Color lgray; + Gdk::Color mgray; + Gdk::Color dgray; + unsigned int lhist[256]; + unsigned int rhist[256]; + unsigned int ghist[256]; + unsigned int bhist[256]; + bool valid; + bool showFull; + int oldwidth, oldheight; + + bool needVal; + bool needRed; + bool needGreen; + bool needBlue; + + HistogramAreaIdleHelper* haih; + + public: + + HistogramArea(); + ~HistogramArea(); + + void renderHistogram (); + void update (unsigned int* rh, unsigned int* gh, unsigned int* bh, unsigned int* lh); + void updateOptions (bool r, bool g, bool b, bool v); + void on_realize(); + bool on_expose_event(GdkEventExpose* event); + bool on_button_press_event (GdkEventButton* event); + void styleChanged (const Glib::RefPtr& style); +}; + +class HistogramPanel : public Gtk::HBox { + + protected: + + HistogramArea* histogramArea; + Gtk::ToggleButton* showRed; + Gtk::ToggleButton* showGreen; + Gtk::ToggleButton* showBlue; + Gtk::ToggleButton* showValue; + + sigc::connection rconn; + + public: + + HistogramPanel (); + + void histogramChanged (unsigned int* rh, unsigned int* gh, unsigned int* bh, unsigned int* lh) { histogramArea->update (rh, gh, bh, lh); } + void rgbv_toggled (); + void resized (Gtk::Allocation& req); +}; + +#endif diff --git a/rtgui/history.cc b/rtgui/history.cc new file mode 100644 index 000000000..46ea67b0b --- /dev/null +++ b/rtgui/history.cc @@ -0,0 +1,326 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +Glib::ustring eventDescrArray[NUMOFEVENTS]; +extern Glib::ustring argv0; + +History::History (bool bookmarkSupport) : tpc (NULL), bmnum (1), blistener(NULL) { + + // fill history event message array + for (int i=0; iset_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); + + Gtk::Frame* histFrame = Gtk::manage (new Gtk::Frame (M("HISTORY_LABEL"))); + histFrame->add (*hscrollw); + + pack_start (*histFrame); + + hTreeView = Gtk::manage (new Gtk::TreeView ()); + hscrollw->add (*hTreeView); + + historyModel = Gtk::ListStore::create (historyColumns); + hTreeView->set_model (historyModel); +// hTreeView->set_headers_visible (false); + + Gtk::CellRendererText *changecrt = Gtk::manage (new Gtk::CellRendererText()); + Gtk::CellRendererText *valuecrt = Gtk::manage (new Gtk::CellRendererText()); + Gtk::TreeView::Column *hviewcol = Gtk::manage (new Gtk::TreeView::Column ("")); + hviewcol->pack_start (*changecrt, true); + hviewcol->add_attribute (changecrt->property_markup (), historyColumns.text); + hviewcol->set_resizable (true); + + Gtk::TreeView::Column *hviewcol2 = Gtk::manage (new Gtk::TreeView::Column ("")); + hviewcol2->pack_start (*valuecrt, true); + hviewcol2->add_attribute (valuecrt->property_markup (), historyColumns.value); + valuecrt->set_property ("xalign", 1.0); + + hTreeView->append_column (*hviewcol); + hTreeView->append_column (*hviewcol2); + + hviewcol2->set_sizing (Gtk::TREE_VIEW_COLUMN_FIXED); + + selchangehist = hTreeView->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &History::historySelectionChanged)); + + // Bookmark List + // ~~~~~~~~~~~~~ + + Gtk::HSeparator* hsepb = Gtk::manage (new Gtk::HSeparator ()); + pack_end (*hsepb, Gtk::PACK_SHRINK, 0); + + Gtk::HBox* ahbox = Gtk::manage (new Gtk::HBox ()); + addBookmark = Gtk::manage (new Gtk::Button (M("HISTORY_NEWSNAPSHOT"))); + Gtk::Image* addimg = Gtk::manage (new Gtk::Image (argv0+"/images/list-add.png")); + addBookmark->set_image (*addimg); + ahbox->pack_start (*addBookmark); + + delBookmark = Gtk::manage (new Gtk::Button (M("HISTORY_DELSNAPSHOT"))); + Gtk::Image* delimg = Gtk::manage (new Gtk::Image (argv0+"/images/list-remove.png")); + delBookmark->set_image (*delimg); + ahbox->pack_start (*delBookmark); + + bscrollw = Gtk::manage (new Gtk::ScrolledWindow ()); +// bscrollw->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + bscrollw->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); + bscrollw->set_size_request (-1, 75); + + Gtk::Frame* bmFrame = Gtk::manage (new Gtk::Frame (M("HISTORY_SNAPSHOTS"))); + Gtk::VBox* bmBox = Gtk::manage (new Gtk::VBox ()); + bmFrame->add (*bmBox); + bmBox->pack_start (*bscrollw, Gtk::PACK_SHRINK, 4); + bmBox->pack_end (*ahbox, Gtk::PACK_SHRINK, 4); + + if (bookmarkSupport) + pack_end (*bmFrame, Gtk::PACK_SHRINK, 4); + + bTreeView = Gtk::manage (new Gtk::TreeView ()); + bscrollw->add (*bTreeView); + + bookmarkModel = Gtk::ListStore::create (bookmarkColumns); + bTreeView->set_model (bookmarkModel); + bTreeView->set_headers_visible (false); + bTreeView->append_column_editable (M("HISTORY_SNAPSHOTS"), bookmarkColumns.text); + + selchangebm = bTreeView->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &History::bookmarkSelectionChanged)); + + addBookmark->signal_clicked().connect( sigc::mem_fun(*this, &History::addBookmarkPressed) ); + delBookmark->signal_clicked().connect( sigc::mem_fun(*this, &History::delBookmarkPressed) ); + +// hTreeView->set_grid_lines (Gtk::TREE_VIEW_GRID_LINES_HORIZONTAL); + hTreeView->set_grid_lines (Gtk::TREE_VIEW_GRID_LINES_BOTH); + hTreeView->signal_size_allocate().connect( sigc::mem_fun(*this, &History::resized) ); + + hTreeView->set_enable_search(false); + bTreeView->set_enable_search(false); + + show_all_children (); +} + +void History::initHistory () { + + historyModel->clear (); + bookmarkModel->clear (); +} + +void History::clearParamChanges () { + + initHistory (); +} + +void History::historySelectionChanged () { + + Glib::RefPtr selection = hTreeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + if (iter) { + Gtk::TreeModel::Row row = *iter; + if (row) + bTreeView->get_selection()->unselect_all (); + if (row && tpc) { + ProcParams params = row[historyColumns.params]; + ParamsEdited paramsEdited = row[historyColumns.paramsEdited]; + tpc->profileChange (¶ms, EvHistoryBrowsed, row[historyColumns.text], ¶msEdited); + } + if (blistener) { + Gtk::TreeModel::Path path = historyModel->get_path (iter); + path.prev (); + iter = historyModel->get_iter (path); + if (blistener && iter) + blistener->historyBeforeLineChanged (iter->get_value (historyColumns.params)); + } + } +} + +void History::bookmarkSelectionChanged () { + + Glib::RefPtr selection = bTreeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + if (iter) { + Gtk::TreeModel::Row row = *iter; + if (row) + hTreeView->get_selection()->unselect_all (); + if (row && tpc) { + ProcParams params = row[bookmarkColumns.params]; + ParamsEdited paramsEdited = row[bookmarkColumns.paramsEdited]; + tpc->profileChange (¶ms, EvBookmarkSelected, row[bookmarkColumns.text], ¶msEdited); + } + } +} + +void History::procParamsChanged (ProcParams* params, ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited) { + + // to prevent recursion, we filter out the events triggered by the history + if (ev==EvHistoryBrowsed) + return; + + selchangehist.block (true); + + if (ev==EvPhotoLoaded) + initHistory (); + // construct formatted list content + Glib::ustring text = Glib::ustring::compose ("%1", eventDescrArray[ev]); + + Glib::RefPtr selection = hTreeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + // remove all rows after the selection + if (iter) { + iter++; + while (iter) + iter = historyModel->erase (iter); + } + // lookup the last remaining item in the list + int size = historyModel->children().size (); + Gtk::TreeModel::Row row; + if (size>0) + row = historyModel->children()[size-1]; + // if there is no last item or its chev!=ev, create a new one + if (size==0 || !row || row[historyColumns.chev]!=ev) { + Gtk::TreeModel::Row newrow = *(historyModel->append()); + newrow[historyColumns.realText] = eventDescrArray[ev]; + newrow[historyColumns.text] = text; + newrow[historyColumns.value] = descr; + newrow[historyColumns.chev] = ev; + newrow[historyColumns.params] = *params; + newrow[historyColumns.paramsEdited] = paramsEdited ? *paramsEdited : defParamsEdited; + if (ev!=EvBookmarkSelected) + selection->select (newrow); + if (blistener && row) + blistener->historyBeforeLineChanged (row[historyColumns.params]); + else if (blistener && size==0) + blistener->historyBeforeLineChanged (newrow[historyColumns.params]); + } + // else just update it + else { + row[historyColumns.realText] = eventDescrArray[ev]; + row[historyColumns.text] = text; + row[historyColumns.value] = descr; + row[historyColumns.chev] = ev; + row[historyColumns.params] = *params; + row[historyColumns.paramsEdited] = paramsEdited ? *paramsEdited : defParamsEdited; + if (ev!=EvBookmarkSelected) + selection->select (row); + } + if (ev!=EvBookmarkSelected) + bTreeView->get_selection()->unselect_all (); + + + if (!selection->get_selected_rows().empty()) { + Gtk::TreeView::Selection::ListHandle_Path selp = selection->get_selected_rows(); + hTreeView->scroll_to_row (*selp.begin()); + } + selchangehist.block (false); +} + +void History::addBookmarkWithText (Glib::ustring text) { + + // lookup the selected item in the history + Glib::RefPtr selection = hTreeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + Gtk::TreeModel::Row row = *iter; + + if (!row) { + return; + } + + // append new row to bookmarks + Gtk::TreeModel::Row newrow = *(bookmarkModel->append()); + newrow[bookmarkColumns.text] = text; + ProcParams params = row[historyColumns.params]; + newrow[bookmarkColumns.params] = params; + ParamsEdited paramsEdited = row[historyColumns.paramsEdited]; + newrow[bookmarkColumns.paramsEdited] = paramsEdited; +} + +void History::addBookmarkPressed () { + + if (hTreeView->get_selection()->get_selected()) + addBookmarkWithText (Glib::ustring::compose ("%1 %2", M("HISTORY_SNAPSHOT"), bmnum++)); +} + +void History::delBookmarkPressed () { + + // lookup the selected item in the bookmark + Glib::RefPtr selection = bTreeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + + if (!iter) { + return; + } + // remove selected bookmark + bookmarkModel->erase (iter); + // select last item in history + int size = historyModel->children().size (); + Gtk::TreeModel::Row row = historyModel->children()[size-1]; + hTreeView->get_selection()->select (row); +} + +void History::undo () { + + Glib::RefPtr selection = hTreeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + + if (iter && iter!=historyModel->children().begin()) + selection->select (--iter); + else if (!iter) { + int size = historyModel->children().size (); + if (size>1) + selection->select (historyModel->children()[size-2]); + } +} + +void History::redo () { + + Glib::RefPtr selection = hTreeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + + if (iter) { + iter++; + if (iter!=historyModel->children().end()) + selection->select (iter); + } + else { + int size = historyModel->children().size (); + if (size>1) + selection->select (historyModel->children()[size-2]); + } +} + +void History::resized (Gtk::Allocation& req) { +} + +bool History::getBeforeLineParams (rtengine::procparams::ProcParams& params) { + + int size = historyModel->children().size (); + if (size==0 || !blistener) + return false; + + Gtk::TreeModel::Row row; + row = historyModel->children()[size==1 ? 0 : size-2]; + params = row[historyColumns.params]; + return true; +} + diff --git a/rtgui/history.h b/rtgui/history.h new file mode 100644 index 000000000..58d0a76c9 --- /dev/null +++ b/rtgui/history.h @@ -0,0 +1,105 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _HISTORY_ +#define _HISTORY_ + +#include +#include +#include +#include +#include + +class HistoryBeforeLineListener { + + public: + virtual void historyBeforeLineChanged (const rtengine::procparams::ProcParams& params) {} +}; + +class History : public Gtk::VBox, public PParamsChangeListener { + + public: + + class HistoryColumns : public Gtk::TreeModel::ColumnRecord { + public: + Gtk::TreeModelColumn realText; + Gtk::TreeModelColumn text; + Gtk::TreeModelColumn value; + Gtk::TreeModelColumn params; + Gtk::TreeModelColumn chev; + Gtk::TreeModelColumn paramsEdited; + HistoryColumns() { add(text); add(realText); add(value); add(chev); add(params); add(paramsEdited); } + }; + HistoryColumns historyColumns; + class BookmarkColumns : public Gtk::TreeModel::ColumnRecord { + public: + Gtk::TreeModelColumn text; + Gtk::TreeModelColumn params; + Gtk::TreeModelColumn paramsEdited; + BookmarkColumns() { add(text); add(params); add(paramsEdited); } + }; + BookmarkColumns bookmarkColumns; + + protected: + Gtk::ScrolledWindow* hscrollw; + Gtk::TreeView* hTreeView; + Glib::RefPtr historyModel; + + Gtk::ScrolledWindow* bscrollw; + Gtk::TreeView* bTreeView; + Glib::RefPtr bookmarkModel; + + Gtk::Button* addBookmark; + Gtk::Button* delBookmark; + + sigc::connection selchangehist; + sigc::connection selchangebm; + + HistoryBeforeLineListener * blistener; + ProfileChangeListener* tpc; + ParamsEdited defParamsEdited; + int bmnum; + + public: + + History (bool bookmarkSupport = true); + + void setProfileChangeListener (ProfileChangeListener* tpc_) { tpc = tpc_; } + void setHistoryBeforeLineListener (HistoryBeforeLineListener* bll) { blistener = bll; } + + // pparamschangelistener interface + void procParamsChanged (rtengine::procparams::ProcParams* params, rtengine::ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited=NULL); + void clearParamChanges (); + + void historySelectionChanged (); + void bookmarkSelectionChanged (); + void initHistory (); + + bool getBeforeLineParams (rtengine::procparams::ProcParams& params); + + void addBookmarkWithText (Glib::ustring text); + void addBookmarkPressed (); + void delBookmarkPressed (); + + void resized (Gtk::Allocation& req); + + void undo (); + void redo (); +}; + +#endif diff --git a/rtgui/hlrec.cc b/rtgui/hlrec.cc new file mode 100644 index 000000000..1c90d6533 --- /dev/null +++ b/rtgui/hlrec.cc @@ -0,0 +1,131 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +HLRecovery::HLRecovery () : ToolPanel() { + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLE"))); + enabled->set_active (false); + pack_start (*enabled); + + method = Gtk::manage (new Gtk::ComboBoxText ()); + method->append_text (M("TP_HLREC_LUMINANCE")); + method->append_text (M("TP_HLREC_CIELAB")); + method->append_text (M("TP_HLREC_COLOR")); + method->set_active (0); + Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ()); + Gtk::Label* lab = Gtk::manage (new Gtk::Label (M("TP_HLREC_METHOD"))); + hb->pack_start (*lab, Gtk::PACK_SHRINK, 4); + hb->pack_start (*method); + pack_start (*hb); + + enaconn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &HLRecovery::enabledChanged) ); + methconn = method->signal_changed().connect ( sigc::mem_fun(*this, &HLRecovery::methodChanged) ); + + show_all (); +} + +void HLRecovery::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + + if (pedited) + enabled->set_inconsistent (!pedited->hlrecovery.enabled); + enaconn.block (true); + enabled->set_active (pp->hlrecovery.enabled); + enaconn.block (false); + + if (pedited && !pedited->hlrecovery.method) + method->set_active (3); + else if (pp->hlrecovery.method=="Luminance") + method->set_active (0); + else if (pp->hlrecovery.method=="CIELab blending") + method->set_active (1); + else if (pp->hlrecovery.method=="Color") + method->set_active (2); + + lastEnabled = pp->hlrecovery.enabled; + + enableListener (); +} + +void HLRecovery::write (ProcParams* pp, ParamsEdited* pedited) { + + if (pedited) { + pedited->hlrecovery.method = method->get_active_row_number()!=3; + pedited->hlrecovery.enabled = !enabled->get_inconsistent(); + } + + pp->hlrecovery.enabled = enabled->get_active(); + if (method->get_active_row_number()==0) + pp->hlrecovery.method = "Luminance"; + else if (method->get_active_row_number()==1) + pp->hlrecovery.method = "CIELab blending"; + else if (method->get_active_row_number()==2) + pp->hlrecovery.method = "Color"; +} + +void HLRecovery::enabledChanged () { + + if (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaconn.block (true); + enabled->set_active (false); + enaconn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_active ()) + listener->panelChanged (EvHREnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvHREnabled, M("GENERAL_DISABLED")); + } +} + +void HLRecovery::methodChanged () { + + if (listener) { + if (enabled->get_active ()) + listener->panelChanged (EvHRMethod, method->get_active_text ()); + } +} + +void HLRecovery::setRaw (bool raw) { + + disableListener (); + set_sensitive (raw); + enableListener (); +} + +void HLRecovery::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + method->append_text (M("GENERAL_UNCHANGED")); +} diff --git a/rtgui/hlrec.h b/rtgui/hlrec.h new file mode 100644 index 000000000..86f490232 --- /dev/null +++ b/rtgui/hlrec.h @@ -0,0 +1,48 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _HLREC_H_ +#define _HLREC_H_ + +#include +#include + +class HLRecovery : public Gtk::VBox, public ToolPanel { + + protected: + Gtk::CheckButton* enabled; + Gtk::ComboBoxText* method; + sigc::connection methconn; + sigc::connection enaconn; + bool lastEnabled; + + public: + + HLRecovery (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void setRaw (bool raw); + + void enabledChanged (); + void methodChanged (); +}; + +#endif diff --git a/rtgui/iccfromwindows.txt b/rtgui/iccfromwindows.txt new file mode 100644 index 000000000..6e3b29c08 --- /dev/null +++ b/rtgui/iccfromwindows.txt @@ -0,0 +1,21 @@ ++#elif defined G_OS_WIN32 ++ if (config->display_profile_from_gdk) ++ { ++ HDC hdc = GetDC (NULL); ++ ++ if (hdc) ++ { ++ gchar *path; ++ gint32 len = 0; ++ ++ GetICMProfile (hdc, &len, NULL); ++ path = g_new (gchar, len); ++ ++ if (GetICMProfile (hdc, &len, path)) ++ profile = cmsOpenProfileFromFile (path, "r"); ++ ++ g_free (path); ++ ReleaseDC (NULL, hdc); ++ } ++ } + #endif diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc new file mode 100644 index 000000000..e51ca623e --- /dev/null +++ b/rtgui/icmpanel.cc @@ -0,0 +1,290 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +extern Options options; + +ICMPanel::ICMPanel () : ToolPanel(), icmplistener(NULL), iunchanged(NULL) { + +// set_border_width (4); + + ipDialog = Gtk::manage (new Gtk::FileChooserButton (M("TP_ICM_INPUTDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN)); + opDialog = Gtk::manage (new Gtk::FileChooserButton (M("TP_ICM_INPUTDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN)); + + Gtk::Label* ilab = Gtk::manage (new Gtk::Label ()); + ilab->set_alignment (0.0, 0.5); + ilab->set_markup (Glib::ustring("") + M("TP_ICM_INPUTPROFILE") + ""); + pack_start (*ilab, Gtk::PACK_SHRINK, 4); + + iembedded = Gtk::manage (new Gtk::RadioButton (M("TP_ICM_INPUTEMBEDDED"))); + pack_start (*iembedded, Gtk::PACK_SHRINK, 4); + + icamera = Gtk::manage (new Gtk::RadioButton (M("TP_ICM_INPUTCAMERA"))); + pack_start (*icamera, Gtk::PACK_SHRINK, 4); + + ifromfile = Gtk::manage (new Gtk::RadioButton (M("TP_ICM_INPUTCUSTOM")+":")); + Gtk::HBox* ffbox = Gtk::manage (new Gtk::HBox ()); + ffbox->pack_start (*ifromfile, Gtk::PACK_SHRINK); + ffbox->pack_start (*ipDialog); + + pack_start (*ffbox, Gtk::PACK_SHRINK, 4); + + opts = icamera->get_group(); + iembedded->set_group (opts); + ifromfile->set_group (opts); + + igamma = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_GAMMABEFOREINPUT"))); + igamma->set_sensitive (false); + pack_start (*igamma, Gtk::PACK_SHRINK, 4); + + saveRef = Gtk::manage (new Gtk::Button (M("TP_ICM_SAVEREFERENCE"))); + saveRef->set_image (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-save"), Gtk::ICON_SIZE_BUTTON))); + pack_start (*saveRef, Gtk::PACK_SHRINK, 4); + + + Gtk::HSeparator* hsep1 = Gtk::manage (new Gtk::HSeparator ()); + pack_start (*hsep1, Gtk::PACK_SHRINK, 2); + + Gtk::Label* wlab = Gtk::manage (new Gtk::Label ()); + wlab->set_alignment (0.0, 0.5); + wlab->set_markup (Glib::ustring("") + M("TP_ICM_WORKINGPROFILE") + ""); + + pack_start (*wlab, Gtk::PACK_SHRINK, 4); + wnames = Gtk::manage (new Gtk::ComboBoxText ()); + pack_start (*wnames, Gtk::PACK_SHRINK, 4); + + Gtk::HSeparator* hsep2 = Gtk::manage (new Gtk::HSeparator ()); + pack_start (*hsep2, Gtk::PACK_SHRINK, 2); + + Gtk::Label* olab = Gtk::manage (new Gtk::Label ()); + olab->set_alignment (0.0, 0.5); + olab->set_markup (Glib::ustring("") + M("TP_ICM_OUTPUTPROFILE") + ""); + + pack_start (*olab, Gtk::PACK_SHRINK, 4); + onames = Gtk::manage (new Gtk::ComboBoxText ()); + pack_start (*onames, Gtk::PACK_SHRINK, 4); + + std::vector wpnames = rtengine::getWorkingProfiles (); + for (int i=0; iappend_text (wpnames[i]); + + onames->append_text (M("TP_ICM_NOICM")); + onames->set_active (0); + + std::vector opnames = rtengine::getOutputProfiles (); + for (int i=0; iappend_text (opnames[i]); + + wnames->set_active (0); + onames->set_active (0); + + Gtk::FileFilter filter_icc; + filter_icc.set_name(M("TP_ICM_FILEDLGFILTERICM")); + filter_icc.add_pattern("*.icc"); + filter_icc.add_pattern("*.icm"); + filter_icc.add_pattern("*.ICC"); + filter_icc.add_pattern("*.ICM"); + Gtk::FileFilter filter_any; + filter_any.set_name(M("TP_ICM_FILEDLGFILTERANY")); + filter_any.add_pattern("*"); + + ipDialog->add_filter (filter_icc); + ipDialog->add_filter (filter_any); + opDialog->add_filter (filter_icc); + opDialog->add_filter (filter_any); + + if (Glib::file_test (options.rtSettings.iccDirectory, Glib::FILE_TEST_IS_DIR)) { + ipDialog->set_current_folder (options.rtSettings.iccDirectory); + opDialog->set_current_folder (options.rtSettings.iccDirectory); + } + + oldip = ""; + + wnames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::wpChanged) ); + onames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::opChanged) ); + icamera->signal_toggled().connect( sigc::mem_fun(*this, &ICMPanel::ipChanged) ); + iembedded->signal_toggled().connect( sigc::mem_fun(*this, &ICMPanel::ipChanged) ); + ifromfile->signal_toggled().connect( sigc::mem_fun(*this, &ICMPanel::ipChanged) ); + ipc = ipDialog->signal_selection_changed().connect( sigc::mem_fun(*this, &ICMPanel::ipSelectionChanged) ); + saveRef->signal_pressed().connect( sigc::mem_fun(*this, &ICMPanel::saveReferencePressed) ); + + show_all (); +} + +void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + ipc.block (true); + if (pp->icm.input == "(embedded)" || ((pp->icm.input == "(camera)" || pp->icm.input=="") && icamera->get_state()==Gtk::STATE_INSENSITIVE)) { + iembedded->set_active (true); + igamma->set_sensitive (false); + } + else if ((pp->icm.input == "(camera)" || pp->icm.input=="") && icamera->get_state()!=Gtk::STATE_INSENSITIVE) { + icamera->set_active (true); + igamma->set_sensitive (false); + } + else { + ifromfile->set_active (true); + oldip = pp->icm.input.substr(5); + ipDialog->set_filename (pp->icm.input.substr(5)); + igamma->set_sensitive (true); + } + + wnames->set_active_text (pp->icm.working); + if (pp->icm.output=="No ICM: sRGB output") + onames->set_active_text (M("TP_ICM_NOICM")); + else + onames->set_active_text (pp->icm.output); + + if (onames->get_active_row_number()==-1) + onames->set_active_text (M("TP_ICM_NOICM")); + + igamma->set_active (pp->icm.gammaOnInput); + + if (pedited) { + iunchanged->set_active (!pedited->icm.input); + igamma->set_sensitive (false); + if (!pedited->icm.working) + wnames->set_active_text(M("GENERAL_UNCHANGED")); + if (!pedited->icm.output) + onames->set_active_text(M("GENERAL_UNCHANGED")); + } + + ipc.block (false); + + enableListener (); +} + +void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) { + + if (iembedded->get_active ()) + pp->icm.input = "(embedded)"; + else if (icamera->get_active ()) + pp->icm.input = "(camera)"; + else + pp->icm.input = "file:"+ipDialog->get_filename (); + + pp->icm.working = wnames->get_active_text (); + + if (onames->get_active_text()==M("TP_ICM_NOICM")) + pp->icm.output = "No ICM: sRGB output"; + else + pp->icm.output = onames->get_active_text(); + pp->icm.gammaOnInput = igamma->get_active (); + + if (pedited) { + pedited->icm.input = !iunchanged->get_active (); + pedited->icm.working = wnames->get_active_text()!=M("GENERAL_UNCHANGED"); + pedited->icm.output = onames->get_active_text()!=M("GENERAL_UNCHANGED"); + pedited->icm.gammaOnInput = !ifromfile->get_active (); + } +} + +void ICMPanel::wpChanged () { + + if (listener) + listener->panelChanged (EvWProfile, wnames->get_active_text ()); +} + +void ICMPanel::ipChanged () { + + std::string profname; + if (iembedded->get_active ()) { + profname = "(embedded)"; + igamma->set_sensitive (false); + } + else if (icamera->get_active ()) { + profname = "(camera)"; + igamma->set_sensitive (false); + } + else { + profname = ipDialog->get_filename (); + igamma->set_sensitive (true); + } + + if (listener && profname!=oldip) + listener->panelChanged (EvIProfile, profname); + + oldip = profname; +} + +void ICMPanel::opChanged () { + + if (listener) + listener->panelChanged (EvOProfile, onames->get_active_text()); +} + +void ICMPanel::setRaw (bool raw) { + + disableListener (); + + icamera->set_active (raw); + iembedded->set_active (!raw); + icamera->set_sensitive (raw); + iembedded->set_sensitive (!raw); + + enableListener (); +} + +void ICMPanel::ipSelectionChanged () { + + if (ipDialog->get_filename () == "") + return; + else + ipChanged (); + +} +void ICMPanel::saveReferencePressed () { + + if (!icmplistener) + return; + Gtk::FileChooserDialog dialog(M("TP_ICM_SAVEREFERENCEDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_SAVE); + + dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); + dialog.add_button(Gtk::StockID("gtk-save"), Gtk::RESPONSE_OK); + + Gtk::FileFilter filter_jpg; + filter_jpg.set_name(M("SAVEDLG_JPGFILTER")); + filter_jpg.add_pattern("*.jpg"); + dialog.add_filter(filter_jpg); + + dialog.set_do_overwrite_confirmation (true); + + if (dialog.run()==Gtk::RESPONSE_OK) + icmplistener->saveInputICCReference (dialog.get_filename()); + +} +void ICMPanel::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + iunchanged = Gtk::manage (new Gtk::RadioButton (M("GENERAL_UNCHANGED"))); + iunchanged->set_group (opts); + pack_start (*iunchanged, Gtk::PACK_SHRINK, 4); + reorder_child (*iunchanged, 5); + removeIfThere (this, saveRef); + onames->append_text (M("GENERAL_UNCHANGED")); + wnames->append_text (M("GENERAL_UNCHANGED")); +} + diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h new file mode 100644 index 000000000..072ecfff3 --- /dev/null +++ b/rtgui/icmpanel.h @@ -0,0 +1,70 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _ICMPANEL_ +#define _ICMPANEL_ + +#include +#include + +class ICMPanelListener { + + public: + virtual void saveInputICCReference (Glib::ustring fname) {} +}; + +class ICMPanel : public Gtk::VBox, public ToolPanel { + + private: + Gtk::RadioButton* iembedded; + Gtk::RadioButton* icamera; + Gtk::RadioButton* ifromfile; + Gtk::CheckButton* igamma; + Gtk::ComboBoxText* wnames; + Gtk::ComboBoxText* onames; + Gtk::RadioButton* ofromdir; + Gtk::RadioButton* ofromfile; + Gtk::RadioButton* iunchanged; + Gtk::FileChooserButton* ipDialog; + Gtk::FileChooserButton* opDialog; + Gtk::RadioButton::Group opts; + Gtk::Button* saveRef; + sigc::connection ipc; + Glib::ustring oldip; + ICMPanelListener* icmplistener; + + public: + ICMPanel (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void wpChanged (); + void opChanged (); + void ipChanged (); + + void ipSelectionChanged (); + + void setRaw (bool raw); + void saveReferencePressed (); + + void setICMPanelListener (ICMPanelListener* ipl) { icmplistener = ipl; } +}; + +#endif diff --git a/rtgui/ilabel.cc b/rtgui/ilabel.cc new file mode 100644 index 000000000..c576498b9 --- /dev/null +++ b/rtgui/ilabel.cc @@ -0,0 +1,63 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include + +ILabel::ILabel (Glib::ustring lab) : label(lab) {} + +void ILabel::on_realize() { + + Gtk::DrawingArea::on_realize(); + add_events(Gdk::EXPOSURE_MASK); + + Glib::RefPtr fn = create_pango_layout(label); + fn->set_markup (label); + int labw, labh; + fn->get_pixel_size (labw, labh); + set_size_request (2+labw,2+labh); + + signal_style_changed().connect( sigc::mem_fun(*this, &ILabel::styleChanged) ); +} + +bool ILabel::on_expose_event (GdkEventExpose* event) { + + Glib::RefPtr style = get_style (); + Glib::RefPtr window = get_window(); + Glib::RefPtr gc_ = style->get_bg_gc(get_state()); + Cairo::RefPtr cr = window->create_cairo_context(); + + Gdk::Color c = style->get_fg (get_state()); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->rectangle (0, 0, get_width (), get_height()); + cr->fill (); + + Glib::RefPtr fn = create_pango_layout (label); + fn->set_markup (label); + window->draw_layout(gc_, 1, 1, fn); + + return true; +} + +void ILabel::styleChanged (const Glib::RefPtr& style) { + + Glib::RefPtr fn = create_pango_layout(label); + fn->set_markup (label); + int labw, labh; + fn->get_pixel_size (labw, labh); + set_size_request (2+labw,2+labh); +} diff --git a/rtgui/ilabel.h b/rtgui/ilabel.h new file mode 100644 index 000000000..50a6fd942 --- /dev/null +++ b/rtgui/ilabel.h @@ -0,0 +1,36 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _ILABEL_ +#define _ILABEL_ + +#include + +class ILabel : public Gtk::DrawingArea { + + Glib::ustring label; + + public: + ILabel (Glib::ustring lab); + bool on_expose_event(GdkEventExpose* event); + void on_realize(); + void styleChanged (const Glib::RefPtr& style); +}; + +#endif + diff --git a/rtgui/imagearea.cc b/rtgui/imagearea.cc new file mode 100644 index 000000000..572a2b701 --- /dev/null +++ b/rtgui/imagearea.cc @@ -0,0 +1,418 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include + +ImageArea::ImageArea (ImageAreaPanel* p) : parent(p) { + + showInfo = false; + infotext = ""; + cropgl = NULL; + pmlistener = NULL; + focusGrabber = NULL; + mainCropWindow = NULL; + previewHandler = NULL; + lastClosedX = -1; + showClippedH = false; + showClippedS = false; + listener = NULL; + + zoomPanel = Gtk::manage (new ZoomPanel (this)); + indClippedPanel = Gtk::manage (new IndicateClippedPanel (this)); + + signal_style_changed().connect( sigc::mem_fun(*this, &ImageArea::styleChanged) ); + signal_size_allocate().connect( sigc::mem_fun(*this, &ImageArea::on_resized) ); + + dirty = false; +} + +void ImageArea::on_realize() +{ + Gtk::DrawingArea::on_realize(); + + add_events(Gdk::EXPOSURE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::POINTER_MOTION_HINT_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::SCROLL_MASK); + + Cairo::FontOptions cfo; + cfo.set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + get_pango_context ()->set_cairo_font_options (cfo); +} + +void ImageArea::on_resized (Gtk::Allocation& req) { + + if (ipc && !mainCropWindow) { + mainCropWindow = new CropWindow (this, ipc); + mainCropWindow->setDecorated (false); + mainCropWindow->setFitZoomEnabled (true); + mainCropWindow->setPosition (0, 0); + mainCropWindow->setSize (get_width(), get_height()); + mainCropWindow->addCropWindowListener (this); + mainCropWindow->setCropGUIListener (cropgl); + mainCropWindow->setPointerMotionListener (pmlistener); + } + else if (ipc) { + mainCropWindow->setSize (get_width(), get_height()); + } +} + +void ImageArea::setImProcCoordinator (rtengine::StagedImageProcessor* ipc_) { + + ipc = ipc_; +} + +void ImageArea::setPreviewHandler (PreviewHandler* ph) { + + previewHandler = ph; +} + + +ImageArea::~ImageArea () { + + for (std::list::iterator i=cropWins.begin(); i!=cropWins.end(); i++) + delete *i; + cropWins.clear (); + + if (mainCropWindow) + delete mainCropWindow; +} + +void ImageArea::styleChanged (const Glib::RefPtr& style) { + + // TODO: notify all crop windows that the style has been changed + queue_draw (); +} + +void ImageArea::setInfoText (Glib::ustring text) { + + infotext = text; + + Glib::RefPtr context = get_pango_context () ; + Pango::FontDescription fontd = context->get_font_description (); + fontd.set_weight (Pango::WEIGHT_BOLD); + fontd.set_size (12*Pango::SCALE); + context->set_font_description (fontd); + ilayout = create_pango_layout(text); + int iw, ih; + ilayout->get_pixel_size (iw, ih); + ipixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, true, 8, iw+8, ih+8); + ipixbuf->fill (128); +} + +void ImageArea::infoEnabled (bool e) { + + if (showInfo!=e) { + showInfo = e; + queue_draw (); + } +} + +CropWindow* ImageArea::getCropWindow (int x, int y) { + + CropWindow* cw = mainCropWindow; + for (std::list::iterator i=cropWins.begin(); i!=cropWins.end(); i++) + if ((*i)->isInside (x, y)) + return *i; + return cw; +} + +bool ImageArea::on_expose_event(GdkEventExpose* event) { + dirty = false; + + if (event->count) + return true; + + Glib::RefPtr window = get_window(); + Cairo::RefPtr cr = get_window()->create_cairo_context(); + + if (mainCropWindow) + mainCropWindow->expose (cr); + + if (showInfo==true && infotext!="") { + int fnw, fnh; + ilayout->get_pixel_size (fnw, fnh); + window->draw_pixbuf (get_style()->get_base_gc (Gtk::STATE_NORMAL), ipixbuf, 0, 0, 4, 4, fnw+8, fnh+8, Gdk::RGB_DITHER_NONE, 0, 0); + cr->set_source_rgb (1.0, 1.0, 1.0); + cr->move_to (8, 8); + ilayout->add_to_cairo_context (cr); + cr->fill (); + } + + for (std::list::reverse_iterator i=cropWins.rbegin(); i!=cropWins.rend(); i++) + (*i)->expose (cr); + + return true; +} + + +bool ImageArea::on_motion_notify_event (GdkEventMotion* event) { + + if (focusGrabber) + focusGrabber->pointerMoved (event->x, event->y); + else { + CropWindow* cw = getCropWindow (event->x, event->y); + if (cw) + cw->pointerMoved (event->x, event->y); + } + return true; +} + +bool ImageArea::on_button_press_event (GdkEventButton* event) { + + if (focusGrabber) + focusGrabber->buttonPress (event->button, event->type, event->state, event->x, event->y); + else { + CropWindow* cw = getCropWindow (event->x, event->y); + if (cw) + cw->buttonPress (event->button, event->type, event->state, event->x, event->y); + } + return true; +} + +bool ImageArea::on_scroll_event (GdkEventScroll* event) { + + CropWindow* cw = getCropWindow (event->x, event->y); + if (cw) { + if (event->direction==GDK_SCROLL_UP) + cw->zoomIn (); + else + cw->zoomOut (); + return true; + } + return true; +} + +bool ImageArea::on_button_release_event (GdkEventButton* event) { + + if (focusGrabber) + focusGrabber->buttonRelease (event->button, event->type, event->state, event->x, event->y); + else { + CropWindow* cw = getCropWindow (event->x, event->y); + if (cw) { + cw->buttonRelease (event->button, event->type, event->state, event->x, event->y); + } + } + return true; +} + + +void ImageArea::grabFocus (CropWindow* cw) { + + focusGrabber = cw; + if (cw && cw!=mainCropWindow) + cropWindowSelected (cw); +} + +void ImageArea::unGrabFocus () { + + focusGrabber = NULL; +} + +void ImageArea::addCropWindow () { + + CropWindow* cw = new CropWindow (this, ipc); + cw->setCropGUIListener (cropgl); + cw->setPointerMotionListener (pmlistener); + cropWins.push_front (cw); + + if (lastClosedX<0) { + int K = 2; + int hBorder = get_width()/K/8; + int vBorder = get_height()/K/8; + int N = cropWins.size()-1; + int layer = N/K/K; + int row = K-1 - (N % (K*K)) / K; + int col = K-1 - (N % (K*K)) % K; + + cw->setSize (get_width()/K - hBorder, get_height()/K - vBorder); + cw->setPosition (col*get_width()/K + hBorder/2 + layer*30, row*get_height()/K + vBorder/2 + layer*30); + } + else { + cw->setSize (lastClosedX, lastClosedY); + cw->setPosition (lastClosedW, lastClosedH); + } + + mainCropWindow->setObservedCropWin (cropWins.front()); + queue_draw (); +} + + +void ImageArea::cropWindowSelected (CropWindow* cw) { + + std::list::iterator i = std::find (cropWins.begin(), cropWins.end(), cw); + if (i!=cropWins.end()) + cropWins.erase (i); + cropWins.push_front (cw); + mainCropWindow->setObservedCropWin (cropWins.front()); +} + +void ImageArea::cropWindowClosed (CropWindow* cw) { + + focusGrabber = NULL; + cw->getPosition (lastClosedX, lastClosedY); + cw->getSize (lastClosedW, lastClosedH); + std::list::iterator i = std::find (cropWins.begin(), cropWins.end(), cw); + if (i!=cropWins.end()) + cropWins.erase (i); + delete cw; + if (!cropWins.empty()) + mainCropWindow->setObservedCropWin (cropWins.front()); + else + mainCropWindow->setObservedCropWin (NULL); + queue_draw (); +} + +void ImageArea::straightenReady (double rotDeg) { + + if (listener) + listener->rotateSelectionReady (rotDeg); +} + +void ImageArea::spotWBSelected (int x, int y) { + + if (listener) + listener->spotWBselected (x, y); +} + +void ImageArea::redraw () { + + if (!dirty) { + dirty = true; + queue_draw (); + } +} + +void ImageArea::getScrollImageSize (int& w, int& h) { + + if (mainCropWindow && ipc) { + double z = mainCropWindow->getZoom (); + w = ipc->getFullWidth() * z; + h = ipc->getFullHeight() * z; + } + else + w = h = 0; +} + +void ImageArea::getScrollPosition (int& x, int& y) { + + if (mainCropWindow) { + int cropX, cropY; + mainCropWindow->getCropPosition (cropX, cropY); + x = cropX*mainCropWindow->getZoom (); + y = cropY*mainCropWindow->getZoom (); + } + else + x = y = 0; +} + +void ImageArea::setScrollPosition (int x, int y) { + + if (mainCropWindow) { + mainCropWindow->delCropWindowListener (this); + mainCropWindow->setCropPosition (x/mainCropWindow->getZoom (), y/mainCropWindow->getZoom ()); + mainCropWindow->addCropWindowListener (this); + } +} + +void ImageArea::cropPositionChanged (CropWindow* cw) { + + updateScrollbars (); +} + +void ImageArea::cropWindowSizeChanged (CropWindow* cw) { + + updateScrollbars (); +} + +void ImageArea::cropZoomChanged (CropWindow* cw) { + + if (cw==mainCropWindow) { + parent->zoomChanged (); + updateScrollbars (); + zoomPanel->refreshZoomLabel (); + } +} + +double ImageArea::getZoom () { + + if (mainCropWindow) + return mainCropWindow->getZoom (); + else + return 1.0; +} + +void ImageArea::setZoom (double zoom) { + + if (mainCropWindow) + mainCropWindow->setZoom (zoom); + zoomPanel->refreshZoomLabel (); +} + +void ImageArea::initialImageArrived (CropWindow* cw) { + + if (mainCropWindow) + mainCropWindow->zoomFit (); +} + +void ImageArea::updateScrollbars () { + parent->refreshScrollBars (); +} + +void ImageArea::setCropGUIListener (CropGUIListener* l) { + + cropgl = l; + for (std::list::iterator i=cropWins.begin(); i!=cropWins.end(); i++) + (*i)->setCropGUIListener (cropgl); + if (mainCropWindow) + mainCropWindow->setCropGUIListener (cropgl); +} + +void ImageArea::setPointerMotionListener (PointerMotionListener* pml) { + + pmlistener = pml; + for (std::list::iterator i=cropWins.begin(); i!=cropWins.end(); i++) + (*i)->setPointerMotionListener (pml); + if (mainCropWindow) + mainCropWindow->setPointerMotionListener (pml); +} + +ToolMode ImageArea::getToolMode () { + + if (listener) + return listener->getToolBar()->getTool (); + else + return TMHand; +} + +void ImageArea::setToolHand () { + + if (listener) + listener->getToolBar()->setTool (TMHand); +} + +int ImageArea::getSpotWBRectSize () { + + if (listener) + return listener->getSpotWBRectSize (); + else + return 1; +} diff --git a/rtgui/imagearea.h b/rtgui/imagearea.h new file mode 100644 index 000000000..bb7163e40 --- /dev/null +++ b/rtgui/imagearea.h @@ -0,0 +1,125 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef __IMAGEAREA_H__ +#define __IMAGEAREA_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class ImageAreaPanel; +class ImageArea : public Gtk::DrawingArea, public CropWindowListener { + + friend class ZoomPanel; + + protected: + + bool showInfo; + Glib::ustring infotext; + Glib::RefPtr ilayout; + Glib::RefPtr deglayout; + Glib::RefPtr ipixbuf; + bool showClippedH, showClippedS; + + ImageAreaPanel* parent; + CropWindow* mainCropWindow; + std::list cropWins; + PreviewHandler* previewHandler; + rtengine::StagedImageProcessor* ipc; + + int lastClosedX, lastClosedY, lastClosedW, lastClosedH; + + bool dirty; + CropWindow* focusGrabber; + CropGUIListener* cropgl; + PointerMotionListener* pmlistener; + ImageAreaToolListener* listener; + + CropWindow* getCropWindow (int x, int y); + + public: + + ZoomPanel* zoomPanel; + IndicateClippedPanel* indClippedPanel; + + ImageArea (ImageAreaPanel* p); + ~ImageArea (); + + void setImProcCoordinator (rtengine::StagedImageProcessor* ipc_); + + void getScrollImageSize (int& w, int& h); + void getScrollPosition (int& x, int& y); + void setScrollPosition (int x, int y); // called by the imageareapanel when the scrollbars have been changed + + // enabling and setting text of info area + void setInfoText (Glib::ustring text); + void infoEnabled (bool e); + + // widget base events + void on_realize (); + bool on_expose_event (GdkEventExpose* event); + bool on_motion_notify_event (GdkEventMotion* event); + bool on_button_press_event (GdkEventButton* event); + bool on_button_release_event (GdkEventButton* event); + bool on_scroll_event (GdkEventScroll* event); + void on_resized (Gtk::Allocation& req); + void styleChanged (const Glib::RefPtr& style); + void updateScrollbars (); + + void setCropGUIListener (CropGUIListener* l); + void setPointerMotionListener (PointerMotionListener* pml); + void setImageAreaToolListener (ImageAreaToolListener* l) { listener = l; } + void setPreviewHandler (PreviewHandler* ph); + PreviewHandler* getPreviewHandler () { return previewHandler; } + + void grabFocus (CropWindow* cw); + void unGrabFocus (); + void addCropWindow (); + void cropWindowSelected (CropWindow* cw); + void cropWindowClosed (CropWindow* cw); + ToolMode getToolMode (); + void setToolHand (); + void straightenReady (double rotDeg); + void spotWBSelected (int x, int y); + int getSpotWBRectSize (); + void redraw (); + + void zoomFit (); + double getZoom (); + void setZoom (double zoom); + + // cropwindowlistener interface + void cropPositionChanged (CropWindow* cw); + void cropWindowSizeChanged (CropWindow* cw); + void cropZoomChanged (CropWindow* cw); + void initialImageArrived (CropWindow* cw) ; + + CropWindow* getMainCropWindow () { return mainCropWindow; } +}; + + + +#endif diff --git a/rtgui/imageareapanel.cc b/rtgui/imageareapanel.cc new file mode 100644 index 000000000..ecafd0446 --- /dev/null +++ b/rtgui/imageareapanel.cc @@ -0,0 +1,173 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include + +ImageAreaPanel::ImageAreaPanel () : before(NULL), after(NULL) { + + set_border_width (2); + + Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ()); + Gtk::HBox* hb2 = Gtk::manage (new Gtk::HBox ()); + hscroll = Gtk::manage (new Gtk::HScrollbar ()); + vscroll = Gtk::manage (new Gtk::VScrollbar ()); + imageArea = new ImageArea (this); + Gtk::Frame* frame = Gtk::manage (new Gtk::Frame ()); + frame->add (*imageArea); + frame->set_shadow_type (Gtk::SHADOW_IN ); + hb1->pack_start (*frame); + hb1->pack_end (*vscroll, Gtk::PACK_SHRINK, 0); + + pack_start (*hb1); + vscroll->show (); + frame->show (); + imageArea->show (); + hb1->show (); + + Gtk::HBox* tmp = Gtk::manage (new Gtk::HBox ()); + hb2->pack_start (*hscroll); + Gtk::Requisition vcr = vscroll->size_request (); + tmp->set_size_request (vcr.width, vcr.width); + hb2->pack_end (*tmp, Gtk::PACK_SHRINK, 0); + + pack_start (*hb2,Gtk::PACK_SHRINK, 0); + hscroll->show (); + tmp->show (); + hb2->show (); + + hscroll->set_update_policy (Gtk::UPDATE_CONTINUOUS); + vscroll->set_update_policy (Gtk::UPDATE_CONTINUOUS); + + vscrollconn = vscroll->signal_value_changed().connect( sigc::mem_fun(*this, &ImageAreaPanel::scrollChanged) ); + hscrollconn = hscroll->signal_value_changed().connect( sigc::mem_fun(*this, &ImageAreaPanel::scrollChanged) ); + + imageArea->signal_size_allocate().connect( sigc::mem_fun(*this, &ImageAreaPanel::imageAreaResized) ); +} + +ImageAreaPanel::~ImageAreaPanel () { + + delete imageArea; +} + +void ImageAreaPanel::configScrollBars () { + + int imgw, imgh; + imageArea->getScrollImageSize (imgw, imgh); + + if (imgw>0 && imgh>0) { + + int iw = imageArea->get_width (); + int ih = imageArea->get_height (); + + hscrollconn.block (true); + vscrollconn.block (true); + + hscroll->get_adjustment()->set_upper (imgw); + vscroll->get_adjustment()->set_upper (imgh); + hscroll->get_adjustment()->set_lower (0); + vscroll->get_adjustment()->set_lower (0); + hscroll->get_adjustment()->set_step_increment (imgw/100); + vscroll->get_adjustment()->set_step_increment (imgh/100); + hscroll->get_adjustment()->set_page_increment (imgw/5); + vscroll->get_adjustment()->set_page_increment (imgh/5); + hscroll->get_adjustment()->set_page_size (iw); + vscroll->get_adjustment()->set_page_size (ih); + + int x, y; + imageArea->getScrollPosition (x, y); + hscroll->set_value (x); + vscroll->set_value (y); + + if (before && this==after) + before->synchronize (); + else if (after && this==before) + after->synchronize (); + + hscrollconn.block (false); + vscrollconn.block (false); + } +} + +void ImageAreaPanel::refreshScrollBars () { + + configScrollBars (); + queue_draw (); +} + +void ImageAreaPanel::imageAreaResized (Gtk::Allocation& req) { + + configScrollBars (); + queue_draw (); +} + +void ImageAreaPanel::scrollChanged () { + + imageArea->setScrollPosition ((int)(hscroll->get_value()), (int)(vscroll->get_value())); + imageArea->queue_draw (); +#ifdef _WIN32 + gdk_window_process_updates (get_window()->gobj(), true); +#endif + if (before && this==after) + before->synchronize (); + else if (after && this==before) + after->synchronize (); +} + +void ImageAreaPanel::setBeforeAfterViews (ImageAreaPanel* bef, ImageAreaPanel* aft) { + + before = bef; + after = aft; + configScrollBars (); +} + +void ImageAreaPanel::zoomChanged () { + + if (after && this==before) + after->imageArea->setZoom (imageArea->getZoom ()); + else if (before && this==after) + before->imageArea->setZoom (imageArea->getZoom ()); +} + +void ImageAreaPanel::synchronize () { + + hscrollconn.block (true); + vscrollconn.block (true); + + if (after && this==before) { + int imgw, imgh, x, y; + after->imageArea->getScrollImageSize (imgw, imgh); + after->imageArea->getScrollPosition (x, y); + int bimgw, bimgh; + imageArea->getScrollImageSize (bimgw, bimgh); + imageArea->setScrollPosition (x*bimgw/imgw, y*bimgh/imgh); + imageArea->queue_draw (); + } + else if (before && this==after) { + int imgw, imgh, x, y; + before->imageArea->getScrollImageSize (imgw, imgh); + before->imageArea->getScrollPosition (x, y); + int bimgw, bimgh; + imageArea->getScrollImageSize (bimgw, bimgh); + imageArea->setScrollPosition (x*bimgw/imgw, y*bimgh/imgh); + imageArea->queue_draw (); + } + + hscrollconn.block (false); + vscrollconn.block (false); +} + diff --git a/rtgui/imageareapanel.h b/rtgui/imageareapanel.h new file mode 100644 index 000000000..50a1d4644 --- /dev/null +++ b/rtgui/imageareapanel.h @@ -0,0 +1,53 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _IMAGEAREAPANEL_ +#define _IMAGEAREAPANEL_ + +#include + +class ImageArea; +class ImageAreaPanel : public Gtk::VBox { + + protected: + Gtk::HScrollbar* hscroll; + Gtk::VScrollbar* vscroll; + sigc::connection hscrollconn; + sigc::connection vscrollconn; + + void synchronize (); + void configScrollBars (); + + ImageAreaPanel *before, *after; + + public: + ImageArea* imageArea; + + ImageAreaPanel (); + ~ImageAreaPanel (); + + void scrollChanged (); + void imageAreaResized (Gtk::Allocation& req); + + void refreshScrollBars (); + void zoomChanged (); + + void setBeforeAfterViews (ImageAreaPanel* bef, ImageAreaPanel* aft); +}; + +#endif diff --git a/rtgui/imageareatoollistener.h b/rtgui/imageareatoollistener.h new file mode 100644 index 000000000..a1d1d7ac1 --- /dev/null +++ b/rtgui/imageareatoollistener.h @@ -0,0 +1,38 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _IMAGEAREATOOLLISTENER_ +#define _IMAGEAREATOOLLISTENER_ + +#include +#include +#include + +class ImageAreaToolListener { + + public: + virtual void spotWBselected (int x, int y, Thumbnail* thm=NULL) {} + virtual int getSpotWBRectSize () { return 8; } + virtual void cropSelectionReady () {} + virtual void rotateSelectionReady (double rotate_deg, Thumbnail* thm=NULL) {} + virtual ToolBar* getToolBar () { return NULL; } + virtual CropGUIListener* startCropEditing (Thumbnail* thm=NULL) { return NULL; } +}; + +#endif + diff --git a/rtgui/indclippedpanel.cc b/rtgui/indclippedpanel.cc new file mode 100644 index 000000000..61924c60c --- /dev/null +++ b/rtgui/indclippedpanel.cc @@ -0,0 +1,51 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include + +IndicateClippedPanel::IndicateClippedPanel (ImageArea* ia) : imageArea(ia) { + + indclippedh = Gtk::manage (new Gtk::ToggleButton ()); + indclippedh->set_relief(Gtk::RELIEF_NONE); + indclippedh->add (*Gtk::manage (new Gtk::Image (argv0+"/images/warnhl.png"))); + indclippedh->set_tooltip_text (M("MAIN_TOOLTIP_INDCLIPPEDH")); + + indclippeds = Gtk::manage (new Gtk::ToggleButton ()); + indclippeds->set_relief(Gtk::RELIEF_NONE); + indclippeds->add (*Gtk::manage (new Gtk::Image (argv0+"/images/warnsh.png"))); + indclippeds->set_tooltip_text (M("MAIN_TOOLTIP_INDCLIPPEDS")); + + indclippedh->set_active (options.showClippedHighlights); + indclippeds->set_active (options.showClippedShadows); + + pack_start (*indclippedh, Gtk::PACK_SHRINK, 0); + pack_start (*indclippeds, Gtk::PACK_SHRINK, 0); + + indclippedh->signal_toggled().connect( sigc::mem_fun(*this, &IndicateClippedPanel::buttonToggled) ); + indclippeds->signal_toggled().connect( sigc::mem_fun(*this, &IndicateClippedPanel::buttonToggled) ); + + show_all (); +} + +void IndicateClippedPanel::buttonToggled () { + + imageArea->queue_draw (); +} diff --git a/rtgui/indclippedpanel.h b/rtgui/indclippedpanel.h new file mode 100644 index 000000000..8acaccdf9 --- /dev/null +++ b/rtgui/indclippedpanel.h @@ -0,0 +1,41 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _INDCLIPPEDPANEL_ +#define _INDCLIPPEDPANEL_ + +#include + +class ImageArea; +class IndicateClippedPanel : public Gtk::HBox { + + protected: + Gtk::ToggleButton* indclippedh; + Gtk::ToggleButton* indclippeds; + ImageArea* imageArea; + + public: + IndicateClippedPanel (ImageArea* ia); + + void buttonToggled (); + + bool showClippedShadows () { return indclippeds->get_active (); } + bool showClippedHighlights () { return indclippedh->get_active (); } +}; + +#endif diff --git a/rtgui/iptcpanel.cc b/rtgui/iptcpanel.cc new file mode 100644 index 000000000..9c3eb7996 --- /dev/null +++ b/rtgui/iptcpanel.cc @@ -0,0 +1,600 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +extern Glib::ustring argv0; + +using namespace rtengine; +using namespace rtengine::procparams; + +IPTCPanel::IPTCPanel () { + + set_border_width (2); + + Gtk::Table* iptc = new Gtk::Table (27, 2); + + int row = 0; + + Gtk::Label* capl = new Gtk::Label (M("IPTCPANEL_CAPTION")+":"); + captionText = Gtk::TextBuffer::create (); + captionView = new Gtk::TextView (captionText); + Gtk::ScrolledWindow* scrolledWindowc = new Gtk::ScrolledWindow(); + scrolledWindowc->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); + scrolledWindowc->add(*captionView); + capl->set_tooltip_text (M("IPTCPANEL_CAPTIONHINT")); + captionView->set_tooltip_text (M("IPTCPANEL_CAPTIONHINT")); + iptc->attach (*capl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*scrolledWindowc, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* capwl = new Gtk::Label (M("IPTCPANEL_CAPTIONWRITER")+":"); + captionWriter = new Gtk::Entry (); + capwl->set_tooltip_text (M("IPTCPANEL_CAPTIONWRITERHINT")); + captionWriter->set_tooltip_text (M("IPTCPANEL_CAPTIONWRITERHINT")); + iptc->attach (*capwl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*captionWriter, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* headl = new Gtk::Label (M("IPTCPANEL_HEADLINE")+":"); + headline = new Gtk::Entry (); + headl->set_tooltip_text (M("IPTCPANEL_HEADLINEHINT")); + headline->set_tooltip_text (M("IPTCPANEL_HEADLINEHINT")); + iptc->attach (*headl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*headline, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* instl = new Gtk::Label (M("IPTCPANEL_INSTRUCTIONS")+":"); + instructions = new Gtk::Entry (); + instl->set_tooltip_text (M("IPTCPANEL_INSTRUCTIONSHINT")); + instructions->set_tooltip_text (M("IPTCPANEL_INSTRUCTIONSHINT")); + iptc->attach (*instl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*instructions, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::HSeparator* hsep1 = new Gtk::HSeparator (); + iptc->attach (*hsep1, 0, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* keyl = new Gtk::Label (M("IPTCPANEL_KEYWORDS")+":"); + keywords = new Gtk::ListViewText (1, false, Gtk::SELECTION_MULTIPLE); + keywords->set_headers_visible (false); + Gtk::ScrolledWindow* scrolledWindowkw = new Gtk::ScrolledWindow(); + scrolledWindowkw->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); + scrolledWindowkw->add(*keywords); + keyword = new Gtk::ComboBoxEntryText (); + keyword->set_size_request (32, -1); + keyl->set_tooltip_text (M("IPTCPANEL_KEYWORDSHINT")); + keywords->set_tooltip_text (M("IPTCPANEL_KEYWORDSHINT")); + keyword->set_tooltip_text (M("IPTCPANEL_KEYWORDSHINT")); + addKW = new Gtk::Button (); + delKW = new Gtk::Button (); + Gtk::Image* addKWImg = new Gtk::Image (argv0+"/images/list-add12.png"); + Gtk::Image* delKWImg = new Gtk::Image (argv0+"/images/list-remove12r.png"); + addKW->add (*addKWImg); + delKW->add (*delKWImg); + Gtk::HBox* kwhb = new Gtk::HBox (); + kwhb->pack_start (*keyword); + kwhb->pack_start (*addKW, Gtk::PACK_SHRINK, 2); + kwhb->pack_start (*delKW, Gtk::PACK_SHRINK, 2); + iptc->attach (*keyl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*kwhb, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + row++; + iptc->attach (*scrolledWindowkw, 0, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + row++; + + Gtk::HSeparator* hsep2 = new Gtk::HSeparator (); + iptc->attach (*hsep2, 0, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + row++; + + Gtk::Label* catl = new Gtk::Label (M("IPTCPANEL_CATEGORY")+":"); + category = new Gtk::ComboBoxEntryText (); + category->set_size_request (32, -1); + catl->set_tooltip_text (M("IPTCPANEL_CATEGORYHINT")); + category->set_tooltip_text (M("IPTCPANEL_CATEGORYHINT")); + Gtk::Label* scl = new Gtk::Label (M("IPTCPANEL_SUPPCATEGORIES")+":"); + suppCategories = new Gtk::ListViewText (1, false, Gtk::SELECTION_MULTIPLE); + suppCategories->set_headers_visible (false); + Gtk::ScrolledWindow* scrolledWindowsc = new Gtk::ScrolledWindow(); + scrolledWindowsc->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); + scrolledWindowsc->add(*suppCategories); + suppCategory = new Gtk::ComboBoxEntryText (); + suppCategory->set_size_request (32, -1); + scl->set_tooltip_text (M("IPTCPANEL_SUPPCATEGORIESHINT")); + suppCategories->set_tooltip_text (M("IPTCPANEL_SUPPCATEGORIESHINT")); + suppCategory->set_tooltip_text (M("IPTCPANEL_SUPPCATEGORIESHINT")); + addSC = new Gtk::Button (); + delSC = new Gtk::Button (); + Gtk::Image* addSCImg = new Gtk::Image (argv0+"/images/list-add12.png"); + Gtk::Image* delSCImg = new Gtk::Image (argv0+"/images/list-remove12r.png"); + addSC->add (*addSCImg); + delSC->add (*delSCImg); + Gtk::HBox* schb = new Gtk::HBox (); + schb->pack_start (*suppCategory); + schb->pack_start (*addSC, Gtk::PACK_SHRINK, 2); + schb->pack_start (*delSC, Gtk::PACK_SHRINK, 2); + iptc->attach (*catl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*category, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + row++; + iptc->attach (*scl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*schb, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + row++; + iptc->attach (*scrolledWindowsc, 0, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + row++; + + Gtk::HSeparator* hsep3 = new Gtk::HSeparator (); + iptc->attach (*hsep3, 0, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + row++; + + Gtk::Label* authl = new Gtk::Label (M("IPTCPANEL_AUTHOR")+":"); + author = new Gtk::Entry (); + authl->set_tooltip_text (M("IPTCPANEL_CREDITHINT")); + author->set_tooltip_text (M("IPTCPANEL_CREDITHINT")); + iptc->attach (*authl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*author, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* aupl = new Gtk::Label (M("IPTCPANEL_AUTHORSPOSITION")+":"); + authorPos = new Gtk::Entry (); + aupl->set_tooltip_text (M("IPTCPANEL_AUTHORSPOSITIONHINT")); + authorPos->set_tooltip_text (M("IPTCPANEL_AUTHORSPOSITIONHINT")); + iptc->attach (*aupl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*authorPos, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* credl = new Gtk::Label (M("IPTCPANEL_CREDIT")+":"); + credit = new Gtk::Entry (); + credl->set_tooltip_text (M("IPTCPANEL_CREDITHINT")); + credit->set_tooltip_text (M("IPTCPANEL_CREDITHINT")); + iptc->attach (*credl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*credit, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* sourl = new Gtk::Label (M("IPTCPANEL_SOURCE")+":"); + source = new Gtk::Entry (); + sourl->set_tooltip_text (M("IPTCPANEL_SOURCEHINT")); + source->set_tooltip_text (M("IPTCPANEL_SOURCEHINT")); + iptc->attach (*sourl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*source, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* cprl = new Gtk::Label (M("IPTCPANEL_COPYRIGHT")+":"); + copyright = new Gtk::Entry (); + cprl->set_tooltip_text (M("IPTCPANEL_COPYRIGHTHINT")); + copyright->set_tooltip_text (M("IPTCPANEL_COPYRIGHTHINT")); + iptc->attach (*cprl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*copyright, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::HSeparator* hsep4 = new Gtk::HSeparator (); + iptc->attach (*hsep4, 0, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* cityl = new Gtk::Label (M("IPTCPANEL_CITY")+":"); + city = new Gtk::Entry (); + cityl->set_tooltip_text (M("IPTCPANEL_CITYHINT")); + city->set_tooltip_text (M("IPTCPANEL_CITYHINT")); + iptc->attach (*cityl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*city, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* provl = new Gtk::Label (M("IPTCPANEL_PROVINCE")+":"); + province = new Gtk::Entry (); + provl->set_tooltip_text (M("IPTCPANEL_PROVINCEHINT")); + province->set_tooltip_text (M("IPTCPANEL_PROVINCEHINT")); + iptc->attach (*provl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*province, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* ctrl = new Gtk::Label (M("IPTCPANEL_COUNTRY")+":"); + country = new Gtk::Entry (); + ctrl->set_tooltip_text (M("IPTCPANEL_COUNTRYHINT")); + country->set_tooltip_text (M("IPTCPANEL_COUNTRYHINT")); + iptc->attach (*ctrl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*country, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* titll = new Gtk::Label (M("IPTCPANEL_TITLE")+":"); + title = new Gtk::Entry (); + titll->set_tooltip_text (M("IPTCPANEL_TITLEHINT")); + title->set_tooltip_text (M("IPTCPANEL_TITLEHINT")); + iptc->attach (*titll, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*title, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* dcl = new Gtk::Label (M("IPTCPANEL_DATECREATED")+":"); + dateCreated = new Gtk::Entry (); + dcl->set_tooltip_text (M("IPTCPANEL_DATECREATEDHINT")); + dateCreated->set_tooltip_text (M("IPTCPANEL_DATECREATEDHINT")); + iptc->attach (*dcl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*dateCreated, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* trl = new Gtk::Label (M("IPTCPANEL_TRANSREFERENCE")+":"); + transReference = new Gtk::Entry (); + trl->set_tooltip_text (M("IPTCPANEL_TRANSREFERENCEHINT")); + transReference->set_tooltip_text (M("IPTCPANEL_TRANSREFERENCEHINT")); + iptc->attach (*trl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*transReference, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::ScrolledWindow* scrolledWindow = new Gtk::ScrolledWindow(); + scrolledWindow->set_border_width(2); + scrolledWindow->set_shadow_type(Gtk::SHADOW_NONE); + scrolledWindow->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); + scrolledWindow->property_window_placement().set_value(Gtk::CORNER_TOP_LEFT); + scrolledWindow->add(*iptc); + + pack_start (*scrolledWindow); + + Gtk::HBox* bbox = new Gtk::HBox (); + + reset = new Gtk::Button (M("IPTCPANEL_RESET")); + reset->set_image (*(new Gtk::Image (Gtk::StockID ("gtk-undo"), Gtk::IconSize (2)))); + bbox->pack_start (*reset); + + file = new Gtk::Button (M("IPTCPANEL_EMBEDDED")); + file->set_image (*(new Gtk::Image (Gtk::StockID ("gtk-open"), Gtk::IconSize (2)))); + bbox->pack_start (*file); + + copy = new Gtk::Button (); + copy->set_image (*(new Gtk::Image (Gtk::StockID ("gtk-copy"), Gtk::IconSize (2)))); + bbox->pack_start (*copy, Gtk::PACK_SHRINK, 0); + + paste = new Gtk::Button (); + paste->set_image (*(new Gtk::Image (Gtk::StockID ("gtk-paste"), Gtk::IconSize (2)))); + bbox->pack_start (*paste, Gtk::PACK_SHRINK, 0); + + pack_end (*bbox, Gtk::PACK_SHRINK, 2); + + Gtk::Tooltips* toolTip = new Gtk::Tooltips (); + toolTip->set_tip (*reset, M("IPTCPANEL_RESETHINT")); + toolTip->set_tip (*file, M("IPTCPANEL_EMBEDDEDHINT")); + toolTip->set_tip (*copy, M("IPTCPANEL_COPYHINT")); + toolTip->set_tip (*paste, M("IPTCPANEL_PASTEHINT")); + + reset->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::resetClicked) ); + file->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::fileClicked) ); + copy->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::copyClicked) ); + paste->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::pasteClicked) ); + + + addKW->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::addKeyWord) ); + delKW->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::delKeyWord) ); + addSC->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::addSuppCategory) ); + delSC->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::delSuppCategory) ); + keyword->get_entry()->signal_activate().connect( sigc::mem_fun(*this, &IPTCPanel::addKeyWord) ); + suppCategory->get_entry()->signal_activate().connect( sigc::mem_fun(*this, &IPTCPanel::addSuppCategory) ); + + conns[0] = captionText->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[1] = captionWriter->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[2] = headline->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[3] = instructions->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[4] = category->get_entry()->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[5] = author->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[6] = authorPos->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[7] = credit->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[8] = source->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[9] = copyright->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[10] = city->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[11] = province->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[12] = country->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[13] = title->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[14] = dateCreated->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[15] = transReference->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + + category->get_entry()->set_max_length (3); + keyword->get_entry()->set_max_length (64); + captionWriter->set_max_length (32); + instructions->set_max_length (256); + author->set_max_length (32); + authorPos->set_max_length (32); + credit->set_max_length (32); + source->set_max_length (32); + copyright->set_max_length (128); + city->set_max_length (32); + province->set_max_length (32); + country->set_max_length (64); + title->set_max_length (64); + dateCreated->set_max_length (8); + transReference->set_max_length (32); + + show_all (); +} + +void IPTCPanel::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + if (pp->iptc.size()>0) + changeList = pp->iptc; + else + changeList = embeddedData; + applyChangeList (); + enableListener (); +} + +void IPTCPanel::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->iptc = changeList; +} + +void IPTCPanel::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + defChangeList = defParams->iptc; +} + +void IPTCPanel::setImageData (const ImageMetaData* id) { + + if (id) + embeddedData = id->getIPTCData (); + else + embeddedData.clear (); + + file->set_sensitive (embeddedData.size() > 0); +} + +void IPTCPanel::notifyListener () { + + if (listener) + listener->panelChanged (EvIPTC, M("HISTORY_CHANGED")); +} + +void IPTCPanel::addKeyWord () { + + keyword->get_entry()->select_region (0, keyword->get_entry()->get_text().size()); + + for (int i=0; isize(); i++) + if (keywords->get_text (i) == keyword->get_entry()->get_text()) + return; + + keywords->append_text (keyword->get_entry()->get_text()); + keyword->prepend_text (keyword->get_entry()->get_text()); + std::vector items; + for (Gtk::TreeModel::iterator i = keyword->get_model()->children().begin(); i!=keyword->get_model()->children().end(); i++) { + Glib::ustring s; + i->get_value (0, s); + items.push_back (s); + } + keyword->clear_items (); + for (int i=0; i<10 && iappend_text (items[i]); + keywords->scroll_to_row (keywords->get_model()->get_path(--keywords->get_model()->children().end())); + + updateChangeList (); +} + +void IPTCPanel::delKeyWord () { + + std::vector selection = keywords->get_selected (); + if (selection.size()>0) { + std::vector keep; + for (int i=0; isize(); i++) + if (std::find (selection.begin(), selection.end(), i) == selection.end()) + keep.push_back (keywords->get_text (i)); + keywords->clear_items (); + for (int i=0; iappend_text (keep[i]); + } + + updateChangeList (); +} + +void IPTCPanel::addSuppCategory () { + + for (int i=0; isize(); i++) + if (suppCategories->get_text (i) == suppCategory->get_entry()->get_text()) + return; + + suppCategories->append_text (suppCategory->get_entry()->get_text()); + suppCategory->prepend_text (suppCategory->get_entry()->get_text()); + std::vector items; + for (Gtk::TreeModel::iterator i = suppCategory->get_model()->children().begin(); i!=suppCategory->get_model()->children().end(); i++) { + Glib::ustring s; + i->get_value (0, s); + items.push_back (s); + } + suppCategory->clear_items (); + for (int i=0; i<10 && iappend_text (items[i]); + suppCategories->scroll_to_row (suppCategories->get_model()->get_path(--suppCategories->get_model()->children().end())); + suppCategory->get_entry()->select_region (0, suppCategory->get_entry()->get_text().size()); + + updateChangeList (); +} + +void IPTCPanel::delSuppCategory () { + + std::vector selection = suppCategories->get_selected (); + if (selection.size()>0) { + std::vector keep; + for (int i=0; isize(); i++) + if (std::find (selection.begin(), selection.end(), i) == selection.end()) + keep.push_back (suppCategories->get_text (i)); + suppCategories->clear_items (); + for (int i=0; iappend_text (keep[i]); + } + + updateChangeList (); +} + +void IPTCPanel::updateChangeList () { + + changeList.clear (); + changeList.resize (18); + changeList[0].field = "Caption"; + changeList[0].values.push_back (captionText->get_text ()); + changeList[1].field = "CaptionWriter"; + changeList[1].values.push_back (captionWriter->get_text ()); + changeList[2].field = "Headline"; + changeList[2].values.push_back (headline->get_text ()); + changeList[3].field = "Instructions"; + changeList[3].values.push_back (instructions->get_text ()); + changeList[4].field = "Keywords"; + for (int i=0; isize(); i++) + changeList[4].values.push_back (keywords->get_text (i)); + changeList[5].field = "Category"; + changeList[5].values.push_back (category->get_entry()->get_text ()); + changeList[6].field = "SupplementalCategories"; + for (int i=0; isize(); i++) + changeList[6].values.push_back (suppCategories->get_text (i)); + changeList[7].field = "Author"; + changeList[7].values.push_back (author->get_text ()); + changeList[8].field = "AuthorsPosition"; + changeList[8].values.push_back (authorPos->get_text ()); + changeList[9].field = "Credit"; + changeList[9].values.push_back (credit->get_text ()); + changeList[10].field = "Source"; + changeList[10].values.push_back (source->get_text ()); + changeList[11].field = "Copyright"; + changeList[11].values.push_back (copyright->get_text ()); + changeList[12].field = "City"; + changeList[12].values.push_back (city->get_text ()); + changeList[13].field = "Province"; + changeList[13].values.push_back (province->get_text ()); + changeList[14].field = "Country"; + changeList[14].values.push_back (country->get_text ()); + changeList[15].field = "Title"; + changeList[15].values.push_back (title->get_text ()); + changeList[16].field = "DateCreated"; + changeList[16].values.push_back (dateCreated->get_text ()); + changeList[17].field = "TransReference"; + changeList[17].values.push_back (transReference->get_text ()); + + notifyListener (); +} + +void IPTCPanel::applyChangeList () { + + for (int i=0; i<16; i++) + conns[i].block (true); + + captionText->set_text (""); + captionWriter->set_text (""); + headline->set_text (""); + instructions->set_text (""); + keywords->clear_items (); + category->get_entry()->set_text (""); + suppCategories->clear_items (); + author->set_text (""); + authorPos->set_text (""); + credit->set_text (""); + source->set_text (""); + copyright->set_text (""); + city->set_text (""); + province->set_text (""); + country->set_text (""); + title->set_text (""); + dateCreated->set_text (""); + transReference->set_text (""); + keyword->get_entry()->set_text (""); + suppCategory->get_entry()->set_text (""); + + for (int i=0; i0) + captionText->set_text (changeList[i].values[0]); + else if (changeList[i].field == "CaptionWriter" && changeList[i].values.size()>0) + captionWriter->set_text (changeList[i].values[0]); + else if (changeList[i].field == "Headline" && changeList[i].values.size()>0) + headline->set_text (changeList[i].values[0]); + else if (changeList[i].field == "Instructions" && changeList[i].values.size()>0) + instructions->set_text (changeList[i].values[0]); + else if (changeList[i].field == "Keywords") + for (int j=0; jappend_text (changeList[i].values[j]); + else if (changeList[i].field == "Category" && changeList[i].values.size()>0) + category->get_entry()->set_text (changeList[i].values[0]); + else if (changeList[i].field == "SupplementalCategories") + for (int j=0; jappend_text (changeList[i].values[j]); + else if (changeList[i].field == "Author" && changeList[i].values.size()>0) + author->set_text (changeList[i].values[0]); + else if (changeList[i].field == "AuthorsPosition" && changeList[i].values.size()>0) + authorPos->set_text (changeList[i].values[0]); + else if (changeList[i].field == "Credit" && changeList[i].values.size()>0) + credit->set_text (changeList[i].values[0]); + else if (changeList[i].field == "Source" && changeList[i].values.size()>0) + source->set_text (changeList[i].values[0]); + else if (changeList[i].field == "Copyright" && changeList[i].values.size()>0) + copyright->set_text (changeList[i].values[0]); + else if (changeList[i].field == "City" && changeList[i].values.size()>0) + city->set_text (changeList[i].values[0]); + else if (changeList[i].field == "Province" && changeList[i].values.size()>0) + province->set_text (changeList[i].values[0]); + else if (changeList[i].field == "Country" && changeList[i].values.size()>0) + country->set_text (changeList[i].values[0]); + else if (changeList[i].field == "Title" && changeList[i].values.size()>0) + title->set_text (changeList[i].values[0]); + else if (changeList[i].field == "DateCreated" && changeList[i].values.size()>0) + dateCreated->set_text (changeList[i].values[0]); + else if (changeList[i].field == "TransReference" && changeList[i].values.size()>0) + transReference->set_text (changeList[i].values[0]); + + for (int i=0; i<16; i++) + conns[i].block (false); +} + +void IPTCPanel::resetClicked () { + + disableListener (); + changeList = defChangeList; + applyChangeList (); + enableListener (); + notifyListener (); +} + +void IPTCPanel::fileClicked () { + + disableListener (); + changeList = embeddedData; + applyChangeList (); + enableListener (); + notifyListener (); +} + +void IPTCPanel::copyClicked () { + + clipboard.setIPTC (changeList); +} + +void IPTCPanel::pasteClicked () { + + disableListener (); + changeList = clipboard.getIPTC (); + applyChangeList (); + enableListener (); + notifyListener (); +} diff --git a/rtgui/iptcpanel.h b/rtgui/iptcpanel.h new file mode 100644 index 000000000..4b5baec6c --- /dev/null +++ b/rtgui/iptcpanel.h @@ -0,0 +1,91 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _IPTCPANEL_ +#define _IPTCPANEL_ + +#include +#include + +class IPTCPanel : public Gtk::VBox, public ToolPanel { + + private: + std::vector changeList; + std::vector defChangeList; + std::vector embeddedData; + + Gtk::TextView* captionView; + Glib::RefPtr captionText; + Gtk::Entry* captionWriter; + Gtk::Entry* headline; + Gtk::Entry* instructions; + Gtk::ComboBoxEntryText* keyword; + Gtk::ListViewText* keywords; + Gtk::Button* addKW; + Gtk::Button* delKW; + Gtk::ComboBoxEntryText* category; + Gtk::ComboBoxEntryText* suppCategory; + Gtk::ListViewText* suppCategories; + Gtk::Button* addSC; + Gtk::Button* delSC; + + Gtk::Entry* author; + Gtk::Entry* authorPos; + Gtk::Entry* credit; + Gtk::Entry* source; + Gtk::Entry* copyright; + Gtk::Entry* city; + Gtk::Entry* province; + Gtk::Entry* country; + Gtk::Entry* title; + Gtk::Entry* dateCreated; + Gtk::Entry* transReference; + + Gtk::Button* reset; + Gtk::Button* file; + Gtk::Button* copy; + Gtk::Button* paste; + + sigc::connection conns[16]; + + void applyChangeList (); + void updateChangeList (); + + public: + IPTCPanel (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + + void setImageData (const rtengine::ImageMetaData* id); + + void notifyListener (); + + void addKeyWord (); + void delKeyWord (); + void addSuppCategory (); + void delSuppCategory (); + + void resetClicked (); + void fileClicked (); + void copyClicked (); + void pasteClicked (); +}; + +#endif diff --git a/rtgui/lcurve.cc b/rtgui/lcurve.cc new file mode 100644 index 000000000..b40f37e8e --- /dev/null +++ b/rtgui/lcurve.cc @@ -0,0 +1,144 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +LCurve::LCurve () : ToolPanel(), brAdd(false), contrAdd(false) { + + Gtk::HBox* abox = Gtk::manage (new Gtk::HBox ()); + abox->set_border_width (2); + + brightness = Gtk::manage (new Adjuster (M("TP_LUMACURVE_BRIGHTNESS"), -100, 100, 0.01, 0)); + contrast = Gtk::manage (new Adjuster (M("TP_LUMACURVE_CONTRAST"), -100, 100, 1, 0)); + + pack_start (*brightness); + brightness->show (); + + pack_start (*contrast); + contrast->show (); + + Gtk::HSeparator *hsep3 = Gtk::manage (new Gtk::HSeparator()); + hsep3->show (); + pack_start (*hsep3); + + shape = Gtk::manage (new CurveEditor ()); + shape->show (); + shape->setCurveListener (this); + + pack_start (*shape, Gtk::PACK_SHRINK, 4); + + brightness->setAdjusterListener (this); + contrast->setAdjusterListener (this); +} + +void LCurve::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + brightness->setEditedState (pedited->lumaCurve.brightness ? Edited : UnEdited); + contrast->setEditedState (pedited->lumaCurve.contrast ? Edited : UnEdited); + shape->setUnChanged (!pedited->lumaCurve.curve); + } + + brightness->setValue (pp->lumaCurve.brightness); + contrast->setValue (pp->lumaCurve.contrast); + shape->setCurve (pp->lumaCurve.curve); + + enableListener (); +} + +void LCurve::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->lumaCurve.brightness = brightness->getValue (); + pp->lumaCurve.contrast = (int)contrast->getValue (); + pp->lumaCurve.curve = shape->getCurve (); + + if (pedited) { + pedited->lumaCurve.brightness = brightness->getEditedState (); + pedited->lumaCurve.contrast = contrast->getEditedState (); + pedited->lumaCurve.curve = !shape->isUnChanged (); + } +} + +void LCurve::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + brightness->setDefault (defParams->lumaCurve.brightness); + contrast->setDefault (defParams->lumaCurve.contrast); + + if (pedited) { + brightness->setDefaultEditedState (pedited->lumaCurve.brightness ? Edited : UnEdited); + contrast->setDefaultEditedState (pedited->lumaCurve.contrast ? Edited : UnEdited); + } + else { + brightness->setDefaultEditedState (Irrelevant); + contrast->setDefaultEditedState (Irrelevant); + } +} + +void LCurve::curveChanged () { + + if (listener) + listener->panelChanged (EvLCurve, M("HISTORY_CUSTOMCURVE")); +} + +void LCurve::adjusterChanged (Adjuster* a, double newval) { + + if (!listener) + return; + + Glib::ustring costr; + if (a==brightness) + costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue()); + else + costr = Glib::ustring::format ((int)a->getValue()); + + if (a==brightness) + listener->panelChanged (EvLBrightness, costr); + else if (a==contrast) + listener->panelChanged (EvLContrast, costr); +} + +void LCurve::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + brightness->showEditedCB (); + contrast->showEditedCB (); + + shape->setBatchMode (batchMode); +} + +void LCurve::setAdjusterBehavior (bool bradd, bool contradd) { + + if (!brAdd && bradd || brAdd && !bradd) + brightness->setLimits (-100, 100, 1, 0); + if (!contrAdd && contradd || contrAdd && !contradd) + contrast->setLimits (-100, 100, 1, 0); + + brAdd = bradd; + contrAdd = contradd; +} + +void LCurve::updateCurveBackgroundHistogram (unsigned* hist) { + + shape->updateBackgroundHistogram (hist); +} diff --git a/rtgui/lcurve.h b/rtgui/lcurve.h new file mode 100644 index 000000000..b8d1bd4c2 --- /dev/null +++ b/rtgui/lcurve.h @@ -0,0 +1,51 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _LCURVE_H_ +#define _LCURVE_H_ + +#include +#include +#include +#include +#include + +class LCurve : public Gtk::VBox, public AdjusterListener, public ToolPanel, public CurveListener { + + protected: + Adjuster* brightness; + Adjuster* contrast; + CurveEditor* shape; + bool brAdd, contrAdd; + + public: + + LCurve (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void setAdjusterBehavior (bool bradd, bool contradd); + + void curveChanged (); + void adjusterChanged (Adjuster* a, double newval); + void updateCurveBackgroundHistogram (unsigned* hist); +}; + +#endif diff --git a/rtgui/lumadenoise.cc b/rtgui/lumadenoise.cc new file mode 100644 index 000000000..e80d1595c --- /dev/null +++ b/rtgui/lumadenoise.cc @@ -0,0 +1,149 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +LumaDenoise::LumaDenoise () : ToolPanel () { + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (false); + enabled->show (); + pack_start (*enabled); + + Gtk::HSeparator *hsep1 = Gtk::manage (new Gtk::HSeparator()); + hsep1->show (); + pack_start (*hsep1); + + enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &LumaDenoise::enabledChanged) ); + + radius = Gtk::manage (new Adjuster (M("TP_LUMADENOISE_RADIUS"), 0.5, 50, 0.1, 1.9)); + edge = Gtk::manage (new Adjuster (M("TP_LUMADENOISE_EDGETOLERANCE"), 10, 30000, 100, 1500)); + radius->setAdjusterListener (this); + edge->setAdjusterListener (this); + radius->show(); + edge->show(); + + pack_start (*radius); + pack_start (*edge); +} + +void LumaDenoise::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + radius->setEditedState (pedited->lumaDenoise.radius ? Edited : UnEdited); + edge->setEditedState (pedited->lumaDenoise.edgetolerance ? Edited : UnEdited); + enabled->set_inconsistent (!pedited->lumaDenoise.enabled); + } + + enaConn.block (true); + enabled->set_active (pp->lumaDenoise.enabled); + enaConn.block (false); + + lastEnabled = pp->lumaDenoise.enabled; + + radius->setValue (pp->lumaDenoise.radius); + edge->setValue (pp->lumaDenoise.edgetolerance); + + enableListener (); +} + +void LumaDenoise::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->lumaDenoise.radius = radius->getValue (); + pp->lumaDenoise.edgetolerance = (int)edge->getValue (); + pp->lumaDenoise.enabled = enabled->get_active(); + + if (pedited) { + pedited->lumaDenoise.radius = radius->getEditedState (); + pedited->lumaDenoise.edgetolerance = edge->getEditedState (); + pedited->lumaDenoise.enabled = !enabled->get_inconsistent(); + } +} + +void LumaDenoise::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + radius->setDefault (defParams->lumaDenoise.radius); + edge->setDefault (defParams->lumaDenoise.edgetolerance); + + if (pedited) { + radius->setDefaultEditedState (pedited->lumaDenoise.radius ? Edited : UnEdited); + edge->setDefaultEditedState (pedited->lumaDenoise.edgetolerance ? Edited : UnEdited); + } + else { + radius->setDefaultEditedState (Irrelevant); + edge->setDefaultEditedState (Irrelevant); + } +} + +void LumaDenoise::adjusterChanged (Adjuster* a, double newval) { + + if (listener && enabled->get_active()) { + + if (a==radius) + listener->panelChanged (EvLDNRadius, Glib::ustring::format (std::setw(2), std::fixed, std::setprecision(1), a->getValue())); + else if (a==edge) + listener->panelChanged (EvLDNEdgeTolerance, Glib::ustring::format ((int)a->getValue())); + } +} + +void LumaDenoise::enabledChanged () { + + if (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaConn.block (true); + enabled->set_active (false); + enaConn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_active ()) + listener->panelChanged (EvLDNEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvLDNEnabled, M("GENERAL_DISABLED")); + } +} + +void LumaDenoise::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + radius->showEditedCB (); + edge->showEditedCB (); +} + +void LumaDenoise::setAdjusterBehavior (bool bedgetoladd) { + + if (!edgetolAdd && bedgetoladd) + edge->setLimits (-10000, 10000, 100, 0); + else if (edgetolAdd && !bedgetoladd) + edge->setLimits (10, 30000, 100, 1500); + + edgetolAdd = bedgetoladd; +} diff --git a/rtgui/lumadenoise.h b/rtgui/lumadenoise.h new file mode 100644 index 000000000..3f8e84170 --- /dev/null +++ b/rtgui/lumadenoise.h @@ -0,0 +1,51 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _LUMADENOISE_H_ +#define _LUMADENOISE_H_ + +#include +#include +#include + +class LumaDenoise : public Gtk::VBox, public AdjusterListener, public ToolPanel { + + protected: + Adjuster* radius; + Adjuster* edge; + Gtk::CheckButton* enabled; + bool lastEnabled; + sigc::connection enaConn; + bool edgetolAdd; + + public: + + LumaDenoise (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void enabledChanged (); + + void setAdjusterBehavior (bool bedgetoladd); +}; + +#endif diff --git a/rtgui/lwbutton.cc b/rtgui/lwbutton.cc new file mode 100644 index 000000000..e5ec6a68d --- /dev/null +++ b/rtgui/lwbutton.cc @@ -0,0 +1,189 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include + +LWButton::LWButton (Cairo::RefPtr i, int aCode, void* aData, Alignment ha, Alignment va, Glib::ustring tooltip) + : icon(i), actionCode(aCode), actionData(aData), halign(ha), valign(va), state(Normal), toolTip(tooltip), listener(NULL) { + + if (i) { + w = i->get_width () + 2; + h = i->get_height () + 2; + } + else + w = h = 2; +} + +void LWButton::getSize (int& minw, int& minh) { + + minw = w; + minh = h; +} + +void LWButton::setPosition (int x, int y) { + + xpos = x; + ypos = y; +} + +void LWButton::getPosition (int& x, int& y) { + + x = xpos; + y = ypos; +} + +void LWButton::setIcon (Cairo::RefPtr i) { + + icon = i; + if (i) { + w = i->get_width () + 2; + h = i->get_height () + 2; + } + else + w = h = 2; +} + +Cairo::RefPtr LWButton::getIcon () { + + return icon; +} + +void LWButton::setColors (const Gdk::Color& bg, const Gdk::Color& fg) { + + bgr = bg.get_red_p (); + bgg = bg.get_green_p (); + bgb = bg.get_blue_p (); + fgr = fg.get_red_p (); + fgg = fg.get_green_p (); + fgb = fg.get_blue_p (); +} + +bool LWButton::inside (int x, int y) { + + return x>xpos && xypos && yredrawNeeded (this); + return true; + } + return in; +} + +bool LWButton::pressNotify (int x, int y) { + + bool in = inside (x, y); + State nstate = state; + if (in && (state==Normal || state==Over || state==Pressed_Out)) + nstate = Pressed_In; + else if (!in && state==Pressed_In) + nstate = Normal; + + if (state!=nstate) { + state = nstate; + if (listener) + listener->redrawNeeded (this); + return true; + } + return in; +} + +bool LWButton::releaseNotify (int x, int y) { + + bool in = inside (x, y); + State nstate = state; + bool action = false; + if (in && (state==Pressed_In || state==Pressed_Out)) { + nstate = Over; + action = true; + } + else + nstate = Normal; + + bool ret = action; + if (state!=nstate) { + state = nstate; + if (listener) + listener->redrawNeeded (this); + ret = true; + } + + if (action && listener) + listener->buttonPressed (this, actionCode, actionData); + return ret; +} + +void LWButton::redraw (Cairo::RefPtr context) { + + context->set_line_width (1.0); + context->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + context->rectangle (xpos+0.5, ypos+0.5, w-1.0, h-1.0); + if (state==Pressed_In) + context->set_source_rgb (fgr, fgg, fgb); + else + context->set_source_rgba (bgr, bgg, bgb, 0); + context->fill_preserve (); + if (state==Over) + context->set_source_rgb (fgr, fgg, fgb); + else + context->set_source_rgba (bgr, bgg, bgb, 0); + context->stroke (); + int dilat = 1; + if (state==Pressed_In) + dilat++; + + if (icon) { + context->set_source (icon, xpos+dilat, ypos+dilat); + context->paint (); + } +} + +void LWButton::getAlignment (Alignment& ha, Alignment& va) { + + ha = halign; + va = valign; +} + +Glib::ustring LWButton::getToolTip (int x, int y) { + + if (inside (x, y)) + return toolTip; + else + return ""; +} + +void LWButton::setToolTip (const Glib::ustring& tooltip) { + + toolTip = tooltip; +} + diff --git a/rtgui/lwbutton.h b/rtgui/lwbutton.h new file mode 100644 index 000000000..0d3e7a61f --- /dev/null +++ b/rtgui/lwbutton.h @@ -0,0 +1,74 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _LWBUTTON_ +#define _LWBUTTON_ + +#include + +class LWButton; +class LWButtonListener { + + public: + virtual void buttonPressed (LWButton* button, int actionCode, void* actionData) {} + virtual void redrawNeeded (LWButton* button) {} +}; + +class LWButton { + + public: + enum Alignment {Left, Right, Top, Bottom, Center}; + enum State { Normal, Over, Pressed_In, Pressed_Out}; + + private: + int xpos, ypos, w, h; + Alignment halign, valign; + Cairo::RefPtr icon; + double bgr, bgg, bgb; + double fgr, fgg, fgb; + State state; + LWButtonListener* listener; + int actionCode; + void* actionData; + Glib::ustring toolTip; + + public: + LWButton (Cairo::RefPtr i, int aCode, void* aData, Alignment ha=Left, Alignment va=Center, Glib::ustring tooltip=""); + + void getSize (int& minw, int& minh); + void getAlignment (Alignment& ha, Alignment& va); + void setPosition (int x, int y); + void getPosition (int& x, int& y); + bool inside (int x, int y); + void setIcon (Cairo::RefPtr i); + Cairo::RefPtr getIcon (); + void setColors (const Gdk::Color& bg, const Gdk::Color& fg); + void setToolTip (const Glib::ustring& tooltip); + + bool motionNotify (int x, int y); + bool pressNotify (int x, int y); + bool releaseNotify (int x, int y); + + Glib::ustring getToolTip (int x, int y); + + void setButtonListener (LWButtonListener* bl) { listener = bl; } + + void redraw (Cairo::RefPtr context); +}; + +#endif diff --git a/rtgui/lwbuttonset.cc b/rtgui/lwbuttonset.cc new file mode 100644 index 000000000..1de440231 --- /dev/null +++ b/rtgui/lwbuttonset.cc @@ -0,0 +1,169 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include + +LWButtonSet::LWButtonSet () : aw(0), ah(0) { +} + +LWButtonSet::~LWButtonSet () { + + for (int i=0; igetSize (bw, bh); + w+= bw; + if (bh>h) + h = bh; + } +} + +void LWButtonSet::arrangeButtons (int x, int y, int w, int h) { + + int mw, mh; + getMinimalDimensions (mw, mh); + + if (w<0) + w = mw; + if (h<0) + h = mh; + + int begx = x; + int endx = x+w-1; + for (int i=0; igetSize (bw, bh); + buttons[i]->getAlignment (halign, valign); + if (halign == LWButton::Left) { + bx = begx; + begx += bw; + } + else if (halign == LWButton::Right) { + bx = endx-bw; + endx -= bw; + } + if (valign == LWButton::Top) + by = y; + else if (valign == LWButton::Bottom) + by = y+h-bh-1; + else if (valign == LWButton::Center) + by = y+(h-bh)/2; + buttons[i]->setPosition (bx, by); + } + aw = w; + ah = h; + ax = x; + ay = y; +} + +void LWButtonSet::move (int nx, int ny) { + + for (int i=0; igetPosition (x, y); + buttons[i]->setPosition (x+nx-ax, y+ny-ay); + } + + ax = nx; + ay = ny; +} + +void LWButtonSet::redraw (Cairo::RefPtr context) { + + for (int i=0; iredraw (context); +} + +bool LWButtonSet::motionNotify (int x, int y) { + + bool res = false; + for (int i=0; imotionNotify (x, y); + res = res || handled; + } + + return res; +} + +bool LWButtonSet::pressNotify (int x, int y) { + + bool res = false; + for (int i=0; ipressNotify (x, y); + res = res || handled; + } + return res; +} + +bool LWButtonSet::releaseNotify (int x, int y) { + + bool res = false; + for (int i=0; ireleaseNotify (x, y); + res = res || handled; + } + return res; +} + +bool LWButtonSet::inside (int x, int y) { + + for (int i=0; iinside (x, y)) + return true; + return false; +} + +void LWButtonSet::setButtonListener (LWButtonListener* bl) { + + for (int i=0; isetButtonListener (bl); +} + +void LWButtonSet::getAllocatedDimensions (int& w, int& h) { + + w = aw; + h = ah; +} + +void LWButtonSet::setColors (const Gdk::Color& bg, const Gdk::Color& fg) { + + for (int i=0; isetColors (bg, fg); +} + +Glib::ustring LWButtonSet::getToolTip (int x, int y) { + + for (int i=0; igetToolTip (x, y); + if (ttip!="") + return ttip; + } + return ""; +} diff --git a/rtgui/lwbuttonset.h b/rtgui/lwbuttonset.h new file mode 100644 index 000000000..b8ea55fad --- /dev/null +++ b/rtgui/lwbuttonset.h @@ -0,0 +1,53 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _LWBUTTONSET_ +#define _LWBUTTONSET_ + +#include +#include +#include + +class LWButtonSet { + + protected: + std::vector buttons; + int aw, ah, ax, ay; + public: + LWButtonSet (); + ~LWButtonSet (); + + void add (LWButton* b); + + void getMinimalDimensions (int& w, int& h); + void getAllocatedDimensions (int& w, int& h); + void arrangeButtons (int x, int y, int w, int h); + void setColors (const Gdk::Color& bg, const Gdk::Color& fg); + bool motionNotify (int x, int y); + bool pressNotify (int x, int y); + bool releaseNotify (int x, int y); + void move (int nx, int ny); + bool inside (int x, int y); + + Glib::ustring getToolTip (int x, int y); + + void setButtonListener (LWButtonListener* bl); + void redraw (Cairo::RefPtr context); +}; + +#endif diff --git a/rtgui/main.cc b/rtgui/main.cc new file mode 100644 index 000000000..c5543d5cd --- /dev/null +++ b/rtgui/main.cc @@ -0,0 +1,113 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +// generated 2004/6/3 19:15:32 CEST by gabor@darkstar.(none) +// using glademm V2.5.0 +// +// newer (non customized) versions of this file go to raw.cc_new + +// This file is for your program, I won't touch it again! + +//#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef WIN32 +#include +#include +#endif + +#include + +extern Options options; + +//#ifdef WIN32 +//#include // included for WinMain +//#endif + +// stores path to data files +Glib::ustring argv0; +Glib::ustring argv1; + +int main(int argc, char **argv) +{ + + std::string argv0_, argv1_; + +#ifdef WIN32 + char exname[512]; + GetModuleFileName (NULL, exname, 512); + argv0_ = exname; + // get the path where the rawtherapee is stored + int i; + for (i=argv0_.size()-1; (argv0_[i]!='/' && argv0_[i]!='\\') && i>0; i--); + if (argv0_[i]=='/' || argv0_[i]=='\\') + argv0_ = argv0_.substr(0,i); +#else + // get the path to data (defined in config.h which is generated by cmake) + argv0_ = DATA_SEARCH_PATH; + // check if path exists, otherwise revert back to behavior similar to windows + try { + Glib::Dir dir(DATA_SEARCH_PATH); + } catch (Glib::FileError) { + argv0_ = argv[0]; + int i; + for (i=argv0_.size()-1; (argv0_[i]!='/' && argv0_[i]!='\\') && i>0; i--); + if (argv0_[i]=='/' || argv0_[i]=='\\') + argv0_ = argv0_.substr(0,i); + } +#endif + + + if (argc>1) + argv1_ = argv[1]; + else + argv1_ = ""; + + argv0 = safe_locale_to_utf8 (argv0_); + argv1 = safe_locale_to_utf8 (argv1_); + + Glib::thread_init(); + gdk_threads_init(); + Gio::init (); + + Options::load (); + +// Gtk::RC::add_default_file (argv0+"/themes/"+options.theme); + std::vector rcfiles; + rcfiles.push_back (argv0+"/themes/"+options.theme); + Gtk::RC::set_default_files (rcfiles); + + Gtk::Main m(&argc, &argv); +// MainWindow *MainWindow = new class MainWindow(); + RTWindow *rtWindow = new class RTWindow(); + gdk_threads_enter (); + m.run(*rtWindow); + gdk_threads_leave (); + delete rtWindow; + return 0; +} + + + + diff --git a/rtgui/mountselectionlistener.h b/rtgui/mountselectionlistener.h new file mode 100644 index 000000000..c1986414d --- /dev/null +++ b/rtgui/mountselectionlistener.h @@ -0,0 +1,30 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _MOUNTSELECTIONLISTENER_ +#define _MOUNTSELECTIONLISTENER_ + +#include + +class MountSelectionListener { + + public: + virtual void mountSelectionChanged (Glib::ustring mountRoot) {} +}; + +#endif diff --git a/rtgui/multilangmgr.cc b/rtgui/multilangmgr.cc new file mode 100644 index 000000000..592f6e40d --- /dev/null +++ b/rtgui/multilangmgr.cc @@ -0,0 +1,98 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include + +MultiLangMgr langMgr; + +Glib::ustring M (std::string key) { return langMgr.getStr (key); } + +bool MultiLangMgr::load (Glib::ustring fname, MultiLangMgr* fb) { + + fallBack = fb; + + FILE *f = g_fopen (fname.c_str(), "rt"); + + if (f==NULL) + return false; + + transTable.clear (); + + char* buffer = new char[2048]; + + while (buffer = fgets (buffer, 2048, f)) { + // find separator + int seppos = 0; + while (buffer[seppos]!=0 && buffer[seppos]!=';') + seppos++; + // no separator found + if (buffer[seppos]==0) + continue; + // cut the last \n and \r characters + int endpos = strlen(buffer)-1; + while (buffer[endpos]=='\n' || buffer[endpos]=='\r') + endpos--; + buffer[endpos+1] = 0; + // replace "\n" to '\n' + int j = 0; + for (int i=0; i::iterator r; + for (r=transTable.begin (); r!=transTable.end(); r++) + fprintf (f, "%s;%s\n", r->first.c_str(), safe_locale_from_utf8(r->second).c_str()); + + fclose (f); + return true; +} + +Glib::ustring MultiLangMgr::getStr (std::string key) { + + std::map::iterator r = transTable.find (key); + if (r!=transTable.end()) + return r->second; + else if (fallBack) + return fallBack->getStr (key); + else + return ""; +} diff --git a/rtgui/multilangmgr.h b/rtgui/multilangmgr.h new file mode 100644 index 000000000..e22d7fa96 --- /dev/null +++ b/rtgui/multilangmgr.h @@ -0,0 +1,45 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _MULTILANGMGR_ +#define _MULTILANGMGR_ + +#include +#include +#include + +class MultiLangMgr { + + std::map transTable; + MultiLangMgr* fallBack; + + public: + MultiLangMgr () : fallBack (NULL) {} + MultiLangMgr (Glib::ustring fname) : fallBack (NULL) { load (fname); } + + bool load (Glib::ustring fname, MultiLangMgr* fb = NULL); + bool save (Glib::ustring fname); + + Glib::ustring getStr (std::string key); +}; + +extern MultiLangMgr langMgr; + +Glib::ustring M (std::string key); + +#endif diff --git a/rtgui/mycurve.cc b/rtgui/mycurve.cc new file mode 100644 index 000000000..9460be070 --- /dev/null +++ b/rtgui/mycurve.cc @@ -0,0 +1,496 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +#define RADIUS 3 /* radius of the control points */ +#define MIN_DISTANCE 8 /* min distance between control points */ + +MyCurve::MyCurve () : listener(NULL), activeParam(-1), bghistvalid(false) { + + cursor_type = Gdk::TOP_LEFT_ARROW; + curve.type = Spline; + height = 0; + grab_point = -1; + + add_events(Gdk::EXPOSURE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::POINTER_MOTION_HINT_MASK | Gdk::ENTER_NOTIFY_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK); + signal_event().connect( sigc::mem_fun(*this, &MyCurve::handleEvents) ); + + curve.x.push_back(0); + curve.y.push_back(0); + curve.x.push_back(1); + curve.y.push_back(1); + curve.type = Spline; + + mcih = new MyCurveIdleHelper; + mcih->myCurve = this; + mcih->destroyed = false; + mcih->pending = 0; +} + +MyCurve::~MyCurve () { + + if (mcih->pending) + mcih->destroyed = true; + else + delete mcih; +} + +std::vector MyCurve::get_vector (int veclen) { + + std::vector vector; + vector.resize (veclen); + + if (curve.type != Parametric) { + // count active points: + double prev =- 1.0; + int active = 0; + int firstact = -1; + for (int i = 0; i < curve.x.size(); ++i) + if (curve.x[i] > prev) { + if (firstact < 0) + firstact = i; + prev = curve.x[i]; + ++active; + } + // handle degenerate case: + if (active < 2) { + double ry; + if (active > 0) + ry = curve.y[firstact]; + else + ry = 0.0; + if (ry < 0.0) ry = 0.0; + if (ry > 1.0) ry = 1.0; + for (int x = 0; x < veclen; ++x) + vector[x] = ry; + return vector; + } + } + + // calculate remaining points + std::vector curveDescr = getPoints (); + rtengine::Curve* rtcurve = new rtengine::Curve (curveDescr); + std::vector t; + t.resize (veclen); + for (int i = 0; i < veclen; i++) + t[i] = (double) i / (veclen - 1.0); + rtcurve->getVal (t, vector); + delete rtcurve; + return vector; +} + +void MyCurve::interpolate (int width, int height) { + + this->height = height; + point.resize (width); + std::vector vector = get_vector (width); + this->height = height; + for (int i = 0; i < width; ++i) + point[i] = Gdk::Point (RADIUS + i, RADIUS + height - (int)((height-1) * vector[i] + 0.5)); + upoint.clear (); + lpoint.clear (); + + if (curve.type==Parametric && activeParam>0) { + double tmp = curve.x[activeParam-1]; + if (activeParam>=4) { + upoint.resize(width); + lpoint.resize(width); + curve.x[activeParam-1] = 100; + vector = get_vector (width); + for (int i = 0; i < width; ++i) + upoint[i] = Gdk::Point (RADIUS + i, RADIUS + height - (int)((height-1) * vector[i] + 0.5)); + curve.x[activeParam-1] = -100; + vector = get_vector (width); + for (int i = 0; i < width; ++i) + lpoint[i] = Gdk::Point (RADIUS + i, RADIUS + height - (int)((height-1) * vector[i] + 0.5)); + curve.x[activeParam-1] = tmp; + } + } +} + +void MyCurve::draw (int width, int height) { + + if (!pixmap) + return; + + // re-calculate curve if dimensions changed + if (this->height != height || point.size() != width) + interpolate (width, height); + + + Gtk::StateType state = Gtk::STATE_NORMAL; + if (!is_sensitive()) + state = Gtk::STATE_INSENSITIVE; + + Glib::RefPtr style = get_style (); + Cairo::RefPtr cr = pixmap->create_cairo_context(); + + // bounding rectangle + Gdk::Color c = style->get_bg (state); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->rectangle (0, 0, width + RADIUS*2, height + RADIUS*2); + cr->fill (); + + // histogram in the background + if (bghistvalid) { + // find heighest bin + int histheight = 0; + for (int i=0; i<256; i++) + if (bghist[i]>histheight) + histheight = bghist[i]; + // draw histogram + cr->set_line_width (1.0); + double stepSize = (width-1) / 256.0; + cr->move_to (0, height-1); + cr->set_source_rgb (0.75, 0.75, 0.75); + for (int i=0; i<256; i++) { + double val = bghist[i] * (double)(height-2) / histheight; + if (val>height-1) + val = height-1; + if (i>0) + cr->line_to (i*stepSize, height-1-val); + } + cr->line_to (width-1, height-1); + cr->fill (); + } + + // draw the grid lines: + cr->set_line_width (1.0); + c = style->get_dark (state); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->set_antialias (Cairo::ANTIALIAS_NONE); + for (int i = 0; i < 5; i++) { + cr->move_to (RADIUS, i * height / 4 + RADIUS); + cr->line_to (width + RADIUS, i * height / 4 + RADIUS); + cr->move_to (i * width / 4 + RADIUS, RADIUS); + cr->line_to (i * width / 4 + RADIUS, height + RADIUS); + } + cr->stroke (); + + // draw f(x)=x line + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + std::valarray ds (1); + ds[0] = 4; + cr->set_dash (ds, 0); + cr->move_to (RADIUS, height + RADIUS); + cr->line_to (width + RADIUS, RADIUS); + cr->stroke (); + cr->unset_dash (); + + cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + cr->set_line_width (1.0); + + // draw upper and lower bounds + if (curve.type==Parametric && activeParam>0 && lpoint.size()>1 && upoint.size()>1) { + cr->set_source_rgba (0.0, 0.0, 0.0, 0.15); + cr->move_to (upoint[0].get_x(), upoint[0].get_y()); + for (int i=1; iline_to (upoint[i].get_x(), upoint[i].get_y()); + cr->line_to (lpoint[lpoint.size()-1].get_x(), lpoint[lpoint.size()-1].get_y()); + for (int i=lpoint.size()-2; i>=0; i--) + cr->line_to (lpoint[i].get_x(), lpoint[i].get_y()); + cr->line_to (upoint[0].get_x(), upoint[0].get_y()); + cr->fill (); + } + + // draw curve + cr->set_source_rgb (0.0, 0.0, 0.0); + cr->move_to (point[0].get_x(), point[0].get_y()); + for (int i=1; iline_to (point[i].get_x(), point[i].get_y()); + cr->stroke (); + + // draw bullets + if (curve.type!=Parametric) + for (int i = 0; i < curve.x.size(); ++i) { + double x = ((width-1) * curve.x[i] + 0.5)+RADIUS; // project (curve.x[i], 0, 1, width); + double y = height - ((height-1) * curve.y[i] + 0.5)+RADIUS; // project (curve.y[i], 0, 1, height); + + cr->arc (x, y, RADIUS, 0, 2*M_PI); + cr->fill (); + } + + get_window()->draw_drawable (style->get_fg_gc (state), pixmap, 0, 0, 0, 0, width + RADIUS * 2, height + RADIUS * 2); +} + +bool MyCurve::handleEvents (GdkEvent* event) { + + Gdk::CursorType new_type = cursor_type; + int src, dst; + GdkEventMotion *mevent; + std::vector::iterator itx, ity; + + bool retval = false; + + int width = get_allocation().get_width() - RADIUS * 2; + int height = get_allocation().get_height() - RADIUS * 2; + + if ((width < 0) || (height < 0)) + return false; + + /* get the pointer position */ + int tx, ty; + Gdk::ModifierType gm; + get_window()->get_pointer (tx, ty, gm); + int x = CLAMP ((tx - RADIUS), 0, width-1); + int y = CLAMP ((ty - RADIUS), 0, height-1); + + unsigned int distance = ~0U; + int num = curve.x.size(); + int closest_point = 0; + + if (curve.type!=Parametric) { + for (int i = 0; i < num; ++i) { + int cx = (int)((width-1) * curve.x[i] + 0.5); //project (c->ctlpoint[i][0], min_x, c->max_x, width); + if ((unsigned int) abs (x - cx) < distance) { + distance = abs (x - cx); + closest_point = i; + } + } + } + + switch (event->type) { + case Gdk::CONFIGURE: + if (pixmap) + pixmap.clear (); + + case Gdk::EXPOSE: + if (!pixmap) { + pixmap = Gdk::Pixmap::create (get_window(), get_allocation().get_width(), get_allocation().get_height()); + interpolate (width, height); + } + draw (width, height); + break; + + case Gdk::BUTTON_PRESS: + if (curve.type!=Parametric) { + add_modal_grab (); + new_type = Gdk::PLUS; + if (distance > MIN_DISTANCE) { + /* insert a new control point */ + if (num > 0) { + int cx = (int)((width-1)*curve.x[closest_point]+0.5); + if (x > cx) + ++closest_point; + } + itx = curve.x.begin(); + ity = curve.y.begin(); + for (int i=0; i= 0.0) { + curve.x[dst] = curve.x[src]; + curve.y[dst] = curve.y[src]; + ++dst; + ++itx; + ++ity; + } + if (dst < src) { + curve.x.erase (itx, curve.x.end()); + curve.y.erase (ity, curve.y.end()); + if (curve.x.size() <= 0) { + curve.x.push_back (0); + curve.y.push_back (0); + interpolate (width, height); + draw (width, height); + } + } + new_type = Gdk::FLEUR; + grab_point = -1; + retval = true; + notifyListener (); + } + break; + + case Gdk::MOTION_NOTIFY: + mevent = (GdkEventMotion *) event; + if (curve.type == Linear || curve.type == Spline) { + if (grab_point == -1) { + /* if no point is grabbed... */ + if (distance <= MIN_DISTANCE) + new_type = Gdk::FLEUR; + else + new_type = Gdk::PLUS; + } + else { + /* drag the grabbed point */ + new_type = Gdk::FLEUR; + int leftbound = -MIN_DISTANCE; + if (grab_point > 0) + leftbound = (int)((width-1)*curve.x[grab_point-1]+0.5); + + int rightbound = width + RADIUS * 2 + MIN_DISTANCE; + if (grab_point + 1 < num) + rightbound = (int)((width-1)*curve.x[grab_point+1]+0.5); + + if (tx <= leftbound || tx >= rightbound || ty > height + RADIUS * 2 + MIN_DISTANCE || ty < -MIN_DISTANCE) + curve.x[grab_point] = -1.0; + else { + curve.x[grab_point] = (double) x / (width-1); + curve.y[grab_point] = (double) (height-y) / (height-1); + } + interpolate (width, height); + draw (width, height); + notifyListener (); + } + } + + if (new_type != cursor_type) { + cursor_type = new_type; + Gdk::Cursor* cursor = new Gdk::Cursor (get_display(), cursor_type); + get_window ()->set_cursor (*cursor); + delete cursor; + } + retval = true; + break; + + default: + break; + } + return retval; +} + +std::vector MyCurve::getPoints () { + + std::vector result; + if (curve.type==Parametric) { + result.push_back (+2.0); + for (int i=0; i=0) { + result.push_back (curve.x[i]); + result.push_back (curve.y[i]); + } + } + return result; +} + +void MyCurve::setPoints (const std::vector& p) { + + int ix = 0; + int t = p[ix++]; + if (t==2) { + curve.type = Parametric; + curve.x.clear (); + curve.y.clear (); + for (int i=1; icurveChanged (); +} + +void MyCurve::setActiveParam (int ac) { + + activeParam = ac; + pixmap.clear (); + queue_draw (); +} + +int mchistupdate (void* data) { + + gdk_threads_enter (); + + MyCurveIdleHelper* mcih = (MyCurveIdleHelper*)data; + + if (mcih->destroyed) { + if (mcih->pending == 1) + delete mcih; + else + mcih->pending--; + gdk_threads_leave (); + return 0; + } + + mcih->myCurve->pixmap.clear (); + mcih->myCurve->queue_draw (); + + mcih->pending--; + gdk_threads_leave (); + return 0; +} + +void MyCurve::updateBackgroundHistogram (unsigned int* hist) { + + if (hist!=NULL) { + memcpy (bghist, hist, 256*sizeof(unsigned int)); + bghistvalid = true; + } + else + bghistvalid = false; + + mcih->pending++; + g_idle_add (mchistupdate, mcih); + +} + diff --git a/rtgui/mycurve.h b/rtgui/mycurve.h new file mode 100644 index 000000000..168c70ec3 --- /dev/null +++ b/rtgui/mycurve.h @@ -0,0 +1,80 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _MYCURVE_ +#define _MYCURVE_ + +#include +#include +#include + +enum CurveType {Linear, Spline, Parametric}; + +class CurveDescr { + + public: + CurveType type; + std::vector x, y; // in case of parametric curves the curve parameters are stored in vector x. In other cases these vectors store the coordinates of the bullets. +}; + +class MyCurve; +struct MyCurveIdleHelper { + MyCurve* myCurve; + bool destroyed; + int pending; +}; + +class MyCurve : public Gtk::DrawingArea { + + friend int mchistupdate (void* data); + + protected: + CurveListener* listener; + CurveDescr curve; + Gdk::CursorType cursor_type; + Glib::RefPtr pixmap; + int height; + int grab_point; + int last; + std::vector point; + std::vector upoint; + std::vector lpoint; + int activeParam; + unsigned int bghist[256]; + bool bghistvalid; + MyCurveIdleHelper* mcih; + + void draw (int width, int height); + void interpolate (int width, int height); + std::vector get_vector (int veclen); + + public: + MyCurve (); + ~MyCurve (); + + void setCurveListener (CurveListener* cl) { listener = cl; } + std::vector getPoints (); + void setPoints (const std::vector& p); + void setType (CurveType t); + bool handleEvents (GdkEvent* event); + void notifyListener (); + void setActiveParam (int ac); + void updateBackgroundHistogram (unsigned int* hist); +}; + +#endif diff --git a/rtgui/myicon.o b/rtgui/myicon.o new file mode 100644 index 000000000..5f2bced97 Binary files /dev/null and b/rtgui/myicon.o differ diff --git a/rtgui/myicon.rc b/rtgui/myicon.rc new file mode 100644 index 000000000..b986cd1b6 --- /dev/null +++ b/rtgui/myicon.rc @@ -0,0 +1 @@ +1 ICON "RT.ico" diff --git a/rtgui/navigator.cc b/rtgui/navigator.cc new file mode 100644 index 000000000..cf4306985 --- /dev/null +++ b/rtgui/navigator.cc @@ -0,0 +1,115 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +Navigator::Navigator () { + + set_label (M("MAIN_MSG_NAVIGATOR")); + Gtk::VBox* mbox = Gtk::manage (new Gtk::VBox ()); + previewWindow = Gtk::manage (new PreviewWindow ()); + mbox->pack_start (*previewWindow, Gtk::PACK_SHRINK, 2); + position = Gtk::manage (new Gtk::Label ()); + mbox->pack_start (*position, Gtk::PACK_SHRINK, 2); + + R = Gtk::manage (new Gtk::Label ()); + G = Gtk::manage (new Gtk::Label ()); + B = Gtk::manage (new Gtk::Label ()); + H = Gtk::manage (new Gtk::Label ()); + S = Gtk::manage (new Gtk::Label ()); + V = Gtk::manage (new Gtk::Label ()); + + Gtk::Table* table = new Gtk::Table (3, 2); + table->attach (*R, 0, 1, 0, 1, Gtk::EXPAND, Gtk::SHRINK, 0, 0); + table->attach (*G, 0, 1, 1, 2, Gtk::EXPAND, Gtk::SHRINK, 0, 0); + table->attach (*B, 0, 1, 2, 3, Gtk::EXPAND, Gtk::SHRINK, 0, 0); + table->attach (*H, 1, 2, 0, 1, Gtk::EXPAND, Gtk::SHRINK, 0, 0); + table->attach (*S, 1, 2, 1, 2, Gtk::EXPAND, Gtk::SHRINK, 0, 0); + table->attach (*V, 1, 2, 2, 3, Gtk::EXPAND, Gtk::SHRINK, 0, 0); + + mbox->pack_start (*table, Gtk::PACK_SHRINK, 2); + + add (*mbox); + + setInvalid (); + show_all (); +} + +void Navigator::setInvalid () { + + position->set_text ("x = n/a, y = n/a"); + R->set_text (M("NAVIGATOR_R_NA")); + G->set_text (M("NAVIGATOR_G_NA")); + B->set_text (M("NAVIGATOR_B_NA")); + H->set_text (M("NAVIGATOR_H_NA")); + S->set_text (M("NAVIGATOR_S_NA")); + V->set_text (M("NAVIGATOR_V_NA")); +} + +void Navigator::pointerMoved (bool validPos, int x, int y, int r, int g, int b) { + + if (!validPos) + setInvalid (); + else { + position->set_text (Glib::ustring::compose ("x = %1, y = %2", x, y)); + R->set_text (Glib::ustring::compose (M("NAVIGATOR_R_VALUE"), r)); + G->set_text (Glib::ustring::compose (M("NAVIGATOR_G_VALUE"), g)); + B->set_text (Glib::ustring::compose (M("NAVIGATOR_B_VALUE"), b)); + int h, s, v; + rgb2hsv (r, g, b, h, s, v); + H->set_text (Glib::ustring::compose (M("NAVIGATOR_H_VALUE"), h)); + S->set_text (Glib::ustring::compose (M("NAVIGATOR_S_VALUE"), s)); + V->set_text (Glib::ustring::compose (M("NAVIGATOR_V_VALUE"), v)); + } +} + +void Navigator::rgb2hsv (int r, int g, int b, int &h, int &s, int &v) { + + volatile double var_R = r / 255.0; + volatile double var_G = g / 255.0; + volatile double var_B = b / 255.0; + + volatile double var_Min = MIN(MIN(var_R,var_G),var_B); + volatile double var_Max = MAX(MAX(var_R,var_G),var_B); + double del_Max = var_Max - var_Min; + double V = (var_Max + var_Min) / 2; + double H, S; + if (fabs(del_Max)<0.0000001) { + H = 0; + S = 0; + } + else { + if (V < 0.5) S = del_Max / (var_Max + var_Min); + else S = del_Max / (2 - var_Max - var_Min); + + double del_R = ( ( ( var_Max - var_R ) / 6.0 ) + ( del_Max / 2.0 ) ) / del_Max; + double del_G = ( ( ( var_Max - var_G ) / 6.0 ) + ( del_Max / 2.0 ) ) / del_Max; + double del_B = ( ( ( var_Max - var_B ) / 6.0 ) + ( del_Max / 2.0 ) ) / del_Max; + if ( var_R == var_Max ) H = del_B - del_G; + else if ( var_G == var_Max ) H = (1.0 / 3.0) + del_R - del_B; + else if ( var_B == var_Max ) H = (2.0 / 3.0) + del_G - del_R; + + if ( H < 0 ) H += 1; + if ( H > 1 ) H -= 1; + } + + h = (int)(H*255.0); + s = (int)(S*255.0); + v = (int)(V*255.0); +} diff --git a/rtgui/navigator.h b/rtgui/navigator.h new file mode 100644 index 000000000..4e67770bc --- /dev/null +++ b/rtgui/navigator.h @@ -0,0 +1,45 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _NAVIGATOR_ +#define _NAVIGATOR_ + +#include +#include +#include + +class Navigator : public Gtk::Frame, public PointerMotionListener { + + protected: + Gtk::Label* position; + Gtk::Label *R, *G, *B; + Gtk::Label *H, *S, *V; + + void rgb2hsv (int r, int g, int b, int &h, int &s, int &v); + void setInvalid (); + public: + PreviewWindow* previewWindow; + + Navigator (); + + // pointermotionlistener interface + void pointerMoved (bool validPos, int x, int y, int r, int g, int b); + +}; + +#endif diff --git a/rtgui/options.cc b/rtgui/options.cc new file mode 100644 index 000000000..001d5369a --- /dev/null +++ b/rtgui/options.cc @@ -0,0 +1,441 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include +#include + +Options options; +Glib::ustring versionString = "v3.0 alpha 1"; + +Options::Options () { + + setDefaults (); +} + +const char *DefaultLanguage = "English (US)"; + +void Options::setDefaults () { + + windowWidth = 1000; + windowHeight = 600; + firstRun = true; + savesParamsAtExit = true; + saveFormat.format = "jpg"; + saveFormat.jpegQuality = 100; + saveFormat.pngCompression = 6; + saveFormat.pngBits = 8; + saveFormat.tiffBits = 8; + saveFormat.tiffUncompressed = true; + saveFormat.saveParams = false; + savePathTemplate = "\%p1/converted/\%f"; + savePathFolder = ""; + saveUsePathTemplate = true; + defProfRaw = "default"; + defProfImg = "neutral"; + dateFormat = "%y-%m-%d"; + startupDir = 1; + startupPath = ""; + profilePath = "profiles"; + dirBrowserWidth = 200; + dirBrowserHeight = 150; + toolPanelWidth = 250; + browserToolPanelWidth = 250; + historyPanelWidth = 150; + lastScale = 4; + lastCropSize = 1; + fbOnlyRaw = false; + fbShowDateTime = true; + fbShowBasicExif = true; + fbShowHidden = false; + fbArrangement = 0; + multiUser = false; + version = 290; + thumbSize = 80; + showHistory = true; + showFilePanelState = 0; + showInfo = false; + cropDPI = 300; + showClippedHighlights = false; + showClippedShadows = false; + highlightThreshold = 254; + shadowThreshold = 0; + bgcolor = 0; + blinkClipped = true; + language = DefaultLanguage; + lastSaveAsPath = ""; + theme = ""; + maxThumbnailHeight = 400; + maxCacheEntries = 10000; + thumbnailFormat = FT_Custom16; + thumbInterp = 1; + saveParamsFile = false; + saveParamsCache = true; + paramsLoadLocation = PLL_Cache; + procQueueEnabled = true; + gimpDir = "C:\\Program Files\\GIMP-2.0"; + psDir = "C:\\Program Files\\Adobe\\Adobe Photoshop CS3"; + customEditorProg = "start"; + editorToSendTo = 1; + liveThumbnails = true; + tpOpen.clear (); + crvOpen.clear (); + parseExtensions.clear (); + parseExtensionsEnabled.clear (); + renameUseTemplates = false; + renameTemplates.clear (); + thumbnailZoomRatios.clear (); + thumbnailZoomRatios.push_back (0.2); + thumbnailZoomRatios.push_back (0.3); + thumbnailZoomRatios.push_back (0.45); + thumbnailZoomRatios.push_back (0.6); + thumbnailZoomRatios.push_back (0.8); + thumbnailZoomRatios.push_back (1.0); + overlayedFileNames = true; + showFileNames = true; + + int babehav[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0}; + baBehav = std::vector (babehav, babehav+ADDSET_PARAM_NUM); + + rtSettings.dualThreadEnabled = true; + rtSettings.demosaicMethod = "eahd"; + rtSettings.colorCorrectionSteps = 2; + rtSettings.dcb_iterations = 2; + rtSettings.dcb_enhance = true; + rtSettings.iccDirectory = "/usr/share/color/icc"; + rtSettings.colorimetricIntent = 1; + rtSettings.monitorProfile = ""; + rtSettings.verbose = false; +} + +Options* Options::copyFrom (Options* other) { + + *this = *other; + return this; +} + +int Options::readFromFile (Glib::ustring fname) { + + rtengine::SafeKeyFile keyFile; + + try { + if (!keyFile.load_from_file (fname)) + return 1; + } + catch (Glib::FileError) { + return 1; + } + + setDefaults (); + +if (keyFile.has_group ("General")) { + Glib::ustring stup; + if (keyFile.has_key ("General", "StartupDirectory") && keyFile.get_string ("General", "StartupDirectory") == "home") + startupDir = STARTUPDIR_HOME; + else if (keyFile.has_key ("General", "StartupDirectory") && keyFile.get_string ("General", "StartupDirectory") == "current") + startupDir = STARTUPDIR_CURRENT; + else if (keyFile.has_key ("General", "StartupDirectory") && keyFile.get_string ("General", "StartupDirectory") == "last") + startupDir = STARTUPDIR_LAST; + else + startupDir = STARTUPDIR_CUSTOM; + + if (keyFile.has_key ("General", "StartupPath")) startupPath = keyFile.get_string ("General", "StartupPath"); + if (keyFile.has_key ("General", "DateFormat")) dateFormat = keyFile.get_string ("General", "DateFormat"); + if (keyFile.has_key ("General", "AdjusterDelay")) Adjuster::delay = keyFile.get_integer ("General", "AdjusterDelay"); + if (keyFile.has_key ("General", "StoreLastProfile")) savesParamsAtExit = keyFile.get_boolean ("General", "StoreLastProfile"); + if (keyFile.has_key ("General", "DualProcSupport")) rtSettings.dualThreadEnabled = keyFile.get_boolean ("General", "DualProcSupport"); + if (keyFile.has_key ("General", "MultiUser")) multiUser = keyFile.get_boolean ("General", "MultiUser"); +// if (keyFile.has_key ("General", "Version")) version = keyFile.get_integer ("General", "Version"); + if (keyFile.has_key ("General", "Language")) language = keyFile.get_string ("General", "Language"); + if (keyFile.has_key ("General", "Theme")) theme = keyFile.get_string ("General", "Theme"); + if (keyFile.has_key ("General", "FirstRun")) firstRun = keyFile.get_boolean ("General", "FirstRun"); +} + +if (keyFile.has_group ("External Editor")) { + if (keyFile.has_key ("External Editor", "EditorKind")) editorToSendTo = keyFile.get_integer ("External Editor", "EditorKind"); + if (keyFile.has_key ("External Editor", "GimpDir")) gimpDir = keyFile.get_string ("External Editor", "GimpDir"); + if (keyFile.has_key ("External Editor", "PhotoshopDir")) psDir = keyFile.get_string ("External Editor", "PhotoshopDir"); + if (keyFile.has_key ("External Editor", "CustomEditor")) customEditorProg = keyFile.get_string ("External Editor", "CustomEditor"); +} + +if (keyFile.has_group ("Output")) { + if (keyFile.has_key ("Output", "Format")) saveFormat.format = keyFile.get_string ("Output", "Format"); + if (keyFile.has_key ("Output", "JpegQuality")) saveFormat.jpegQuality = keyFile.get_integer ("Output", "JpegQuality"); + if (keyFile.has_key ("Output", "PngCompression")) saveFormat.pngCompression = keyFile.get_integer ("Output", "PngCompression"); + if (keyFile.has_key ("Output", "PngBps")) saveFormat.pngBits = keyFile.get_integer ("Output", "PngBps"); + if (keyFile.has_key ("Output", "TiffBps")) saveFormat.tiffBits = keyFile.get_integer ("Output", "TiffBps"); + if (keyFile.has_key ("Output", "SaveProcParams")) saveFormat.saveParams = keyFile.get_boolean ("Output", "SaveProcParams"); + if (keyFile.has_key ("Output", "Path")) savePathTemplate = keyFile.get_string ("Output", "Path"); + if (keyFile.has_key ("Output", "PathTemplate")) savePathTemplate = keyFile.get_string ("Output", "PathTemplate"); + if (keyFile.has_key ("Output", "PathFolder")) savePathFolder = keyFile.get_string ("Output", "PathFolder"); + if (keyFile.has_key ("Output", "UsePathTemplate")) saveUsePathTemplate = keyFile.get_boolean("Output", "UsePathTemplate"); + if (keyFile.has_key ("Output", "LastSaveAsPath")) lastSaveAsPath = keyFile.get_string ("Output", "LastSaveAsPath"); +} + +if (keyFile.has_group ("Profiles")) { + if (keyFile.has_key ("Profiles", "Directory")) profilePath = keyFile.get_string ("Profiles", "Directory"); + if (keyFile.has_key ("Profiles", "RawDefault")) defProfRaw = keyFile.get_string ("Profiles", "RawDefault"); + if (keyFile.has_key ("Profiles", "ImgDefault")) defProfImg = keyFile.get_string ("Profiles", "ImgDefault"); + if (keyFile.has_key ("Profiles", "SaveParamsWithFile")) saveParamsFile = keyFile.get_boolean ("Profiles", "SaveParamsWithFile"); + if (keyFile.has_key ("Profiles", "SaveParamsToCache")) saveParamsCache = keyFile.get_boolean ("Profiles", "SaveParamsToCache"); + if (keyFile.has_key ("Profiles", "LoadParamsFromLocation")) paramsLoadLocation = (PPLoadLocation)keyFile.get_integer ("Profiles", "LoadParamsFromLocation"); +} + +if (keyFile.has_group ("File Browser")) { + if (keyFile.has_key ("File Browser", "ThumbnailSize")) thumbSize = keyFile.get_integer ("File Browser", "ThumbnailSize"); + if (keyFile.has_key ("File Browser", "BrowseOnlyRaw")) fbOnlyRaw = keyFile.get_boolean ("File Browser", "BrowseOnlyRaw"); + if (keyFile.has_key ("File Browser", "BrowserShowsDate")) fbShowDateTime = keyFile.get_boolean ("File Browser", "BrowserShowsDate"); + if (keyFile.has_key ("File Browser", "BrowserShowsExif")) fbShowBasicExif = keyFile.get_boolean ("File Browser", "BrowserShowsExif"); + if (keyFile.has_key ("File Browser", "BrowserShowsHidden")) fbShowHidden = keyFile.get_boolean ("File Browser", "BrowserShowsHidden"); + if (keyFile.has_key ("File Browser", "MaxPreviewHeight")) maxThumbnailHeight = keyFile.get_integer ("File Browser", "MaxPreviewHeight"); + if (keyFile.has_key ("File Browser", "MaxCacheEntries")) maxCacheEntries = keyFile.get_integer ("File Browser", "MaxCacheEntries"); + if (keyFile.has_key ("File Browser", "ThumbnailFormat")) thumbnailFormat = (ThFileType)keyFile.get_integer ("File Browser", "ThumbnailFormat"); + if (keyFile.has_key ("File Browser", "ParseExtensions")) parseExtensions = keyFile.get_string_list ("File Browser", "ParseExtensions"); + if (keyFile.has_key ("File Browser", "ParseExtensionsEnabled")) parseExtensionsEnabled = keyFile.get_integer_list ("File Browser", "ParseExtensionsEnabled"); + if (keyFile.has_key ("File Browser", "ThumbnailArrangement")) fbArrangement = keyFile.get_integer ("File Browser", "ThumbnailArrangement"); + if (keyFile.has_key ("File Browser", "ThumbnailInterpolation")) thumbInterp = keyFile.get_integer ("File Browser", "ThumbnailInterpolation"); + if (keyFile.has_key ("File Browser", "LiveThumbnails")) liveThumbnails = keyFile.get_boolean ("File Browser", "LiveThumbnails"); + if (keyFile.has_key ("File Browser", "FavoriteDirs")) favoriteDirs = keyFile.get_string_list ("File Browser", "FavoriteDirs"); + if (keyFile.has_key ("File Browser", "RenameTemplates")) renameTemplates = keyFile.get_string_list ("File Browser", "RenameTemplates"); + if (keyFile.has_key ("File Browser", "RenameUseTemplates")) renameUseTemplates = keyFile.get_boolean ("File Browser", "RenameUseTemplates"); + if (keyFile.has_key ("File Browser", "ThumbnailZoomRatios"))thumbnailZoomRatios= keyFile.get_double_list ("File Browser", "ThumbnailZoomRatios"); + if (keyFile.has_key ("File Browser", "OverlayedFileNames")) overlayedFileNames = keyFile.get_boolean ("File Browser", "OverlayedFileNames"); + if (keyFile.has_key ("File Browser", "ShowFileNames")) showFileNames = keyFile.get_boolean ("File Browser", "ShowFileNames"); +} + +if (keyFile.has_group ("Clipping Indication")) { + if (keyFile.has_key ("Clipping Indication", "HighlightThreshold")) highlightThreshold= keyFile.get_integer ("Clipping Indication", "HighlightThreshold"); + if (keyFile.has_key ("Clipping Indication", "ShadowThreshold")) shadowThreshold = keyFile.get_integer ("Clipping Indication", "ShadowThreshold"); + if (keyFile.has_key ("Clipping Indication", "BlinkClipped")) blinkClipped = keyFile.get_boolean ("Clipping Indication", "BlinkClipped"); +} + +if (keyFile.has_group ("GUI")) { + if (keyFile.has_key ("GUI", "WindowWidth")) windowWidth = keyFile.get_integer ("GUI", "WindowWidth"); + if (keyFile.has_key ("GUI", "WindowHeight")) windowHeight = keyFile.get_integer ("GUI", "WindowHeight"); + if (keyFile.has_key ("GUI", "DirBrowserWidth")) dirBrowserWidth = keyFile.get_integer ("GUI", "DirBrowserWidth"); + if (keyFile.has_key ("GUI", "DirBrowserHeight")) dirBrowserHeight = keyFile.get_integer ("GUI", "DirBrowserHeight"); + if (keyFile.has_key ("GUI", "ToolPanelWidth")) toolPanelWidth = keyFile.get_integer ("GUI", "ToolPanelWidth"); + if (keyFile.has_key ("GUI", "BrowserToolPanelWidth"))browserToolPanelWidth = keyFile.get_integer ("GUI", "BrowserToolPanelWidth"); + if (keyFile.has_key ("GUI", "HistoryPanelWidth")) historyPanelWidth = keyFile.get_integer ("GUI", "HistoryPanelWidth"); + if (keyFile.has_key ("GUI", "LastPreviewScale")) lastScale = keyFile.get_integer ("GUI", "LastPreviewScale"); + if (keyFile.has_key ("GUI", "LastCropSize")) lastCropSize = keyFile.get_integer ("GUI", "LastCropSize"); + if (keyFile.has_key ("GUI", "ShowHistory")) showHistory = keyFile.get_boolean ("GUI", "ShowHistory"); + if (keyFile.has_key ("GUI", "ShowFilePanelState")) showFilePanelState= keyFile.get_integer ("GUI", "ShowFilePanelState"); + if (keyFile.has_key ("GUI", "ShowInfo")) showInfo = keyFile.get_boolean ("GUI", "ShowInfo"); + if (keyFile.has_key ("GUI", "ShowClippedHighlights"))showClippedHighlights = keyFile.get_boolean ("GUI", "ShowClippedHighlights"); + if (keyFile.has_key ("GUI", "ShowClippedShadows")) showClippedShadows= keyFile.get_boolean ("GUI", "ShowClippedShadows"); + if (keyFile.has_key ("GUI", "FrameColor")) bgcolor = keyFile.get_integer ("GUI", "FrameColor"); + if (keyFile.has_key ("GUI", "ProcessingQueueEnbled"))procQueueEnabled = keyFile.get_boolean ("GUI", "ProcessingQueueEnbled"); + if (keyFile.has_key ("GUI", "ToolPanelsExpanded")) tpOpen = keyFile.get_integer_list ("GUI", "ToolPanelsExpanded"); + if (keyFile.has_key ("GUI", "CurvePanelsExpanded")) crvOpen = keyFile.get_integer_list ("GUI", "CurvePanelsExpanded"); +} + +if (keyFile.has_group ("Algorithms")) { + if (keyFile.has_key ("Algorithms", "DemosaicMethod")) rtSettings.demosaicMethod = keyFile.get_string ("Algorithms", "DemosaicMethod"); + if (keyFile.has_key ("Algorithms", "ColorCorrection")) rtSettings.colorCorrectionSteps = keyFile.get_integer ("Algorithms", "ColorCorrection"); + if(keyFile.has_key("Algorithms", "DCBIterations")) rtSettings.dcb_iterations = keyFile.get_integer("Algorithms", "DCBIterations"); + if(keyFile.has_key("Algorithms", "DCBEnhance")) rtSettings.dcb_enhance = keyFile.get_boolean("Algorithms", "DCBEnhance"); +} + +if (keyFile.has_group ("Crop Settings")) { + if (keyFile.has_key ("Crop Settings", "DPI")) cropDPI = keyFile.get_integer ("Crop Settings", "DPI"); +} + +if (keyFile.has_group ("Color Management")) { + if (keyFile.has_key ("Color Management", "ICCDirectory")) rtSettings.iccDirectory = keyFile.get_string ("Color Management", "ICCDirectory"); + if (keyFile.has_key ("Color Management", "MonitorProfile")) rtSettings.monitorProfile = keyFile.get_string ("Color Management", "MonitorProfile"); + if (keyFile.has_key ("Color Management", "Intent")) rtSettings.colorimetricIntent = keyFile.get_integer("Color Management", "Intent"); +} + +if (keyFile.has_group ("Batch Processing")) { + if (keyFile.has_key ("Batch Processing", "AdjusterBehavior")) baBehav = keyFile.get_integer_list ("Batch Processing", "AdjusterBehavior"); +} + + return 0; +} + +int Options::saveToFile (Glib::ustring fname) { + + rtengine::SafeKeyFile keyFile; + + keyFile.set_boolean ("General", "StoreLastProfile", savesParamsAtExit); + if (startupDir==STARTUPDIR_HOME) + keyFile.set_string ("General", "StartupDirectory", "home"); + else if (startupDir==STARTUPDIR_CURRENT) + keyFile.set_string ("General", "StartupDirectory", "current"); + else if (startupDir==STARTUPDIR_CUSTOM) + keyFile.set_string ("General", "StartupDirectory", "custom"); + else if (startupDir==STARTUPDIR_LAST) + keyFile.set_string ("General", "StartupDirectory", "last"); + keyFile.set_string ("General", "StartupPath", startupPath); + keyFile.set_string ("General", "DateFormat", dateFormat); + keyFile.set_integer ("General", "AdjusterDelay", Adjuster::delay); + keyFile.set_boolean ("General", "DualProcSupport", rtSettings.dualThreadEnabled); + keyFile.set_boolean ("General", "MultiUser", multiUser); + keyFile.set_string ("General", "Language", language); + keyFile.set_string ("General", "Theme", theme); + keyFile.set_integer ("General", "Version", 290); + keyFile.set_boolean ("General", "FirstRun", firstRun); + + keyFile.set_integer ("External Editor", "EditorKind", editorToSendTo); + keyFile.set_string ("External Editor", "GimpDir", gimpDir); + keyFile.set_string ("External Editor", "PhotoshopDir", psDir); + keyFile.set_string ("External Editor", "CustomEditor", customEditorProg); + + + keyFile.set_boolean ("File Browser", "BrowseOnlyRaw", fbOnlyRaw); + keyFile.set_boolean ("File Browser", "BrowserShowsDate", fbShowDateTime); + keyFile.set_boolean ("File Browser", "BrowserShowsExif", fbShowBasicExif); + keyFile.set_boolean ("File Browser", "BrowserShowsHidden", fbShowHidden); + keyFile.set_integer ("File Browser", "ThumbnailSize", thumbSize); + keyFile.set_integer ("File Browser", "MaxPreviewHeight", maxThumbnailHeight); + keyFile.set_integer ("File Browser", "MaxCacheEntries", maxCacheEntries); + keyFile.set_integer ("File Browser", "ThumbnailFormat", (int)thumbnailFormat); + Glib::ArrayHandle pext = parseExtensions; + keyFile.set_string_list ("File Browser", "ParseExtensions", pext); + Glib::ArrayHandle pextena = parseExtensionsEnabled; + keyFile.set_integer_list ("File Browser", "ParseExtensionsEnabled", pextena); + keyFile.set_integer ("File Browser", "ThumbnailArrangement", fbArrangement); + keyFile.set_integer ("File Browser", "ThumbnailInterpolation", thumbInterp); + keyFile.set_boolean ("File Browser", "LiveThumbnails", liveThumbnails); + Glib::ArrayHandle pfav = favoriteDirs; + keyFile.set_string_list ("File Browser", "FavoriteDirs", pfav); + Glib::ArrayHandle pren = renameTemplates; + keyFile.set_string_list ("File Browser", "RenameTemplates", pren); + keyFile.set_boolean ("File Browser", "RenameUseTemplates", renameUseTemplates); + Glib::ArrayHandle ptzoom = thumbnailZoomRatios; + keyFile.set_double_list ("File Browser", "ThumbnailZoomRatios", ptzoom); + keyFile.set_boolean ("File Browser", "OverlayedFileNames", overlayedFileNames); + keyFile.set_boolean ("File Browser", "ShowFileNames", showFileNames ); + + keyFile.set_integer ("Clipping Indication", "HighlightThreshold", highlightThreshold); + keyFile.set_integer ("Clipping Indication", "ShadowThreshold", shadowThreshold); + keyFile.set_boolean ("Clipping Indication", "BlinkClipped", blinkClipped); + + keyFile.set_string ("Output", "Format", saveFormat.format); + keyFile.set_integer ("Output", "JpegQuality", saveFormat.jpegQuality); + keyFile.set_integer ("Output", "PngCompression", saveFormat.pngCompression); + keyFile.set_integer ("Output", "PngBps", saveFormat.pngBits); + keyFile.set_integer ("Output", "TiffBps", saveFormat.tiffBits); + keyFile.set_boolean ("Output", "SaveProcParams", saveFormat.saveParams); + keyFile.set_string ("Output", "PathTemplate", savePathTemplate); + keyFile.set_string ("Output", "PathFolder", savePathFolder); + keyFile.set_boolean("Output", "UsePathTemplate", saveUsePathTemplate); + keyFile.set_string ("Output", "LastSaveAsPath", lastSaveAsPath); + + keyFile.set_string ("Profiles", "Directory", profilePath); + keyFile.set_string ("Profiles", "RawDefault", defProfRaw); + keyFile.set_string ("Profiles", "ImgDefault", defProfImg); + keyFile.set_boolean ("Profiles", "SaveParamsWithFile", saveParamsFile); + keyFile.set_boolean ("Profiles", "SaveParamsToCache", saveParamsCache); + keyFile.set_integer ("Profiles", "LoadParamsFromLocation", paramsLoadLocation); + + keyFile.set_integer ("GUI", "WindowWidth", windowWidth); + keyFile.set_integer ("GUI", "WindowHeight", windowHeight); + keyFile.set_integer ("GUI", "DirBrowserWidth", dirBrowserWidth); + keyFile.set_integer ("GUI", "DirBrowserHeight", dirBrowserHeight); + keyFile.set_integer ("GUI", "ToolPanelWidth", toolPanelWidth); + keyFile.set_integer ("GUI", "BrowserToolPanelWidth", browserToolPanelWidth); + keyFile.set_integer ("GUI", "HistoryPanelWidth", historyPanelWidth); + keyFile.set_integer ("GUI", "LastPreviewScale", lastScale); + keyFile.set_integer ("GUI", "LastCropSize", lastCropSize); + keyFile.set_boolean ("GUI", "ShowHistory", showHistory); + keyFile.set_integer ("GUI", "ShowFilePanelState", showFilePanelState); + keyFile.set_boolean ("GUI", "ShowInfo", showInfo); + keyFile.set_boolean ("GUI", "ShowClippedHighlights", showClippedHighlights); + keyFile.set_boolean ("GUI", "ShowClippedShadows", showClippedShadows); + keyFile.set_integer ("GUI", "FrameColor", bgcolor); + keyFile.set_boolean ("GUI", "ProcessingQueueEnbled", procQueueEnabled); + Glib::ArrayHandle tpopen = tpOpen; + keyFile.set_integer_list ("GUI", "ToolPanelsExpanded", tpopen); + Glib::ArrayHandle crvopen = crvOpen; + keyFile.set_integer_list ("GUI", "CurvePanelsExpanded", crvopen); + + keyFile.set_string ("Algorithms", "DemosaicMethod", rtSettings.demosaicMethod); + keyFile.set_integer ("Algorithms", "ColorCorrection", rtSettings.colorCorrectionSteps); + keyFile.set_integer ("Algorithms", "DCBIterations", rtSettings.dcb_iterations); + keyFile.set_boolean ("Algorithms", "DCBEnhance", rtSettings.dcb_enhance); + + keyFile.set_integer ("Crop Settings", "DPI", cropDPI); + + keyFile.set_string ("Color Management", "ICCDirectory", rtSettings.iccDirectory); + keyFile.set_string ("Color Management", "MonitorProfile", rtSettings.monitorProfile); + keyFile.set_integer ("Color Management", "Intent", rtSettings.colorimetricIntent); + + Glib::ArrayHandle bab = baBehav; + keyFile.set_integer_list ("Batch Processing", "AdjusterBehavior", bab); + + + FILE *f = g_fopen (fname.c_str(), "wt"); + if (f==NULL) + return 1; + else { + fprintf (f, "%s", keyFile.to_data().c_str()); + fclose (f); + return 0; + } +} + +Glib::ustring Options::rtdir; +Glib::ustring Options::cacheBaseDir; + +void Options::load () { + + rtdir = Glib::ustring(g_get_user_config_dir ())+"/RawTherapeeAlpha"; + options.readFromFile (argv0+"/options"); + cacheBaseDir = argv0 + "/cache"; + if (options.multiUser) { + int r = options.readFromFile (rtdir + "/options"); + if (r && !g_mkdir_with_parents (rtdir.c_str(), 511)) { + Glib::ustring profdir = rtdir + "/profiles"; + g_mkdir_with_parents (profdir.c_str(), 511); + options.saveToFile (rtdir + "/options"); + } + cacheBaseDir = rtdir + "/cache"; + } + + Glib::ustring fname = argv0+"/languages/"; + fname += (options.language.empty())? DefaultLanguage : options.language; + + if (!langMgr.load (fname, new MultiLangMgr (argv0+"/languages/"+DefaultLanguage))) + langMgr.load (argv0+"/languages/"+DefaultLanguage); + + rtengine::init (&options.rtSettings); +} + +void Options::save () { + + if (options.multiUser==false) { + options.saveToFile (argv0+"/options"); + } + else { + options.saveToFile (rtdir + "/options"); + } +} + +bool Options::is_extention_enabled (Glib::ustring ext) { + for (int j=0; j=parseExtensionsEnabled.size() || parseExtensionsEnabled[j]; + return false; +} diff --git a/rtgui/options.h b/rtgui/options.h new file mode 100644 index 000000000..27c236b85 --- /dev/null +++ b/rtgui/options.h @@ -0,0 +1,142 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _OPTIONS_ +#define _OPTIONS_ + +#include +#include + +#define STARTUPDIR_CURRENT 0 +#define STARTUPDIR_HOME 1 +#define STARTUPDIR_CUSTOM 2 +#define STARTUPDIR_LAST 3 + +class SaveFormat { + + public: + Glib::ustring format; + int pngBits; + int pngCompression; + int jpegQuality; + int tiffBits; + bool tiffUncompressed; + bool saveParams; +}; + +enum ThFileType {FT_Invalid=-1, FT_None=0, FT_Raw=1, FT_Jpeg=2, FT_Tiff=3, FT_Png=4, FT_Custom=5, FT_Tiff16=6, FT_Png16=7, FT_Custom16=8}; +enum PPLoadLocation {PLL_Cache=0, PLL_Input=1}; + +class Options { + + private: + int getString (const char* src, char* dst); + void error (int line); + + public: + bool firstRun; + bool savesParamsAtExit; + SaveFormat saveFormat; + Glib::ustring savePathTemplate; + Glib::ustring savePathFolder; + bool saveUsePathTemplate; + Glib::ustring defProfRaw; + Glib::ustring defProfImg; + Glib::ustring dateFormat; + int startupDir; + Glib::ustring startupPath; + Glib::ustring profilePath; + Glib::ustring lastSaveAsPath; + int toolPanelWidth; + int browserToolPanelWidth; + int historyPanelWidth; + int windowWidth; + int windowHeight; + int dirBrowserWidth; + int dirBrowserHeight; + int lastScale; + int lastCropSize; + bool fbOnlyRaw; + bool fbShowDateTime; + bool fbShowBasicExif; + bool fbShowHidden; + int fbArrangement; + bool multiUser; + static Glib::ustring rtdir; + int version; + int thumbSize; + bool showHistory; + int showFilePanelState; // 0: normal, 1: maximized, 2: normal, 3: hidden + bool showInfo; + int cropDPI; + bool showClippedHighlights; + bool showClippedShadows; + int highlightThreshold; + int shadowThreshold; + bool blinkClipped; + int bgcolor; + Glib::ustring language; + Glib::ustring theme; + static Glib::ustring cacheBaseDir; + bool saveParamsFile; + bool saveParamsCache; + PPLoadLocation paramsLoadLocation; + bool procQueueEnabled; + Glib::ustring gimpDir; + Glib::ustring psDir; + Glib::ustring customEditorProg; + int editorToSendTo; + int maxThumbnailHeight; + int maxCacheEntries; + ThFileType thumbnailFormat; + int thumbInterp; // 0: nearest, 1: bilinear + bool liveThumbnails; + std::vector parseExtensions; + std::vector parseExtensionsEnabled; + std::vector tpOpen; + std::vector crvOpen; + std::vector baBehav; + rtengine::Settings rtSettings; + + std::vector favoriteDirs; + std::vector renameTemplates; + bool renameUseTemplates; + + std::vector thumbnailZoomRatios; + bool overlayedFileNames; + bool showFileNames; + + + Options (); + + Options* copyFrom (Options* other); + void setDefaults (); + int readFromFile (Glib::ustring fname); + int saveToFile (Glib::ustring fname); + static void load (); + static void save (); + + bool is_extention_enabled(Glib::ustring ext); +}; + +extern Options options; +extern Glib::ustring argv0; +extern Glib::ustring argv1; +extern Glib::ustring versionString; + +#endif diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc new file mode 100644 index 000000000..d8175bd01 --- /dev/null +++ b/rtgui/paramsedited.cc @@ -0,0 +1,320 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include + +ParamsEdited::ParamsEdited () { + + set (false); +} + +void ParamsEdited::set (bool v) { + + toneCurve.curve = v; + toneCurve.brightness = v; + toneCurve.black = v; + toneCurve.contrast = v; + toneCurve.shcompr = v; + toneCurve.hlcompr = v; + toneCurve.autoexp = v; + toneCurve.clip = v; + toneCurve.expcomp = v; + lumaCurve.curve = v; + lumaCurve.brightness = v; + lumaCurve.contrast = v; + sharpening.enabled = v; + sharpening.radius = v; + sharpening.amount = v; + sharpening.threshold = v; + sharpening.edgesonly = v; + sharpening.edges_radius = v; + sharpening.edges_tolerance = v; + sharpening.halocontrol = v; + sharpening.halocontrol_amount= v; + sharpening.method = v; + sharpening.deconvamount = v; + sharpening.deconvradius = v; + sharpening.deconviter = v; + sharpening.deconvdamping = v; + colorBoost.amount = v; + colorBoost.avoidclip = v; + colorBoost.enable_saturationlimiter = v; + colorBoost.saturationlimit = v; + wb.method = v; + wb.green = v; + wb.temperature = v; + colorShift.a = v; + colorShift.b = v; + lumaDenoise.enabled = v; + lumaDenoise.radius = v; + lumaDenoise.edgetolerance = v; + colorDenoise.enabled = v; + colorDenoise.amount = v; + sh.enabled = v; + sh.hq = v; + sh.highlights = v; + sh.htonalwidth = v; + sh.shadows = v; + sh.stonalwidth = v; + sh.localcontrast = v; + sh.radius = v; + crop.enabled = v; + crop.x = v; + crop.y = v; + crop.w = v; + crop.h = v; + crop.fixratio = v; + crop.ratio = v; + crop.orientation = v; + crop.guide = v; + coarse.rotate = v; + coarse.hflip = v; + coarse.vflip = v; + rotate.degree = v; + rotate.fill = v; + distortion.amount = v; + cacorrection.red = v; + cacorrection.blue = v; + vignetting.amount = v; + vignetting.radius = v; + chmixer.red[0] = v; + chmixer.red[1] = v; + chmixer.red[2] = v; + chmixer.green[0] = v; + chmixer.green[1] = v; + chmixer.green[2] = v; + chmixer.blue[0] = v; + chmixer.blue[1] = v; + chmixer.blue[2] = v; + hlrecovery.enabled = v; + hlrecovery.method = v; + resize.scale = v; + resize.method = v; + resize.dataspec = v; + resize.width = v; + resize.height = v; + resize.enabled = v; + icm.input = v; + icm.gammaOnInput = v; + icm.working = v; + icm.output = v; + exif.clear (); + iptc.clear (); +} + +using namespace rtengine; +using namespace rtengine::procparams; + +void ParamsEdited::initFrom (const std::vector& src) { + + set (true); + if (src.size()==0) + return; + + const ProcParams& p = src[0]; + for (int i=1; i + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _PARAMEDITED_H_ +#define _PARAMEDITED_H_ + +#include +#include +#include +#include + +class ToneCurveParamsEdited { + + public: + bool curve; + bool brightness; + bool black; + bool contrast; + bool shcompr; + bool hlcompr; + bool autoexp; + bool clip; + bool expcomp; +}; + +class LCurveParamsEdited { + + public: + bool brightness; + bool contrast; + bool curve; +}; + +class SharpeningParamsEdited { + + public: + bool enabled; + bool radius; + bool amount; + bool threshold; + bool edgesonly; + bool edges_radius; + bool edges_tolerance; + bool halocontrol; + bool halocontrol_amount; + + bool method; + bool deconvamount; + bool deconvradius; + bool deconviter; + bool deconvdamping; +}; + +class ColorBoostParamsEdited { + + public: + bool amount; + bool avoidclip; + bool enable_saturationlimiter; + bool saturationlimit; +}; + +class WBParamsEdited { + + public: + bool method; + bool temperature; + bool green; +}; + +class ColorShiftParamsEdited { + + public: + bool a; + bool b; +}; + +class LumaDenoiseParamsEdited { + + public: + bool enabled; + bool radius; + bool edgetolerance; +}; + +class ColorDenoiseParamsEdited { + + public: + bool enabled; + bool amount; +}; + +class SHParamsEdited { + + public: + bool enabled; + bool hq; + bool highlights; + bool htonalwidth; + bool shadows; + bool stonalwidth; + bool localcontrast; + bool radius; +}; + +class CropParamsEdited { + + public: + bool enabled; + bool x; + bool y; + bool w; + bool h; + bool fixratio; + bool ratio; + bool orientation; + bool guide; +}; + +class CoarseTransformParamsEdited { + + public: + bool rotate; + bool hflip; + bool vflip; +}; + +class RotateParamsEdited { + + public: + bool degree; + bool fill; +}; + +class DistortionParamsEdited { + + public: + bool amount; +}; + +class VignettingParamsEdited { + + public: + bool amount; + bool radius; +}; + +class ChannelMixerParamsEdited { + + public: + bool red[3]; + bool green[3]; + bool blue[3]; +}; + +class CACorrParamsEdited { + + public: + bool red; + bool blue; +}; + +class HRecParamsEdited { + + public: + bool enabled; + bool method; +}; + +class ResizeParamsEdited { + + public: + bool scale; + bool method; + bool dataspec; + bool width; + bool height; + bool enabled; +}; + +class ColorManagementParamsEdited { + + public: + bool input; + bool gammaOnInput; + bool working; + bool output; +}; + +class ExifPairEdited { + + public: + Glib::ustring field; + bool value; +}; + +class IPTCPairEdited { + + public: + Glib::ustring field; + bool values; +}; + +class ParamsEdited { + + public: + ToneCurveParamsEdited toneCurve; + LCurveParamsEdited lumaCurve; + SharpeningParamsEdited sharpening; + ColorBoostParamsEdited colorBoost; + WBParamsEdited wb; + ColorShiftParamsEdited colorShift; + LumaDenoiseParamsEdited lumaDenoise; + ColorDenoiseParamsEdited colorDenoise; + SHParamsEdited sh; + CropParamsEdited crop; + CoarseTransformParamsEdited coarse; + RotateParamsEdited rotate; + DistortionParamsEdited distortion; + CACorrParamsEdited cacorrection; + VignettingParamsEdited vignetting; + ChannelMixerParamsEdited chmixer; + HRecParamsEdited hlrecovery; + ResizeParamsEdited resize; + ColorManagementParamsEdited icm; + std::vector exif; + std::vector iptc; + + ParamsEdited (); + + void set (bool v); + void initFrom (const std::vector& src); + void combine (rtengine::procparams::ProcParams& toEdit, const rtengine::procparams::ProcParams& mods); + + bool operator== (const ParamsEdited& other); + bool operator!= (const ParamsEdited& other); +}; +#endif diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc new file mode 100644 index 000000000..21641b614 --- /dev/null +++ b/rtgui/partialpastedlg.cc @@ -0,0 +1,315 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +PartialPasteDlg::PartialPasteDlg () { + + set_modal (true); + set_title (M("PARTIALPASTE_DIALOGLABEL")); + + basic = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_BASICGROUP"))); + luminance = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_LUMINANCEGROUP"))); + color = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_COLORGROUP"))); + lens = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_LENSGROUP"))); + composition = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_COMPOSITIONGROUP"))); + metaicm = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_METAICMGROUP"))); + + // options in basic: + wb = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_WHITEBALANCE"))); + exposure = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_EXPOSURE"))); + hlrec = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_HLRECOVERY"))); + + // options in luminance: + sharpen = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_SHARPENING"))); + lumaden = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_LUMADENOISE"))); + lumacurve = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_LUMACURVE"))); + sh = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_SHADOWSHIGHLIGHTS"))); + + // options in color: + colormixer = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_COLORMIXER"))); + colorshift = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_COLORSHIFT"))); + colorboost = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_COLORBOOST"))); + colorden = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_COLORDENOISE"))); + + // options in lens: + distortion = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DISTORTION"))); + cacorr = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_CACORRECTION"))); + vignetting = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_VIGNETTING"))); + + // options in composition: + coarserot = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_COARSETRANS"))); + finerot = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_ROTATION"))); + crop = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_CROP"))); + resize = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RESIZE"))); + + // options in metaicm: + exifch = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_EXIFCHANGES"))); + iptc = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_IPTCINFO"))); + icm = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_ICMSETTINGS"))); + + Gtk::VBox* vboxes[6]; + Gtk::HSeparator* hseps[6]; + for (int i=0; i<6; i++) { + vboxes[i] = Gtk::manage (new Gtk::VBox ()); + vboxes[i]->set_border_width (16); + hseps[i] = Gtk::manage (new Gtk::HSeparator ()); + } + + vboxes[0]->pack_start (*basic, Gtk::PACK_SHRINK, 2); + vboxes[0]->pack_start (*hseps[0], Gtk::PACK_SHRINK, 2); + vboxes[0]->pack_start (*wb, Gtk::PACK_SHRINK, 2); + vboxes[0]->pack_start (*exposure, Gtk::PACK_SHRINK, 2); + vboxes[0]->pack_start (*hlrec, Gtk::PACK_SHRINK, 2); + + vboxes[1]->pack_start (*luminance, Gtk::PACK_SHRINK, 2); + vboxes[1]->pack_start (*hseps[1], Gtk::PACK_SHRINK, 2); + vboxes[1]->pack_start (*sharpen, Gtk::PACK_SHRINK, 2); + vboxes[1]->pack_start (*lumaden, Gtk::PACK_SHRINK, 2); + vboxes[1]->pack_start (*lumacurve, Gtk::PACK_SHRINK, 2); + vboxes[1]->pack_start (*sh, Gtk::PACK_SHRINK, 2); + + vboxes[2]->pack_start (*color, Gtk::PACK_SHRINK, 2); + vboxes[2]->pack_start (*hseps[2], Gtk::PACK_SHRINK, 2); + vboxes[2]->pack_start (*colormixer, Gtk::PACK_SHRINK, 2); + vboxes[2]->pack_start (*colorshift, Gtk::PACK_SHRINK, 2); + vboxes[2]->pack_start (*colorboost, Gtk::PACK_SHRINK, 2); + vboxes[2]->pack_start (*colorden, Gtk::PACK_SHRINK, 2); + + + vboxes[3]->pack_start (*lens, Gtk::PACK_SHRINK, 2); + vboxes[3]->pack_start (*hseps[3], Gtk::PACK_SHRINK, 2); + vboxes[3]->pack_start (*distortion, Gtk::PACK_SHRINK, 2); + vboxes[3]->pack_start (*cacorr, Gtk::PACK_SHRINK, 2); + vboxes[3]->pack_start (*vignetting, Gtk::PACK_SHRINK, 2); + + vboxes[4]->pack_start (*composition, Gtk::PACK_SHRINK, 2); + vboxes[4]->pack_start (*hseps[4], Gtk::PACK_SHRINK, 2); + vboxes[4]->pack_start (*coarserot, Gtk::PACK_SHRINK, 2); + vboxes[4]->pack_start (*finerot, Gtk::PACK_SHRINK, 2); + vboxes[4]->pack_start (*crop, Gtk::PACK_SHRINK, 2); + vboxes[4]->pack_start (*resize, Gtk::PACK_SHRINK, 2); + + vboxes[5]->pack_start (*metaicm, Gtk::PACK_SHRINK, 2); + vboxes[5]->pack_start (*hseps[5], Gtk::PACK_SHRINK, 2); + vboxes[5]->pack_start (*exifch, Gtk::PACK_SHRINK, 2); + vboxes[5]->pack_start (*iptc, Gtk::PACK_SHRINK, 2); + vboxes[5]->pack_start (*icm, Gtk::PACK_SHRINK, 2); + + Gtk::VBox* vbleft = Gtk::manage (new Gtk::VBox ()); + Gtk::VBox* vbright = Gtk::manage (new Gtk::VBox ()); + + vbleft->set_border_width (16); + vbright->set_border_width (16); + + for (int i=0; i<3; i++) + vbleft->pack_start (*vboxes[i]); + for (int i=3; i<6; i++) + vbright->pack_start (*vboxes[i]); + + Gtk::HBox* hbmain = Gtk::manage (new Gtk::HBox ()); + hbmain->pack_start (*vbleft); + hbmain->pack_start (*(Gtk::manage (new Gtk::VSeparator ()))); + hbmain->pack_start (*vbright); + + get_vbox()->pack_start (*hbmain); + + basicConn = basic->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::basicToggled)); + luminanceConn = luminance->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::luminanceToggled)); + colorConn = color->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::colorToggled)); + lensConn = lens->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::lensToggled)); + compositionConn = composition->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::compositionToggled)); + metaicmConn = metaicm->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::metaicmToggled)); + + wbConn = wb->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); + exposureConn = exposure->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); + hlrecConn = hlrec->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); + + sharpenConn = sharpen->signal_toggled().connect (sigc::bind (sigc::mem_fun(*luminance, &Gtk::CheckButton::set_inconsistent), true)); + lumadenConn = lumaden->signal_toggled().connect (sigc::bind (sigc::mem_fun(*luminance, &Gtk::CheckButton::set_inconsistent), true)); + lumacurveConn = lumacurve->signal_toggled().connect (sigc::bind (sigc::mem_fun(*luminance, &Gtk::CheckButton::set_inconsistent), true)); + shConn = sh->signal_toggled().connect (sigc::bind (sigc::mem_fun(*luminance, &Gtk::CheckButton::set_inconsistent), true)); + + colormixerConn = colormixer->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); + colorshiftConn = colorshift->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); + colorboostConn = colorboost->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); + colordenConn = colorden->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); + + distortionConn = distortion->signal_toggled().connect (sigc::bind (sigc::mem_fun(*lens, &Gtk::CheckButton::set_inconsistent), true)); + cacorrConn = cacorr->signal_toggled().connect (sigc::bind (sigc::mem_fun(*lens, &Gtk::CheckButton::set_inconsistent), true)); + vignettingConn = vignetting->signal_toggled().connect (sigc::bind (sigc::mem_fun(*lens, &Gtk::CheckButton::set_inconsistent), true)); + + coarserotConn = coarserot->signal_toggled().connect (sigc::bind (sigc::mem_fun(*composition, &Gtk::CheckButton::set_inconsistent), true)); + finerotConn = finerot->signal_toggled().connect (sigc::bind (sigc::mem_fun(*composition, &Gtk::CheckButton::set_inconsistent), true)); + cropConn = crop->signal_toggled().connect (sigc::bind (sigc::mem_fun(*composition, &Gtk::CheckButton::set_inconsistent), true)); + resizeConn = resize->signal_toggled().connect (sigc::bind (sigc::mem_fun(*composition, &Gtk::CheckButton::set_inconsistent), true)); + + exifchConn = exifch->signal_toggled().connect (sigc::bind (sigc::mem_fun(*metaicm, &Gtk::CheckButton::set_inconsistent), true)); + iptcConn = iptc->signal_toggled().connect (sigc::bind (sigc::mem_fun(*metaicm, &Gtk::CheckButton::set_inconsistent), true)); + icmConn = icm->signal_toggled().connect (sigc::bind (sigc::mem_fun(*metaicm, &Gtk::CheckButton::set_inconsistent), true)); + + add_button (Gtk::StockID("gtk-ok"), 1); + add_button (Gtk::StockID("gtk-cancel"), 0); + set_response_sensitive (1); + set_default_response (1); + show_all_children (); +} + +void PartialPasteDlg::basicToggled () { + + wbConn.block (true); + exposureConn.block (true); + hlrecConn.block (true); + + basic->set_inconsistent (false); + + wb->set_active (basic->get_active ()); + exposure->set_active (basic->get_active ()); + hlrec->set_active (basic->get_active ()); + + wbConn.block (false); + exposureConn.block (false); + hlrecConn.block (false); +} + +void PartialPasteDlg::luminanceToggled () { + + sharpenConn.block (true); + lumadenConn.block (true); + lumacurveConn.block (true); + shConn.block (true); + + luminance->set_inconsistent (false); + + sharpen->set_active (luminance->get_active ()); + lumaden->set_active (luminance->get_active ()); + lumacurve->set_active (luminance->get_active ()); + sh->set_active (luminance->get_active ()); + + sharpenConn.block (false); + lumadenConn.block (false); + lumacurveConn.block (false); + shConn.block (false); +} + +void PartialPasteDlg::colorToggled () { + + colormixerConn.block (true); + colorshiftConn.block (true); + colorboostConn.block (true); + colordenConn.block (true); + + color->set_inconsistent (false); + + colormixer->set_active (color->get_active ()); + colorshift->set_active (color->get_active ()); + colorboost->set_active (color->get_active ()); + colorden->set_active (color->get_active ()); + + colormixerConn.block (false); + colorshiftConn.block (false); + colorboostConn.block (false); + colordenConn.block (false); +} + +void PartialPasteDlg::lensToggled () { + + distortionConn.block (true); + cacorrConn.block (true); + vignettingConn.block (true); + + lens->set_inconsistent (false); + + distortion->set_active (lens->get_active ()); + cacorr->set_active (lens->get_active ()); + vignetting->set_active (lens->get_active ()); + + distortionConn.block (false); + cacorrConn.block (false); + vignettingConn.block (false); +} + +void PartialPasteDlg::compositionToggled () { + + coarserotConn.block (true); + finerotConn.block (true); + cropConn.block (true); + resizeConn.block (true); + + composition->set_inconsistent (false); + + coarserot->set_active (composition->get_active ()); + finerot->set_active (composition->get_active ()); + crop->set_active (composition->get_active ()); + resize->set_active (composition->get_active ()); + + coarserotConn.block (false); + finerotConn.block (false); + cropConn.block (false); + resizeConn.block (false); +} + +void PartialPasteDlg::metaicmToggled () { + + exifchConn.block (true); + iptcConn.block (true); + icmConn.block (true); + + metaicm->set_inconsistent (false); + + exifch->set_active (metaicm->get_active ()); + iptc->set_active (metaicm->get_active ()); + icm->set_active (metaicm->get_active ()); + + exifchConn.block (false); + iptcConn.block (false); + icmConn.block (false); +} + + +void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dst, const rtengine::procparams::ProcParams* src) { + + if (wb->get_active ()) dst->wb = src->wb; + if (exposure->get_active ()) dst->toneCurve = src->toneCurve; + if (hlrec->get_active ()) dst->hlrecovery = src->hlrecovery; + + if (sharpen->get_active ()) dst->sharpening = src->sharpening; + if (lumaden->get_active ()) dst->lumaDenoise = src->lumaDenoise; + if (lumacurve->get_active ()) dst->lumaCurve = src->lumaCurve; + if (sh->get_active ()) dst->sh = src->sh; + + if (colormixer->get_active ()) dst->chmixer = src->chmixer; + if (colorshift->get_active ()) dst->colorShift = src->colorShift; + if (colorboost->get_active ()) dst->colorBoost = src->colorBoost; + if (colorden->get_active ()) dst->colorDenoise = src->colorDenoise; + + if (distortion->get_active ()) dst->distortion = src->distortion; + if (cacorr->get_active ()) dst->cacorrection = src->cacorrection; + if (vignetting->get_active ()) dst->vignetting = src->vignetting; + + if (coarserot->get_active ()) dst->coarse = src->coarse; + if (finerot->get_active ()) dst->rotate = src->rotate; + if (crop->get_active ()) dst->crop = src->crop; + if (resize->get_active ()) dst->resize = src->resize; + + if (exifch->get_active ()) dst->exif = src->exif; + if (iptc->get_active ()) dst->iptc = src->iptc; + if (icm->get_active ()) dst->icm = src->icm; +} + diff --git a/rtgui/partialpastedlg.h b/rtgui/partialpastedlg.h new file mode 100644 index 000000000..6a42a5033 --- /dev/null +++ b/rtgui/partialpastedlg.h @@ -0,0 +1,92 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _PARTIALPASTEDLG_ +#define _PARTIALPASTEDLG_ + +#include +#include + +class PartialPasteDlg : public Gtk::Dialog { + + public: + // main groups: + Gtk::CheckButton* basic; + Gtk::CheckButton* luminance; + Gtk::CheckButton* color; + Gtk::CheckButton* lens; + Gtk::CheckButton* composition; + Gtk::CheckButton* metaicm; + + // options in basic: + Gtk::CheckButton* wb; + Gtk::CheckButton* exposure; + Gtk::CheckButton* hlrec; + + // options in luminance: + Gtk::CheckButton* sharpen; + Gtk::CheckButton* lumaden; + Gtk::CheckButton* lumacurve; + Gtk::CheckButton* sh; + + // options in color: + Gtk::CheckButton* colormixer; + Gtk::CheckButton* colorshift; + Gtk::CheckButton* colorboost; + Gtk::CheckButton* colorden; + + // options in lens: + Gtk::CheckButton* distortion; + Gtk::CheckButton* cacorr; + Gtk::CheckButton* vignetting; + + // options in composition: + Gtk::CheckButton* coarserot; + Gtk::CheckButton* finerot; + Gtk::CheckButton* crop; + Gtk::CheckButton* resize; + + // options in metaicm: + Gtk::CheckButton* exifch; + Gtk::CheckButton* iptc; + Gtk::CheckButton* icm; + + sigc::connection basicConn, luminanceConn, colorConn, lensConn, compositionConn, metaicmConn; + sigc::connection wbConn, exposureConn, hlrecConn; + sigc::connection sharpenConn, lumadenConn, lumacurveConn, shConn; + sigc::connection colormixerConn, colorshiftConn, colorboostConn, colordenConn; + sigc::connection distortionConn, cacorrConn, vignettingConn; + sigc::connection coarserotConn, finerotConn, cropConn, resizeConn; + sigc::connection exifchConn, iptcConn, icmConn; + + + public: + PartialPasteDlg (); + + void applyPaste (rtengine::procparams::ProcParams* dst, const rtengine::procparams::ProcParams* src); + + void basicToggled (); + void luminanceToggled (); + void colorToggled (); + void lensToggled (); + void compositionToggled (); + void metaicmToggled (); +}; + +#endif + diff --git a/rtgui/placesbrowser.cc b/rtgui/placesbrowser.cc new file mode 100644 index 000000000..11a9e68f7 --- /dev/null +++ b/rtgui/placesbrowser.cc @@ -0,0 +1,300 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include > +#include + +PlacesBrowser::PlacesBrowser () : listener (NULL) { + + scrollw = Gtk::manage (new Gtk::ScrolledWindow ()); + scrollw->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); + pack_start (*scrollw); + + add = Gtk::manage (new Gtk::Button (M("MAIN_FRAME_PLACES_ADD"))); + del = Gtk::manage (new Gtk::Button (M("MAIN_FRAME_PLACES_DEL"))); + add->set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::ADD, Gtk::ICON_SIZE_MENU))); + del->set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::REMOVE, Gtk::ICON_SIZE_MENU))); + Gtk::HBox* buttonBox = Gtk::manage (new Gtk::HBox ()); + buttonBox->pack_start (*add); + buttonBox->pack_start (*del); + + pack_start (*buttonBox, Gtk::PACK_SHRINK, 2); + + treeView = Gtk::manage (new Gtk::TreeView ()); + treeView->unset_flags (Gtk::CAN_FOCUS); + scrollw->add (*treeView); + + placesModel = Gtk::ListStore::create (placesColumns); + treeView->set_model (placesModel); + treeView->set_headers_visible (true); + + Gtk::TreeView::Column *iviewcol = Gtk::manage (new Gtk::TreeView::Column (M("MAIN_FRAME_PLACES"))); + Gtk::CellRendererPixbuf *iconCR = Gtk::manage (new Gtk::CellRendererPixbuf()); + Gtk::CellRendererText *labelCR = Gtk::manage (new Gtk::CellRendererText()); + iviewcol->pack_start (*iconCR, false); + iviewcol->pack_start (*labelCR, true); + iviewcol->add_attribute (*iconCR, "gicon", 0); + iviewcol->add_attribute (*labelCR, "text", placesColumns.label); + treeView->append_column (*iviewcol); + + treeView->set_row_separator_func (sigc::mem_fun(*this, &PlacesBrowser::rowSeparatorFunc)); + + vm = Gio::VolumeMonitor::get(); + + vm->signal_mount_changed().connect (sigc::mem_fun(*this, &PlacesBrowser::mountChanged)); + vm->signal_mount_added().connect (sigc::mem_fun(*this, &PlacesBrowser::mountChanged)); + vm->signal_mount_removed().connect (sigc::mem_fun(*this, &PlacesBrowser::mountChanged)); + vm->signal_volume_changed().connect (sigc::mem_fun(*this, &PlacesBrowser::volumeChanged)); + vm->signal_volume_added().connect (sigc::mem_fun(*this, &PlacesBrowser::volumeChanged)); + vm->signal_volume_removed().connect (sigc::mem_fun(*this, &PlacesBrowser::volumeChanged)); + vm->signal_drive_connected().connect (sigc::mem_fun(*this, &PlacesBrowser::driveChanged)); + vm->signal_drive_disconnected().connect (sigc::mem_fun(*this, &PlacesBrowser::driveChanged)); + vm->signal_drive_changed().connect (sigc::mem_fun(*this, &PlacesBrowser::driveChanged)); + + treeView->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &PlacesBrowser::selectionChanged)); + add->signal_clicked().connect(sigc::mem_fun(*this, &PlacesBrowser::addPressed)); + del->signal_clicked().connect(sigc::mem_fun(*this, &PlacesBrowser::delPressed)); + + show_all (); +} + +void PlacesBrowser::refreshPlacesList () { + + placesModel->clear (); + + // append home directory + Glib::RefPtr hfile = Gio::File::create_for_path (Glib::get_home_dir ()); + if (hfile) { + try { + Glib::RefPtr info = safe_query_file_info (hfile); + if (info) { + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.label] = info->get_display_name (); + newrow[placesColumns.icon] = info->get_icon (); + newrow[placesColumns.root] = hfile->get_parse_name (); + newrow[placesColumns.type] = 4; + newrow[placesColumns.rowSeparator] = false; + } + } catch (Gio::Error&) { /* This will be thrown if the path doesn't exist */ } + } + + // append pictures directory + hfile = Gio::File::create_for_path (Glib::get_user_special_dir (G_USER_DIRECTORY_PICTURES)); + if (hfile) { + try { + Glib::RefPtr info = safe_query_file_info (hfile); + if (info) { + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.label] = info->get_display_name (); + newrow[placesColumns.icon] = info->get_icon (); + newrow[placesColumns.root] = hfile->get_parse_name (); + newrow[placesColumns.type] = 4; + newrow[placesColumns.rowSeparator] = false; + } + } catch (Gio::Error&) { /* This will be thrown if the path doesn't exist */ } + } + + if (placesModel->children().size()>0) { + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.rowSeparator] = true; + } + + // scan all drives + std::vector > drives = vm->get_connected_drives (); + for (int j=0; j > volumes = drives[j]->get_volumes (); + if (volumes.size()==0) { + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.label] = drives[j]->get_name (); + newrow[placesColumns.icon] = drives[j]->get_icon (); + newrow[placesColumns.root] = ""; + newrow[placesColumns.type] = 3; + newrow[placesColumns.rowSeparator] = false; + } + for (int i=0; i mount = volumes[i]->get_mount (); + if (mount) { // placesed volumes + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.label] = mount->get_name (); + newrow[placesColumns.icon] = mount->get_icon (); + newrow[placesColumns.root] = mount->get_root ()->get_parse_name (); + newrow[placesColumns.type] = 1; + newrow[placesColumns.rowSeparator] = false; + } + else { // unplacesed volumes + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.label] = volumes[i]->get_name (); + newrow[placesColumns.icon] = volumes[i]->get_icon (); + newrow[placesColumns.root] = ""; + newrow[placesColumns.type] = 2; + newrow[placesColumns.rowSeparator] = false; + } + } + } + + // volumes not belonging to drives + std::vector > volumes = vm->get_volumes (); + for (int i=0; iget_drive ()) { + Glib::RefPtr mount = volumes[i]->get_mount (); + if (mount) { // placesed volumes + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.label] = mount->get_name (); + newrow[placesColumns.icon] = mount->get_icon (); + newrow[placesColumns.root] = mount->get_root ()->get_parse_name (); + newrow[placesColumns.type] = 1; + newrow[placesColumns.rowSeparator] = false; + } + else { // unplacesed volumes + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.label] = volumes[i]->get_name (); + newrow[placesColumns.icon] = volumes[i]->get_icon (); + newrow[placesColumns.root] = ""; + newrow[placesColumns.type] = 2; + newrow[placesColumns.rowSeparator] = false; + } + } + } + // placess not belonging to volumes + std::vector > mounts = vm->get_mounts (); + for (int i=0; iget_volume ()) { + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.label] = mounts[i]->get_name (); + newrow[placesColumns.icon] = mounts[i]->get_icon (); + newrow[placesColumns.root] = mounts[i]->get_root ()->get_parse_name (); + newrow[placesColumns.type] = 1; + newrow[placesColumns.rowSeparator] = false; + } + } + // append favorites + if (placesModel->children().size()>0) { + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.rowSeparator] = true; + } + for (int i=0; i hfile = Gio::File::create_for_path (options.favoriteDirs[i]); + if (hfile) { + Glib::RefPtr info = safe_query_file_info (hfile); + if (info) { + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.label] = info->get_display_name (); + newrow[placesColumns.icon] = info->get_icon (); + newrow[placesColumns.root] = hfile->get_parse_name (); + newrow[placesColumns.type] = 5; + newrow[placesColumns.rowSeparator] = false; + } + } + } +} + +bool PlacesBrowser::rowSeparatorFunc (const Glib::RefPtr& model, const Gtk::TreeModel::iterator& iter) { + + return iter->get_value (placesColumns.rowSeparator); +} + +void PlacesBrowser::mountChanged (const Glib::RefPtr& m) { + + gdk_threads_enter (); + refreshPlacesList (); + gdk_threads_leave (); +} + +void PlacesBrowser::volumeChanged (const Glib::RefPtr& m) { + + gdk_threads_enter (); + refreshPlacesList (); + gdk_threads_leave (); +} + +void PlacesBrowser::driveChanged (const Glib::RefPtr& m) { + + gdk_threads_enter (); + refreshPlacesList (); + gdk_threads_leave (); +} + +void PlacesBrowser::selectionChanged () { + + Glib::RefPtr selection = treeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + if (iter) { + if (iter->get_value (placesColumns.type)==2) { + std::vector > volumes = vm->get_volumes (); + for (int i=0; iget_name () == iter->get_value (placesColumns.label)) { + volumes[i]->mount (); + break; + } + } + else if (iter->get_value (placesColumns.type)==3) { + std::vector > drives = vm->get_connected_drives (); + for (int i=0; iget_name () == iter->get_value (placesColumns.label)) { + drives[i]->poll_for_media (); + break; + } + } + else if (listener) + listener->selectDir (iter->get_value (placesColumns.root)); + } +} + +void PlacesBrowser::dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile) { + + lastSelectedDir = dirname; +} + +void PlacesBrowser::addPressed () { + + if (lastSelectedDir=="") + return; + + // check if the dirname is already in the list. If yes, return. + for (int i=0; i hfile = Gio::File::create_for_path (lastSelectedDir); + if (hfile) { + Glib::RefPtr info = safe_query_file_info (hfile); + if (info) { + options.favoriteDirs.push_back (hfile->get_parse_name ()); + refreshPlacesList (); + } + } +} + +void PlacesBrowser::delPressed () { + + // lookup the selected item in the bookmark + Glib::RefPtr selection = treeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + + if (iter && iter->get_value (placesColumns.type)==5) { + std::vector::iterator i = std::find (options.favoriteDirs.begin(), options.favoriteDirs.end(), iter->get_value (placesColumns.root)); + if (i != options.favoriteDirs.end()) + options.favoriteDirs.erase (i); + } + + refreshPlacesList (); +} + diff --git a/rtgui/placesbrowser.h b/rtgui/placesbrowser.h new file mode 100644 index 000000000..eac18f162 --- /dev/null +++ b/rtgui/placesbrowser.h @@ -0,0 +1,68 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _PLACESBROWSER_ +#define _PLACESBROWSER_ + +#include +#include +#include +#include +#include + +class PlacesBrowser : public Gtk::VBox, public DirSelectionListener { + + class PlacesColumns : public Gtk::TreeModel::ColumnRecord { + public: + Gtk::TreeModelColumn > icon; + Gtk::TreeModelColumn label; + Gtk::TreeModelColumn root; + Gtk::TreeModelColumn type; + Gtk::TreeModelColumn rowSeparator; + PlacesColumns() { add(icon); add(label); add(root); add(type); add(rowSeparator); } + }; + PlacesColumns placesColumns; + Gtk::ScrolledWindow* scrollw; + Gtk::TreeView* treeView; + Glib::RefPtr placesModel; + Glib::RefPtr vm; + DirBrowserRemoteInterface* listener; + Glib::ustring lastSelectedDir; + Gtk::Button* add; + Gtk::Button* del; + + public: + + PlacesBrowser (); + + void setDirBrowserRemoteInterface (DirBrowserRemoteInterface* l) { listener = l; } + void dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile=""); + + void refreshPlacesList (); + void mountChanged (const Glib::RefPtr& m); + void volumeChanged (const Glib::RefPtr& v); + void driveChanged (const Glib::RefPtr& d); + bool rowSeparatorFunc (const Glib::RefPtr& model, const Gtk::TreeModel::iterator& iter); + void selectionChanged (); + void addPressed (); + void delPressed (); +}; + +#endif + + diff --git a/rtgui/pointermotionlistener.h b/rtgui/pointermotionlistener.h new file mode 100644 index 000000000..0d9230c31 --- /dev/null +++ b/rtgui/pointermotionlistener.h @@ -0,0 +1,28 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _POINTERMOTIONLISTENER_ +#define _POINTERMOTIONLISTENER_ + +class PointerMotionListener { + + public: + virtual void pointerMoved (bool validPos, int x, int y, int r, int g, int b) {} +}; + +#endif diff --git a/rtgui/pparamschangelistener.h b/rtgui/pparamschangelistener.h new file mode 100644 index 000000000..5a34890f2 --- /dev/null +++ b/rtgui/pparamschangelistener.h @@ -0,0 +1,34 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _PPARAMSCHANGELISTENER_ +#define _PPARAMSCHANGELISTENER_ + +#include +#include +#include + +class PParamsChangeListener { + + public: + virtual void procParamsChanged (rtengine::procparams::ProcParams* params, rtengine::ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited=NULL) {} + virtual void clearParamChanges () {} +}; + +#endif + diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc new file mode 100644 index 000000000..77f20e594 --- /dev/null +++ b/rtgui/preferences.cc @@ -0,0 +1,991 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include "preferences.h" +#include +#include +#include +#include + +extern Options options; +extern Glib::ustring argv0; + +Preferences::Preferences (int initialPage) { + + set_title (M("MAIN_BUTTON_PREFERENCES")); + + moptions.copyFrom (&options); + + set_size_request (650, 550); + set_border_width (4); + + Gtk::VBox* mainvb = get_vbox (); + set_has_separator (false); + + Gtk::Notebook* nb = Gtk::manage (new Gtk::Notebook ()); + mainvb->pack_start (*nb); + + Gtk::HSeparator* hsep1 = Gtk::manage (new Gtk::HSeparator ()); + mainvb->pack_start (*hsep1, Gtk::PACK_SHRINK, 2); + + Gtk::HBox* buttonpanel = Gtk::manage (new Gtk::HBox ()); + mainvb->pack_end (*buttonpanel, Gtk::PACK_SHRINK, 2); + + Gtk::Button* load = Gtk::manage (new Gtk::Button (M("GENERAL_LOAD"))); + Gtk::Button* save = Gtk::manage (new Gtk::Button (M("GENERAL_SAVE"))); + Gtk::Button* about = Gtk::manage (new Gtk::Button (M("GENERAL_ABOUT"))); + Gtk::Button* ok = Gtk::manage (new Gtk::Button (M("GENERAL_OK"))); + Gtk::Button* cancel = Gtk::manage (new Gtk::Button (M("GENERAL_CANCEL"))); + + save->set_image (*Gtk::manage(new Gtk::Image (Gtk::StockID("gtk-save"), Gtk::ICON_SIZE_BUTTON))); + load->set_image (*Gtk::manage(new Gtk::Image (Gtk::StockID("gtk-open"), Gtk::ICON_SIZE_BUTTON))); + about->set_image (*Gtk::manage(new Gtk::Image (argv0+"/images/logoicon16.png"))); + ok->set_image (*Gtk::manage(new Gtk::Image (Gtk::StockID("gtk-ok"), Gtk::ICON_SIZE_BUTTON))); + cancel->set_image (*Gtk::manage(new Gtk::Image (Gtk::StockID("gtk-cancel"), Gtk::ICON_SIZE_BUTTON))); + + + load->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::loadPressed) ); + save->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::savePressed) ); + about->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::aboutPressed) ); + ok->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::okPressed) ); + cancel->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::cancelPressed) ); + + buttonpanel->pack_start (*load, Gtk::PACK_SHRINK, 4); + buttonpanel->pack_start (*save, Gtk::PACK_SHRINK, 4); + buttonpanel->pack_start (*about, Gtk::PACK_SHRINK, 4); + buttonpanel->pack_end (*ok, Gtk::PACK_SHRINK, 4); + buttonpanel->pack_end (*cancel, Gtk::PACK_SHRINK, 4); + + nb->append_page (*getGeneralPanel(), M("PREFERENCES_TAB_GENERAL")); + nb->append_page (*getProcParamsPanel(), M("PREFERENCES_TAB_IMPROC")); + nb->append_page (*getFileBrowserPanel(), M("PREFERENCES_TAB_BROWSER")); + nb->append_page (*getColorManagementPanel(),M("PREFERENCES_TAB_COLORMGR")); + nb->append_page (*getBatchProcPanel(), M("PREFERENCES_BATCH_PROCESSING")); + nb->set_current_page (initialPage); + + fillPreferences (); + + show_all_children (); + set_modal (true); +} + +Gtk::Widget* Preferences::getBatchProcPanel () { + + Gtk::VBox* mvbpp = Gtk::manage (new Gtk::VBox ()); + + Gtk::ScrolledWindow* behscrollw = Gtk::manage (new Gtk::ScrolledWindow ()); + behscrollw->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + Gtk::Frame* behFrame = Gtk::manage (new Gtk::Frame (M("PREFERENCES_BEHAVIOR"))); + behFrame->add (*behscrollw); + mvbpp->pack_start (*behFrame); +// mvbpp->pack_start (*behFrame, Gtk::PACK_SHRINK, 2); + Gtk::TreeView* behTreeView = Gtk::manage (new Gtk::TreeView ()); + behscrollw->add (*behTreeView); + + behModel = Gtk::TreeStore::create (behavColumns); + behTreeView->set_model (behModel); + + behTreeView->append_column (M("PREFERENCES_PROPERTY"), behavColumns.label); + behTreeView->append_column_editable (M("PREFERENCES_ADD"), behavColumns.badd); + behTreeView->append_column_editable (M("PREFERENCES_SET"), behavColumns.bset); + + Gtk::CellRendererToggle* cr_add = static_cast (behTreeView->get_column (1)->get_first_cell_renderer()); + Gtk::CellRendererToggle* cr_set = static_cast (behTreeView->get_column (2)->get_first_cell_renderer()); + + cr_add->set_radio (true); + cr_add->set_property("xalign", 0.0f); + sigc::connection addc = cr_add->signal_toggled().connect (sigc::mem_fun (*this, &Preferences::behAddRadioToggled)); + cr_set->set_radio (true); + cr_set->set_property("xalign", 0.0f); + sigc::connection setc = cr_set->signal_toggled().connect (sigc::mem_fun (*this, &Preferences::behSetRadioToggled)); + + behTreeView->get_column (1)->add_attribute (*cr_add, "visible", behavColumns.visible); + behTreeView->get_column (1)->set_sizing(Gtk::TREE_VIEW_COLUMN_FIXED); + behTreeView->get_column (1)->set_fixed_width (50); + behTreeView->get_column (2)->add_attribute (*cr_set, "visible", behavColumns.visible); + behTreeView->get_column (2)->set_sizing(Gtk::TREE_VIEW_COLUMN_FIXED); + behTreeView->get_column (2)->set_fixed_width (50); + + // fill model + Gtk::TreeModel::iterator mi, ci; + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_EXPOSURE_LABEL")); + appendBehavList (mi, M("TP_EXPOSURE_EXPCOMP"), ADDSET_TC_EXPCOMP, false); + appendBehavList (mi, M("TP_EXPOSURE_BRIGHTNESS"), ADDSET_TC_BRIGHTNESS, false); + appendBehavList (mi, M("TP_EXPOSURE_BLACKLEVEL"), ADDSET_TC_BLACKLEVEL, false); + appendBehavList (mi, M("TP_EXPOSURE_CONTRAST"), ADDSET_TC_CONTRAST, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_SHADOWSHLIGHTS_LABEL")); + appendBehavList (mi, M("TP_SHADOWSHLIGHTS_HIGHLIGHTS"), ADDSET_SH_HIGHLIGHTS, false); + appendBehavList (mi, M("TP_SHADOWSHLIGHTS_SHADOWS"), ADDSET_SH_SHADOWS, false); + appendBehavList (mi, M("TP_SHADOWSHLIGHTS_LOCALCONTR"), ADDSET_SH_LOCALCONTRAST, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_LUMACURVE_LABEL")); + appendBehavList (mi, M("TP_LUMACURVE_BRIGHTNESS"), ADDSET_LC_BRIGHTNESS, false); + appendBehavList (mi, M("TP_LUMACURVE_CONTRAST"), ADDSET_LC_CONTRAST, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_SHARPENING_LABEL")); + appendBehavList (mi, M("TP_SHARPENING_AMOUNT"), ADDSET_SHARP_AMOUNT, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_LUMADENOISE_LABEL")); + appendBehavList (mi, M("TP_LUMADENOISE_EDGETOLERANCE"), ADDSET_LD_EDGETOLERANCE, true); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_WBALANCE_LABEL")); + appendBehavList (mi, M("TP_WBALANCE_TEMPERATURE"), ADDSET_WB_TEMPERATURE, true); + appendBehavList (mi, M("TP_WBALANCE_GREEN"), ADDSET_WB_GREEN, true); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_COLORBOOST_LABEL")); + appendBehavList (mi, M("TP_COLORBOOST_AMOUNT"), ADDSET_CBOOST_AMOUNT, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_COLORSHIFT_LABEL")); + appendBehavList (mi, M("TP_COLORSHIFT_BLUEYELLOW"), ADDSET_CS_BLUEYELLOW, false); + appendBehavList (mi, M("TP_COLORSHIFT_GREENMAGENTA"), ADDSET_CS_GREENMAGENTA, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_ROTATE_LABEL")); + appendBehavList (mi, M("TP_ROTATE_DEGREE"), ADDSET_ROTATE_DEGREE, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_DISTORTION_LABEL")); + appendBehavList (mi, M("TP_DISTORTION_AMOUNT"), ADDSET_DIST_AMOUNT, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_CACORRECTION_LABEL")); + appendBehavList (mi, M("TP_CACORRECTION_BLUE"), ADDSET_CA_BLUE, true); + appendBehavList (mi, M("TP_CACORRECTION_RED"), ADDSET_CA_RED, true); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_VIGNETTING_LABEL")); + appendBehavList (mi, M("TP_VIGNETTING_AMOUNT"), ADDSET_VIGN_AMOUNT, false); + + behTreeView->expand_all (); + + return mvbpp; +} + +void Preferences::appendBehavList (Gtk::TreeModel::iterator& parent, Glib::ustring label, int id, bool set) { + + Gtk::TreeModel::iterator ci = behModel->append (parent->children()); + ci->set_value (behavColumns.label, label); + ci->set_value (behavColumns.visible, true); + ci->set_value (behavColumns.badd, !set); + ci->set_value (behavColumns.bset, set); + ci->set_value (behavColumns.addsetid, id); +} + +void Preferences::behAddRadioToggled (const Glib::ustring& path) { + + Gtk::TreeModel::iterator iter = behModel->get_iter (path); + bool set = iter->get_value (behavColumns.bset); + iter->set_value (behavColumns.bset, false); + iter->set_value (behavColumns.badd, true); +} + +void Preferences::behSetRadioToggled (const Glib::ustring& path) { + + Gtk::TreeModel::iterator iter = behModel->get_iter (path); + bool add = iter->get_value (behavColumns.badd); + iter->set_value (behavColumns.bset, true); + iter->set_value (behavColumns.badd, false); +} + +Gtk::Widget* Preferences::getProcParamsPanel () { + + Gtk::VBox* mvbpp = Gtk::manage (new Gtk::VBox ()); + + Gtk::Frame* fpp = Gtk::manage (new Gtk::Frame (M("PREFERENCES_IMPROCPARAMS"))); + Gtk::Label* drlab = Gtk::manage (new Gtk::Label (M("PREFERENCES_FORRAW")+":")); + rprofiles = Gtk::manage (new Gtk::ComboBoxText ()); + Gtk::Label* drimg = Gtk::manage (new Gtk::Label (M("PREFERENCES_FORIMAGE")+":")); + iprofiles = Gtk::manage (new Gtk::ComboBoxText ()); + Gtk::Table* defpt = Gtk::manage (new Gtk::Table (2, 2)); + defpt->attach (*drlab, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + defpt->attach (*rprofiles, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + defpt->attach (*drimg, 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + defpt->attach (*iprofiles, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + fpp->add (*defpt); + + mvbpp->pack_start (*fpp, Gtk::PACK_SHRINK, 4); + + Gtk::Frame* fdp = Gtk::manage (new Gtk::Frame (M("PREFERENCES_PROFILEHANDLING"))); + Gtk::VBox* vbdp = Gtk::manage (new Gtk::VBox ()); + saveParamsFile = Gtk::manage (new Gtk::CheckButton (M("PREFERENCES_PROFILESAVEINPUT"))); + vbdp->pack_start (*saveParamsFile, Gtk::PACK_SHRINK, 4); + saveParamsCache = Gtk::manage (new Gtk::CheckButton (M("PREFERENCES_PROFILESAVECACHE"))); + vbdp->pack_start (*saveParamsCache, Gtk::PACK_SHRINK, 4); + Gtk::Label* lplab = Gtk::manage (new Gtk::Label (M("PREFERENCES_PROFILELOADPR")+":")); + loadParamsPreference = Gtk::manage (new Gtk::ComboBoxText ()); + loadParamsPreference->append_text (M("PREFERENCES_PROFILEPRCACHE")); + loadParamsPreference->append_text (M("PREFERENCES_PROFILEPRFILE")); + Gtk::HBox* hb41 = Gtk::manage (new Gtk::HBox ()); + hb41->pack_start (*lplab, Gtk::PACK_SHRINK, 4); + hb41->pack_start (*loadParamsPreference); + vbdp->pack_start (*hb41, Gtk::PACK_SHRINK, 4); + fdp->add (*vbdp); + mvbpp->pack_start (*fdp, Gtk::PACK_SHRINK, 4); + + Gtk::Frame* fdem = Gtk::manage (new Gtk::Frame (M("PREFERENCES_DEMOSAICINGALGO"))); + Gtk::VBox* fdb = Gtk::manage (new Gtk::VBox ()); + fdb->set_border_width (4); + fdem->add (*fdb); + Gtk::Label* dmlab = Gtk::manage (new Gtk::Label (M("PREFERENCES_DMETHOD")+":")); + dmethod = Gtk::manage (new Gtk::ComboBoxText ()); + Gtk::HBox* hb11 = Gtk::manage (new Gtk::HBox ()); + hb11->pack_start (*dmlab, Gtk::PACK_SHRINK, 4); + hb11->pack_start (*dmethod); + dmethod->append_text ("EAHD"); + dmethod->append_text ("HPHD"); + dmethod->append_text ("VNG-4"); + dmethod->append_text ("PPG"); + dmethod->append_text ("DCB"); + dmethod->append_text ("AHD"); + Gtk::Label* cclab = Gtk::manage (new Gtk::Label (M("PREFERENCES_FALSECOLOR")+":")); + ccSteps = Gtk::manage (new Gtk::SpinButton ()); + ccSteps->set_digits (0); + ccSteps->set_increments (1, 2); + ccSteps->set_range (0, 5); + Gtk::HBox* hb12 = Gtk::manage (new Gtk::HBox ()); + hb12->pack_start (*cclab, Gtk::PACK_SHRINK, 4); + hb12->pack_start (*ccSteps); + + dcbIterationsLabel = Gtk::manage(new Gtk::Label(M("PREFERENCES_DCBITERATIONS")+":")); + dcbIterations = Gtk::manage(new Gtk::SpinButton ()); + dcbIterations->set_digits(0); + dcbIterations->set_increments(1, 2); + dcbIterations->set_range(0, 10); + Gtk::HBox* hb13 = Gtk::manage(new Gtk::HBox()); + hb13->pack_start (*dcbIterationsLabel, Gtk::PACK_SHRINK, 4); + hb13->pack_start (*dcbIterations); + + dcbEnhance = Gtk::manage(new Gtk::CheckButton((M("PREFERENCES_DCBENHANCE")))); + + fdb->pack_start (*hb11, Gtk::PACK_SHRINK, 4); + fdb->pack_start (*hb12, Gtk::PACK_SHRINK, 4); + fdb->pack_start (*hb13, Gtk::PACK_SHRINK, 4); + fdb->pack_start (*dcbEnhance, Gtk::PACK_SHRINK, 4); + mvbpp->pack_start (*fdem, Gtk::PACK_SHRINK, 4); + mvbpp->set_border_width (4); + // drlab->set_size_request (drimg->get_width(), -1); + + std::vector pnames; + if (options.multiUser) + parseDir (Options::rtdir + "/" + options.profilePath, pnames, ".pp2"); + parseDir (argv0 + "/" + options.profilePath, pnames, ".pp2"); + for (int i=0; iappend_text (pnames[i]); + iprofiles->append_text (pnames[i]); + } + + dmconn = dmethod->signal_changed().connect( sigc::mem_fun(*this, &Preferences::dmethodChanged) ); + + return mvbpp; +} + +Gtk::Widget* Preferences::getColorManagementPanel () { + + Gtk::VBox* mvbcm = Gtk::manage (new Gtk::VBox ()); + mvbcm->set_border_width (4); + + Gtk::Label* intlab = Gtk::manage (new Gtk::Label (M("PREFERENCES_CMETRICINTENT")+":")); + intent = Gtk::manage (new Gtk::ComboBoxText ()); + intent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); + intent->append_text (M("PREFERENCES_INTENT_RELATIVE")); + intent->append_text (M("PREFERENCES_INTENT_SATURATION")); + intent->append_text (M("PREFERENCES_INTENT_ABSOLUTE")); + + iccDir = Gtk::manage (new Gtk::FileChooserButton (M("PREFERENCES_ICCDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + Gtk::Label* pdlabel = Gtk::manage (new Gtk::Label (M("PREFERENCES_ICCDIR")+":")); + + monProfile = Gtk::manage (new Gtk::FileChooserButton (M("PREFERENCES_MONITORICC"), Gtk::FILE_CHOOSER_ACTION_OPEN)); + Gtk::Label* mplabel = Gtk::manage (new Gtk::Label (M("PREFERENCES_MONITORICC")+":")); + + Gtk::Table* colt = Gtk::manage (new Gtk::Table (3, 2)); + colt->attach (*intlab, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + colt->attach (*intent, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + colt->attach (*pdlabel, 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + colt->attach (*iccDir, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + colt->attach (*mplabel, 0, 1, 2, 3, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + colt->attach (*monProfile, 1, 2, 2, 3, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + mvbcm->pack_start (*colt, Gtk::PACK_SHRINK, 4); + + return mvbcm; +} + +Gtk::Widget* Preferences::getGeneralPanel () { + + Gtk::VBox* mvbsd = new Gtk::VBox (); + + Gtk::Frame* flang = new Gtk::Frame (M("PREFERENCES_DEFAULTLANG")); + Gtk::HBox* hblang = new Gtk::HBox (); + hblang->set_border_width (4); + Gtk::Label* langlab = new Gtk::Label (M("PREFERENCES_SELECTLANG")+":"); + languages = new Gtk::ComboBoxText (); + + std::vector langs; + parseDir (argv0 + "/languages", langs, ""); + for (int i=0; iappend_text (langs[i]); + + Gtk::Label* langw = new Gtk::Label (Glib::ustring("(") + M("PREFERENCES_APPLNEXTSTARTUP") + ")"); + hblang->pack_start (*langlab, Gtk::PACK_SHRINK, 4); + hblang->pack_start (*languages); + hblang->pack_end (*langw, Gtk::PACK_SHRINK, 4); + flang->add (*hblang); + mvbsd->pack_start (*flang, Gtk::PACK_SHRINK, 4); + + Gtk::Frame* ftheme = new Gtk::Frame (M("PREFERENCES_DEFAULTTHEME")); + Gtk::HBox* hbtheme = new Gtk::HBox (); + hbtheme->set_border_width (4); + Gtk::Label* themelab = new Gtk::Label (M("PREFERENCES_SELECTTHEME")+":"); + theme = new Gtk::ComboBoxText (); + + theme->append_text (Glib::ustring("(")+M("PREFERENCES_GTKTHEME")+")"); + theme->set_active (0); + std::vector themes; + parseDir (argv0 + "/themes", themes, ""); + for (int i=0; iappend_text (themes[i]); + + hbtheme->pack_start (*themelab, Gtk::PACK_SHRINK, 4); + hbtheme->pack_start (*theme); + ftheme->add (*hbtheme); + mvbsd->pack_start (*ftheme, Gtk::PACK_SHRINK, 4); + +//----- + + Gtk::Frame* frl = new Gtk::Frame (M("PREFERENCES_CLIPPINGIND")); + blinkClipped = new Gtk::CheckButton (M("PREFERENCES_BLINKCLIPPED")); + Gtk::VBox* vbrl = new Gtk::VBox (); + vbrl->set_border_width (4); + vbrl->pack_start (*blinkClipped, Gtk::PACK_SHRINK, 4); + + Gtk::HBox* vbhl = new Gtk::HBox (); + Gtk::Label* hll = new Gtk::Label (M("PREFERENCES_HLTHRESHOLD")+": "); + hlThresh = new Gtk::SpinButton (); + hlThresh->set_digits (0); + hlThresh->set_increments (1, 10); + hlThresh->set_range (0, 255); + vbhl->pack_start (*hll, Gtk::PACK_SHRINK, 8); + vbhl->pack_start (*hlThresh, Gtk::PACK_SHRINK, 8); + + vbrl->pack_start (*vbhl, Gtk::PACK_SHRINK, 4); + + Gtk::HBox* vbsh = new Gtk::HBox (); + Gtk::Label* shl = new Gtk::Label (M("PREFERENCES_SHTHRESHOLD")+": "); + shThresh = new Gtk::SpinButton (); + shThresh->show (); + shThresh->set_digits (0); + shThresh->set_increments (1, 10); + shThresh->set_range (0, 255); + vbsh->pack_start (*shl, Gtk::PACK_SHRINK, 8); + vbsh->pack_start (*shThresh, Gtk::PACK_SHRINK, 8); + vbrl->pack_start (*vbsh, Gtk::PACK_SHRINK, 4); + + frl->add (*vbrl); + mvbsd->pack_start (*frl, Gtk::PACK_SHRINK, 4); + +//----- + Gtk::Frame* fdf = new Gtk::Frame (M("PREFERENCES_DATEFORMAT")); + + Gtk::HBox* hb6 = new Gtk::HBox (); + Gtk::VBox* dfvb = new Gtk::VBox (); + Gtk::Label* dflab = new Gtk::Label (M("PREFERENCES_DATEFORMAT")+":"); + hb6->pack_start (*dflab, Gtk::PACK_SHRINK,4); + dateformat = new Gtk::Entry (); + dateformat->set_tooltip_markup (M("PREFERENCES_DATEFORMATHINT")); + dflab->set_tooltip_markup (M("PREFERENCES_DATEFORMATHINT")); + hb6->pack_start (*dateformat); + dfvb->pack_start (*hb6, Gtk::PACK_SHRINK, 4); + fdf->add (*dfvb); + dfvb->set_border_width (4); + + mvbsd->pack_start (*fdf, Gtk::PACK_SHRINK, 4); + + //----- + Gtk::Frame* fdg = new Gtk::Frame (M("PREFERENCES_EXTERNALEDITOR")); + Gtk::VBox* dgvb = new Gtk::VBox (); + + Gtk::HBox* hb7c = new Gtk::HBox (); + edOther = new Gtk::RadioButton (M("PREFERENCES_EDITORCMDLINE")+":"); + hb7c->pack_start (*edOther, Gtk::PACK_SHRINK,4); + editorToSendTo = new Gtk::Entry (); + hb7c->pack_start (*editorToSendTo); + Gtk::RadioButton::Group ge = edOther->get_group(); + +#ifdef __APPLE__ + Gtk::HBox* hb7 = new Gtk::HBox (); + edGimp = new Gtk::RadioButton ("GIMP"); + hb7->pack_start (*edGimp, Gtk::PACK_SHRINK,4); + dgvb->pack_start (*hb7, Gtk::PACK_SHRINK, 4); + edGimp->set_group (ge); + + Gtk::HBox* hb7b = new Gtk::HBox (); + edPS = new Gtk::RadioButton (M("PREFERENCES_PSPATH")+":"); + hb7b->pack_start (*edPS, Gtk::PACK_SHRINK,4); + psDir = new Gtk::FileChooserButton (M("PREFERENCES_PSPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER); + hb7b->pack_start (*psDir); + dgvb->pack_start (*hb7b, Gtk::PACK_SHRINK, 4); + edPS->set_group (ge); +#elif defined _WIN32 + Gtk::HBox* hb7 = new Gtk::HBox (); + edGimp = new Gtk::RadioButton (M("PREFERENCES_GIMPPATH")+":"); + hb7->pack_start (*edGimp, Gtk::PACK_SHRINK,4); + gimpDir = new Gtk::FileChooserButton (M("PREFERENCES_GIMPPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER); + hb7->pack_start (*gimpDir); + dgvb->pack_start (*hb7, Gtk::PACK_SHRINK, 4); + edGimp->set_group (ge); + + Gtk::HBox* hb7b = new Gtk::HBox (); + edPS = new Gtk::RadioButton (M("PREFERENCES_PSPATH")+":"); + hb7b->pack_start (*edPS, Gtk::PACK_SHRINK,4); + psDir = new Gtk::FileChooserButton (M("PREFERENCES_PSPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER); + hb7b->pack_start (*psDir); + dgvb->pack_start (*hb7b, Gtk::PACK_SHRINK, 4); + edPS->set_group (ge); +#else + Gtk::HBox* hb7 = new Gtk::HBox (); + edGimp = new Gtk::RadioButton ("GIMP"); + hb7->pack_start (*edGimp, Gtk::PACK_SHRINK,4); + dgvb->pack_start (*hb7, Gtk::PACK_SHRINK, 4); + edGimp->set_group (ge); +#endif + + dgvb->pack_start (*hb7c, Gtk::PACK_SHRINK, 4); + dgvb->set_border_width (4); + fdg->add (*dgvb); + mvbsd->pack_start (*fdg, Gtk::PACK_SHRINK, 4); + + mvbsd->set_border_width (4); + + tconn = theme->signal_changed().connect( sigc::mem_fun(*this, &Preferences::themeChanged) ); + + return mvbsd; +} + +Gtk::Widget* Preferences::getFileBrowserPanel () { + + Gtk::VBox* mvbfb = new Gtk::VBox (); + mvbfb->set_border_width (4); + + Gtk::Frame* fsd = new Gtk::Frame (M("PREFERENCES_STARTUPIMDIR")); + + sdcurrent = new Gtk::RadioButton (M("PREFERENCES_DIRSOFTWARE")); + sdlast = new Gtk::RadioButton (M("PREFERENCES_DIRLAST")); + sdhome = new Gtk::RadioButton (M("PREFERENCES_DIRHOME")); + sdother = new Gtk::RadioButton (M("PREFERENCES_DIROTHER")+": "); + startupdir = new Gtk::Entry (); + + Gtk::Button* sdselect = new Gtk::Button (""); + sdselect->set_image (*(new Gtk::Image (Gtk::StockID("gtk-open"), Gtk::ICON_SIZE_BUTTON))); + + Gtk::RadioButton::Group opts = sdcurrent->get_group(); + sdlast->set_group (opts); + sdhome->set_group (opts); + sdother->set_group (opts); + + Gtk::VBox* vbsd = new Gtk::VBox (); + vbsd->pack_start (*sdcurrent, Gtk::PACK_SHRINK,0); + vbsd->pack_start (*sdlast, Gtk::PACK_SHRINK,0); + vbsd->pack_start (*sdhome, Gtk::PACK_SHRINK,0); + Gtk::HBox* otherbox = new Gtk::HBox (); + otherbox->pack_start (*sdother, Gtk::PACK_SHRINK); + otherbox->pack_start (*startupdir); + otherbox->pack_end (*sdselect, Gtk::PACK_SHRINK, 4); + vbsd->pack_start (*otherbox, Gtk::PACK_SHRINK, 0); + vbsd->set_border_width (4); + + fsd->add (*vbsd); + mvbfb->pack_start (*fsd, Gtk::PACK_SHRINK, 4); + + sdselect->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::selectStartupDir) ); + +//--- + + + Gtk::Frame* fro = new Gtk::Frame (M("PREFERENCES_FBROWSEROPTS")); + showDateTime = new Gtk::CheckButton (M("PREFERENCES_SHOWDATETIME")); + showBasicExif = new Gtk::CheckButton (M("PREFERENCES_SHOWBASICEXIF")); + Gtk::VBox* vbro = new Gtk::VBox (); + overlayedFileNames = new Gtk::CheckButton (M("PREFERENCES_OVERLAY_FILENAMES")); + vbro->set_border_width (4); + vbro->pack_start (*showDateTime, Gtk::PACK_SHRINK, 0); + vbro->pack_start (*showBasicExif, Gtk::PACK_SHRINK, 0); + vbro->pack_start (*overlayedFileNames, Gtk::PACK_SHRINK, 4); + + fro->add (*vbro); + + Gtk::Frame* fre = new Gtk::Frame (M("PREFERENCES_PARSEDEXT")); + Gtk::VBox* vbre = new Gtk::VBox (); + vbre->set_border_width (4); + Gtk::HBox* hb0 = new Gtk::HBox (); + Gtk::Label* elab = new Gtk::Label (M("PREFERENCES_PARSEDEXTADD")+":"); + hb0->pack_start (*elab, Gtk::PACK_SHRINK, 4); + extension = new Gtk::Entry (); + hb0->pack_start (*extension); + addExt = new Gtk::Button (); + delExt = new Gtk::Button (); + addExt->set_tooltip_text (M("PREFERENCES_PARSEDEXTADDHINT")); + delExt->set_tooltip_text (M("PREFERENCES_PARSEDEXTDELHINT")); + Gtk::Image* addExtImg = new Gtk::Image (argv0+"/images/list-add12.png"); + Gtk::Image* delExtImg = new Gtk::Image (argv0+"/images/list-remove12r.png"); + addExt->add (*addExtImg); + delExt->add (*delExtImg); + hb0->pack_end (*delExt, Gtk::PACK_SHRINK, 4); + hb0->pack_end (*addExt, Gtk::PACK_SHRINK, 4); + extensions = new Gtk::TreeView (); + Gtk::ScrolledWindow* hscrollw = new Gtk::ScrolledWindow (); + hscrollw->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); + hscrollw->add (*extensions); + extensionModel = Gtk::ListStore::create (extensionColumns); + extensions->set_model (extensionModel); + extensions->append_column_editable("Enabled", extensionColumns.enabled); + extensions->append_column("Extension", extensionColumns.ext); + extensions->set_headers_visible (false); + vbre->pack_start (*hscrollw); + vbre->pack_start (*hb0, Gtk::PACK_SHRINK, 0); + + fre->add (*vbre); + + Gtk::Frame* frc = new Gtk::Frame (M("PREFERENCES_CACHEOPTS")); + Gtk::VBox* vbc = new Gtk::VBox (); + frc->add (*vbc); + vbc->set_border_width (4); + + Gtk::Label* cflab = new Gtk::Label (M("PREFERENCES_CACHETHUMBFORM")+":"); + cformat = new Gtk::ComboBoxText (); + cformat->append_text (M("PREFERENCES_CACHEFORMAT1")); + cformat->append_text (M("PREFERENCES_CACHEFORMAT2")); + cformat->append_text (M("PREFERENCES_CACHEFORMAT1")+", 16 bit"); + Gtk::HBox* hb2 = new Gtk::HBox (); + hb2->pack_start (*cflab, Gtk::PACK_SHRINK, 4); + hb2->pack_start (*cformat); + vbc->pack_start (*hb2, Gtk::PACK_SHRINK, 0); + + Gtk::HBox* hb3 = new Gtk::HBox (); + Gtk::Label* chlab = new Gtk::Label (M("PREFERENCES_CACHETHUMBHEIGHT")+":"); + maxThumbSize = new Gtk::SpinButton (); + hb3->pack_start (*chlab, Gtk::PACK_SHRINK, 8); + hb3->pack_start (*maxThumbSize, Gtk::PACK_SHRINK, 8); + + maxThumbSize->set_digits (0); + maxThumbSize->set_increments (1, 10); + maxThumbSize->set_range (40, 400); + vbc->pack_start (*hb3, Gtk::PACK_SHRINK, 0); + + Gtk::HBox* hb4 = new Gtk::HBox (); + Gtk::Label* celab = new Gtk::Label (M("PREFERENCES_CACHEMAXENTRIES")+":"); + maxCacheEntries = new Gtk::SpinButton (); + hb4->pack_start (*celab, Gtk::PACK_SHRINK, 8); + hb4->pack_start (*maxCacheEntries, Gtk::PACK_SHRINK, 8); + + maxCacheEntries->set_digits (0); + maxCacheEntries->set_increments (1, 10); + maxCacheEntries->set_range (10, 100000); + vbc->pack_start (*hb4, Gtk::PACK_SHRINK, 0); + + Gtk::HBox* hb5 = new Gtk::HBox (); + clearThumbnails = new Gtk::Button (M("PREFERENCES_CACHECLEARTHUMBS")); + clearProfiles = new Gtk::Button (M("PREFERENCES_CACHECLEARPROFILES")); + clearAll = new Gtk::Button (M("PREFERENCES_CACHECLEARALL")); + hb5->pack_start (*clearThumbnails, Gtk::PACK_SHRINK, 8); + hb5->pack_start (*clearProfiles, Gtk::PACK_SHRINK, 8); + hb5->pack_start (*clearAll, Gtk::PACK_SHRINK, 8); + vbc->pack_start (*hb5, Gtk::PACK_SHRINK, 0); + + Gtk::HBox* hb6 = new Gtk::HBox (); + Gtk::VBox* vb6 = new Gtk::VBox (); + + vb6->pack_start (*fro); + vb6->pack_end (*frc); + hb6->pack_start (*vb6); + hb6->pack_start (*fre); + + mvbfb->pack_start (*hb6, Gtk::PACK_SHRINK, 4); + +// mvbfb->pack_start (*fro, Gtk::PACK_SHRINK, 4); +// mvbfb->pack_start (*fre); +// mvbfb->pack_start (*frc, Gtk::PACK_SHRINK, 4); + + addExt->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::addExtPressed) ); + delExt->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::delExtPressed) ); + extension->signal_activate().connect( sigc::mem_fun(*this, &Preferences::addExtPressed) ); + clearThumbnails->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::clearThumbImagesPressed) ); + clearProfiles->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::clearProfilesPressed) ); + clearAll->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::clearAllPressed) ); + + return mvbfb; +} + +void Preferences::parseDir (Glib::ustring dirname, std::vector& items, Glib::ustring ext) { + + // process directory + Glib::Dir* dir = NULL; + try { + dir = new Glib::Dir (dirname); + } + catch (const Glib::FileError& fe) { + return; + } + dirname = dirname + "/"; + for (Glib::DirIterator i = dir->begin(); i!=dir->end(); ++i) { + Glib::ustring fname = dirname + *i; + Glib::ustring sname = *i; + // ignore directories + if (!Glib::file_test (fname, Glib::FILE_TEST_IS_DIR) && sname.size() >= ext.size() && sname.substr (sname.size()-ext.size(), ext.size()).casefold() == ext) + items.push_back (sname.substr(0,sname.size()-ext.size())); + } + delete dir; +} + +void Preferences::storePreferences () { + + moptions.defProfRaw = rprofiles->get_active_text(); + moptions.defProfImg = iprofiles->get_active_text(); + moptions.dateFormat = dateformat->get_text(); + moptions.fbShowDateTime = showDateTime->get_active (); + moptions.fbShowBasicExif = showBasicExif->get_active (); + moptions.blinkClipped = blinkClipped->get_active (); + moptions.highlightThreshold = (int)hlThresh->get_value (); + moptions.shadowThreshold = (int)shThresh->get_value (); + moptions.language = languages->get_active_text (); + moptions.theme = theme->get_active_text (); +#ifdef _WIN32 + moptions.gimpDir = gimpDir->get_filename (); + moptions.psDir = psDir->get_filename (); +#elif defined __APPLE__ + moptions.psDir = psDir->get_filename (); +#endif + moptions.customEditorProg = editorToSendTo->get_text (); + if (edGimp->get_active ()) + moptions.editorToSendTo = 1; +#ifdef _WIN32 + else if (edPS->get_active ()) + moptions.editorToSendTo = 2; +#elif defined __APPLE__ + else if (edPS->get_active ()) + moptions.editorToSendTo = 2; +#endif + else if (edOther->get_active ()) + moptions.editorToSendTo = 3; + + + moptions.rtSettings.colorCorrectionSteps= (int)ccSteps->get_value (); + moptions.rtSettings.monitorProfile = monProfile->get_filename (); + moptions.rtSettings.iccDirectory = iccDir->get_filename (); + moptions.rtSettings.colorimetricIntent = intent->get_active_row_number (); + if (dmethod->get_active_row_number()==0) + moptions.rtSettings.demosaicMethod = "eahd"; + else if (dmethod->get_active_row_number()==1) + moptions.rtSettings.demosaicMethod = "hphd"; + else if (dmethod->get_active_row_number()==2) + moptions.rtSettings.demosaicMethod = "vng4"; + else if (dmethod->get_active_row_number()==3) + moptions.rtSettings.demosaicMethod = "ppg"; + else if (dmethod->get_active_row_number()==4) + moptions.rtSettings.demosaicMethod = "dcb"; + else if (dmethod->get_active_row_number()==5) + moptions.rtSettings.demosaicMethod = "ahd"; + moptions.rtSettings.dcb_iterations=(int)dcbIterations->get_value(); + moptions.rtSettings.dcb_enhance=dcbEnhance->get_active(); + + if (sdcurrent->get_active ()) + moptions.startupDir = STARTUPDIR_CURRENT; + else if (sdhome->get_active ()) + moptions.startupDir = STARTUPDIR_HOME; + else if (sdlast->get_active ()) + moptions.startupDir = STARTUPDIR_LAST; + else if (sdother->get_active ()) { + moptions.startupDir = STARTUPDIR_CUSTOM; + moptions.startupPath = startupdir->get_text(); + } + + moptions.parseExtensions.clear (); + moptions.parseExtensionsEnabled.clear (); + Gtk::TreeNodeChildren c = extensionModel->children (); + for (int i=0; iget_active_row_number() == 0) + moptions.thumbnailFormat = FT_Custom; + else if (cformat->get_active_row_number() == 1) + moptions.thumbnailFormat = FT_Jpeg; + else if (cformat->get_active_row_number() == 2) + moptions.thumbnailFormat = FT_Custom16; + + moptions.maxThumbnailHeight = (int)maxThumbSize->get_value (); + moptions.maxCacheEntries = (int)maxCacheEntries->get_value (); + moptions.overlayedFileNames = overlayedFileNames->get_active (); + + moptions.saveParamsFile = saveParamsFile->get_active (); + moptions.saveParamsCache = saveParamsCache->get_active (); + moptions.paramsLoadLocation = (PPLoadLocation)loadParamsPreference->get_active_row_number (); + + int i = 0; + moptions.baBehav.resize (ADDSET_PARAM_NUM); + for (Gtk::TreeIter sections=behModel->children().begin(); sections!=behModel->children().end(); sections++) + for (Gtk::TreeIter adjs=sections->children().begin(); adjs!=sections->children().end(); adjs++) + moptions.baBehav[adjs->get_value (behavColumns.addsetid)] = adjs->get_value (behavColumns.badd); +} + +void Preferences::fillPreferences () { + + dmconn.block (true); + tconn.block (true); + + rprofiles->set_active_text (moptions.defProfRaw); + iprofiles->set_active_text (moptions.defProfImg); + dateformat->set_text (moptions.dateFormat); + ccSteps->set_value (moptions.rtSettings.colorCorrectionSteps); + if (Glib::file_test (moptions.rtSettings.monitorProfile, Glib::FILE_TEST_EXISTS)) + monProfile->set_filename (moptions.rtSettings.monitorProfile); + if (Glib::file_test (moptions.rtSettings.iccDirectory, Glib::FILE_TEST_IS_DIR)) + iccDir->set_filename (moptions.rtSettings.iccDirectory); + intent->set_active (moptions.rtSettings.colorimetricIntent); + languages->set_active_text (moptions.language); + theme->set_active_text (moptions.theme); + showDateTime->set_active (moptions.fbShowDateTime); + showBasicExif->set_active (moptions.fbShowBasicExif); + blinkClipped->set_active (moptions.blinkClipped); + hlThresh->set_value (moptions.highlightThreshold); + shThresh->set_value (moptions.shadowThreshold); + + edGimp->set_active (moptions.editorToSendTo==1); + edOther->set_active (moptions.editorToSendTo==3); +#ifdef _WIN32 + edPS->set_active (moptions.editorToSendTo==2); + if (Glib::file_test (moptions.gimpDir, Glib::FILE_TEST_IS_DIR)) + gimpDir->set_filename (moptions.gimpDir); + if (Glib::file_test (moptions.psDir, Glib::FILE_TEST_IS_DIR)) + psDir->set_filename (moptions.psDir); +#elif defined __APPLE__ + edPS->set_active (moptions.editorToSendTo==2); + if (Glib::file_test (moptions.psDir, Glib::FILE_TEST_IS_DIR)) + psDir->set_filename (moptions.psDir); +#endif + editorToSendTo->set_text (moptions.customEditorProg); + + if (moptions.rtSettings.demosaicMethod=="eahd") + dmethod->set_active (0); + else if (moptions.rtSettings.demosaicMethod=="hphd") + dmethod->set_active (1); + else if (moptions.rtSettings.demosaicMethod=="vng4") + dmethod->set_active (2); + else if (moptions.rtSettings.demosaicMethod=="ppg") + dmethod->set_active (3); + else if (moptions.rtSettings.demosaicMethod=="dcb") + dmethod->set_active (4); + else if (moptions.rtSettings.demosaicMethod=="ahd") + dmethod->set_active (5); + dcbEnhance->set_active(moptions.rtSettings.dcb_enhance); + dcbIterations->set_value(moptions.rtSettings.dcb_iterations); + dcbEnhance->set_sensitive(moptions.rtSettings.demosaicMethod=="dcb"); + dcbIterations->set_sensitive(moptions.rtSettings.demosaicMethod=="dcb"); + dcbIterationsLabel->set_sensitive(moptions.rtSettings.demosaicMethod=="dcb"); + + if (moptions.startupDir==STARTUPDIR_CURRENT) + sdcurrent->set_active (); + else if (moptions.startupDir==STARTUPDIR_LAST) + sdlast->set_active (); + else if (moptions.startupDir==STARTUPDIR_HOME) + sdhome->set_active (); + else if (moptions.startupDir==STARTUPDIR_CUSTOM) { + sdother->set_active (); + startupdir->set_text (moptions.startupPath); + } + + extensionModel->clear (); + for (int i=0; iappend()); + row[extensionColumns.enabled] = moptions.parseExtensionsEnabled[i]; + row[extensionColumns.ext] = moptions.parseExtensions[i]; + } + + if (moptions.thumbnailFormat == FT_Custom) + cformat->set_active (0); + else if (moptions.thumbnailFormat == FT_Jpeg) + cformat->set_active (1); + else if (moptions.thumbnailFormat == FT_Custom16) + cformat->set_active (2); + + maxThumbSize->set_value (moptions.maxThumbnailHeight); + maxCacheEntries->set_value (moptions.maxCacheEntries); + overlayedFileNames->set_active (moptions.overlayedFileNames); + + saveParamsFile->set_active (moptions.saveParamsFile); + saveParamsCache->set_active (moptions.saveParamsCache); + loadParamsPreference->set_active (moptions.paramsLoadLocation); + + addc.block (true); + setc.block (true); + if (moptions.baBehav.size() == ADDSET_PARAM_NUM) { + for (int i=0; ichildren().begin(); sections!=behModel->children().end(); sections++) + for (Gtk::TreeIter adjs=sections->children().begin(); adjs!=sections->children().end(); adjs++) + if (adjs->get_value (behavColumns.addsetid) == i) { + adjs->set_value (behavColumns.badd, moptions.baBehav[i]==1); + adjs->set_value (behavColumns.bset, moptions.baBehav[i]!=1); + break; + } + } + addc.block (false); + setc.block (false); + + dmconn.block (false); + tconn.block (false); +} + +void Preferences::loadPressed () { + + moptions.copyFrom (&options); + fillPreferences (); +} + +void Preferences::savePressed () { + + storePreferences (); + options.copyFrom (&moptions); + Options::save (); +} + +void Preferences::okPressed () { + + storePreferences (); + options.copyFrom (&moptions); + hide (); +} + +void Preferences::cancelPressed () { + + hide (); +} + +void Preferences::selectStartupDir () { + + Gtk::FileChooserDialog dialog(M("PREFERENCES_DIRSELECTDLG"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER); +// dialog.set_transient_for(*this); + + //Add response buttons the the dialog: + dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); + dialog.add_button(Gtk::StockID("gtk-open"), Gtk::RESPONSE_OK); + + int result = dialog.run(); + + if (result==Gtk::RESPONSE_OK) + startupdir->set_text (dialog.get_filename()); +} + +void Preferences::dmethodChanged () { + + if (dmethod->get_active_row_number()==0) + ccSteps->set_value (2); + else if (dmethod->get_active_row_number()==1) + ccSteps->set_value (1); + else if (dmethod->get_active_row_number()==2) + ccSteps->set_value (2); + + if (dmethod->get_active_row_number()==4) { + dcbEnhance->set_sensitive(true); + dcbIterations->set_sensitive(true); + dcbIterationsLabel->set_sensitive(true); + } else { + dcbEnhance->set_sensitive(false); + dcbIterations->set_sensitive(false); + dcbIterationsLabel->set_sensitive(false); + } +} + +void Preferences::aboutPressed () { + + Splash* splash = new Splash (-1); + splash->set_transient_for (*this); + splash->set_modal (true); + splash->show (); +} +void Preferences::themeChanged () { + + std::vector files; + files.push_back (argv0+"/themes/"+theme->get_active_text ()); + Gtk::RC::set_default_files (files); + Gtk::RC::reparse_all (Gtk::Settings::get_default()); + GdkEventClient event = { GDK_CLIENT_EVENT, NULL, TRUE, gdk_atom_intern("_GTK_READ_RCFILES", FALSE), 8 }; + gdk_event_send_clientmessage_toall ((GdkEvent*)&event); +} + +void Preferences::addExtPressed () { + + Gtk::TreeNodeChildren c = extensionModel->children (); + for (int i=0; iget_text ()) + return; + + Gtk::TreeRow row = *(extensionModel->append()); + + row[extensionColumns.enabled] = true; + row[extensionColumns.ext] = extension->get_text (); +} + +void Preferences::delExtPressed () { + + extensionModel->erase (extensions->get_selection()->get_selected ()); +} + +void Preferences::clearProfilesPressed () { + + Gtk::MessageDialog md (*this, M("PREFERENCES_CLEARDLG_LINE1"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_NONE, true); + md.set_secondary_text (M("PREFERENCES_CLEARDLG_LINE2")); + md.set_title (M("PREFERENCES_CLEARDLG_TITLE")); + md.show_all (); + while (gtk_events_pending ()) gtk_main_iteration (); + cacheMgr.clearProfiles (); + md.hide (); +} + +void Preferences::clearThumbImagesPressed () { + + Gtk::MessageDialog md (*this, M("PREFERENCES_CLEARDLG_LINE1"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_NONE, true); + md.set_secondary_text (M("PREFERENCES_CLEARDLG_LINE2")); + md.set_title (M("PREFERENCES_CLEARDLG_TITLE")); + md.show_all (); + while (gtk_events_pending ()) gtk_main_iteration (); + cacheMgr.clearThumbImages (); + md.hide (); +} + +void Preferences::clearAllPressed () { + + Gtk::MessageDialog md (*this, M("PREFERENCES_CLEARDLG_LINE1"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_NONE, true); + md.set_secondary_text (M("PREFERENCES_CLEARDLG_LINE2")); + md.set_title (M("PREFERENCES_CLEARDLG_TITLE")); + md.show_all (); + while (gtk_events_pending ()) gtk_main_iteration (); + cacheMgr.clearAll (); + md.hide (); +} + diff --git a/rtgui/preferences.h b/rtgui/preferences.h new file mode 100644 index 000000000..ebf2d9956 --- /dev/null +++ b/rtgui/preferences.h @@ -0,0 +1,145 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef __PREFERENCES_H__ +#define __PREFERENCES_H__ + +#include +#include +#include +#include + +class Preferences : public Gtk::Dialog { + + class ExtensionColumns : public Gtk::TreeModel::ColumnRecord { + public: + Gtk::TreeModelColumn enabled; + Gtk::TreeModelColumn ext; + ExtensionColumns() { add(enabled); add(ext); } + }; + ExtensionColumns extensionColumns; + Glib::RefPtr extensionModel; + + + class BehavColumns : public Gtk::TreeModel::ColumnRecord { + public: + Gtk::TreeModelColumn label; + Gtk::TreeModelColumn badd; + Gtk::TreeModelColumn bset; + Gtk::TreeModelColumn visible; + Gtk::TreeModelColumn addsetid; + BehavColumns() { add(label); add(badd); add(bset); add(visible); add(addsetid); } + }; + Glib::RefPtr behModel; + BehavColumns behavColumns; + + + protected: + Gtk::ComboBoxText* rprofiles; + Gtk::ComboBoxText* iprofiles; + Gtk::ComboBoxText* dmethod; + Gtk::ComboBoxText* languages; + Gtk::Entry* dateformat; + Gtk::Entry* startupdir; + Gtk::RadioButton* sdcurrent; + Gtk::RadioButton* sdlast; + Gtk::RadioButton* sdhome; + Gtk::RadioButton* sdother; + Gtk::FileChooserButton* gimpDir; + Gtk::FileChooserButton* psDir; + Gtk::Entry* editorToSendTo; + Gtk::RadioButton* edGimp; + Gtk::RadioButton* edPS; + Gtk::RadioButton* edOther; + + + Gtk::CheckButton* showDateTime; + Gtk::CheckButton* showBasicExif; + + Gtk::SpinButton* ccSteps; + Gtk::Label* dcbIterationsLabel; + Gtk::SpinButton* dcbIterations; + Gtk::CheckButton* dcbEnhance; + Gtk::FileChooserButton* iccDir; + Gtk::FileChooserButton* monProfile; + + Gtk::CheckButton* blinkClipped; + Gtk::SpinButton* hlThresh; + Gtk::SpinButton* shThresh; + + Gtk::ComboBoxText* intent; + + Gtk::ComboBoxText* theme; + + Gtk::ComboBoxText* cformat; + Gtk::SpinButton* maxThumbSize; + Gtk::SpinButton* maxCacheEntries; + Gtk::Button* clearThumbnails; + Gtk::Button* clearProfiles; + Gtk::Button* clearAll; + Gtk::Entry* extension; + Gtk::TreeView* extensions; + Gtk::Button* addExt; + Gtk::Button* delExt; + Gtk::CheckButton* overlayedFileNames; + + Gtk::CheckButton* saveParamsFile; + Gtk::CheckButton* saveParamsCache; + Gtk::ComboBoxText* loadParamsPreference; + + Options moptions; + sigc::connection dmconn, tconn, addc, setc; + + void fillPreferences (); + void storePreferences (); + void parseDir (Glib::ustring dirname, std::vector& items, Glib::ustring ext); + void dmethodChanged (); + + void themeChanged (); + + void appendBehavList (Gtk::TreeModel::iterator& parent, Glib::ustring label, int id, bool set); + + Gtk::Widget* getProcParamsPanel (); + Gtk::Widget* getColorManagementPanel (); + Gtk::Widget* getFileBrowserPanel (); + Gtk::Widget* getGeneralPanel (); + Gtk::Widget* getBatchProcPanel (); + + public: + Preferences (int initialPage=0); + + void savePressed (); + void loadPressed (); + void okPressed (); + void cancelPressed (); + void aboutPressed (); + + void selectStartupDir (); + void addExtPressed (); + void delExtPressed (); + + void clearProfilesPressed (); + void clearThumbImagesPressed (); + void clearAllPressed (); + void behAddRadioToggled (const Glib::ustring& path); + void behSetRadioToggled (const Glib::ustring& path); +// void selectICCProfileDir (); +// void selectMonitorProfile (); +}; + +#endif diff --git a/rtgui/previewhandler.cc b/rtgui/previewhandler.cc new file mode 100644 index 000000000..421ebac9c --- /dev/null +++ b/rtgui/previewhandler.cc @@ -0,0 +1,234 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +PreviewHandler::PreviewHandler () : image(NULL) { + + pih = new PreviewHandlerIdleHelper; + pih->phandler = this; + pih->destroyed = false; + pih->pending = 0; +}; + +PreviewHandler::~PreviewHandler () { + + if (pih->pending) + pih->destroyed = true; + else + delete pih; +}; + +//----------------previewimagelistener functions-------------------- + +struct iaimgpar { + IImage8* image; + PreviewHandlerIdleHelper* pih; + double scale; + CropParams cp; +}; + +int iasetimage (void* data) { + + gdk_threads_enter (); + + iaimgpar* iap = (iaimgpar*)data; + PreviewHandlerIdleHelper* pih = iap->pih; + + if (pih->destroyed) { + if (pih->pending == 1) + delete pih; + else + pih->pending--; + delete iap; + gdk_threads_leave (); + return 0; + } + + if (pih->phandler->image) { + IImage8* temp = pih->phandler->image; + temp->getMutex().lock (); + pih->phandler->image = iap->image; + temp->getMutex().unlock (); + } + else + pih->phandler->image = iap->image; + pih->phandler->cropParams = iap->cp; + pih->phandler->previewScale = iap->scale; + pih->pending--; + delete iap; + + gdk_threads_leave (); + + return 0; +} + +void PreviewHandler::setImage (rtengine::IImage8* i, double scale, rtengine::procparams::CropParams cp) { + + pih->pending++; + + iaimgpar* iap = new iaimgpar; + iap->image = i; + iap->pih = pih; + iap->scale = scale; + iap->cp = cp; + + g_idle_add (iasetimage, iap); +} + +int iadelimage (void* data) { + + gdk_threads_enter (); + + iaimgpar* iap = (iaimgpar*)data; + PreviewHandlerIdleHelper* pih = iap->pih; + + if (pih->destroyed) { + if (pih->pending == 1) + delete pih; + else + pih->pending--; + delete iap; + gdk_threads_leave (); + return 0; + } + + if (pih->phandler->image) { + IImage8* temp = pih->phandler->image; + temp->getMutex().lock (); + pih->phandler->image = NULL; + temp->getMutex().unlock (); + } + iap->image->free (); + pih->phandler->previewImgMutex.lock (); + pih->phandler->previewImg.clear (); + pih->phandler->previewImgMutex.unlock (); + + pih->pending--; + delete iap; + + gdk_threads_leave (); + + return 0; +} + +void PreviewHandler::delImage (IImage8* i) { + + pih->pending++; + + iaimgpar* iap = new iaimgpar; + iap->image = i; + iap->pih = pih; + + g_idle_add (iadelimage, iap); +} + +int imready (void* data) { + + gdk_threads_enter (); + + iaimgpar* iap = (iaimgpar*)data; + PreviewHandlerIdleHelper* pih = iap->pih; + + if (pih->destroyed) { + if (pih->pending == 1) + delete pih; + else + pih->pending--; + delete iap; + gdk_threads_leave (); + return 0; + } + + pih->phandler->previewImgMutex.lock (); + pih->phandler->previewImg = Gdk::Pixbuf::create_from_data (pih->phandler->image->getData(), Gdk::COLORSPACE_RGB, false, 8, pih->phandler->image->getWidth(), pih->phandler->image->getHeight(), 3*pih->phandler->image->getWidth()); + pih->phandler->previewImgMutex.unlock (); + pih->phandler->cropParams = iap->cp; + pih->phandler->previewImageChanged (); + pih->pending--; + delete iap; + + gdk_threads_leave (); + + return 0; +} + +void PreviewHandler::imageReady (CropParams cp) { + + pih->pending++; + iaimgpar* iap = new iaimgpar; + iap->pih = pih; + iap->cp = cp; + g_idle_add (imready, iap); +} + +Glib::RefPtr PreviewHandler::getRoughImage (int x, int y, int w, int h, double zoom) { + + Glib::RefPtr resPixbuf; + previewImgMutex.lock (); + if (previewImg) { + double totalZoom = zoom*previewScale; + if (w>previewImg->get_width()*totalZoom) + w = image->getWidth()*totalZoom; + if (h>previewImg->get_height()*totalZoom) + h = image->getHeight()*totalZoom; + int ix = x*zoom; + int iy = y*zoom; + if (ix<0) + ix = 0; + if (iy<0) + iy = 0; + if ((ix+w)/totalZoom>previewImg->get_width()) + ix = previewImg->get_width()*totalZoom - w; + if ((iy+h)/totalZoom>previewImg->get_height()) + iy = previewImg->get_height()*totalZoom - h; + + resPixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, w, h); + previewImg->scale (resPixbuf, 0, 0, w, h, -ix, -iy, totalZoom, totalZoom, Gdk::INTERP_NEAREST); + } + previewImgMutex.unlock (); + return resPixbuf; +} + +Glib::RefPtr PreviewHandler::getRoughImage (int desiredW, int desiredH, double& zoom_) { + + Glib::RefPtr resPixbuf; + previewImgMutex.lock (); + if (previewImg) { + double zoom1 = (double)desiredW / previewImg->get_width(); + double zoom2 = (double)desiredH / previewImg->get_height(); + double zoom = zoom1getWidth()*zoom, image->getHeight()*zoom); + previewImg->scale (resPixbuf, 0, 0, previewImg->get_width()*zoom, previewImg->get_height()*zoom, 0, 0, zoom, zoom, Gdk::INTERP_NEAREST); + zoom_ = zoom / previewScale; + } + previewImgMutex.unlock (); + return resPixbuf; +} + +void PreviewHandler::previewImageChanged () { + + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->previewImageChanged (); +} diff --git a/rtgui/previewhandler.h b/rtgui/previewhandler.h new file mode 100644 index 000000000..677ad5d3f --- /dev/null +++ b/rtgui/previewhandler.h @@ -0,0 +1,76 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _PREVIEWHANDLER_ +#define _PREVIEWHANDLER_ + +#include +#include +#include + +class PreviewListener { + + public: + virtual void previewImageChanged () {} +}; + +class PreviewHandler; +struct PreviewHandlerIdleHelper { + PreviewHandler* phandler; + bool destroyed; + int pending; +}; + +class PreviewHandler : public rtengine::PreviewImageListener { + + friend int iasetimage (void* data); + friend int iadelimage (void* data); + friend int imready (void* data); + + protected: + rtengine::IImage8* image; + rtengine::procparams::CropParams cropParams; + double previewScale; + PreviewHandlerIdleHelper* pih; + std::list listeners; + Glib::Mutex previewImgMutex; + Glib::RefPtr previewImg; + + + public: + + PreviewHandler (); + ~PreviewHandler (); + + void addPreviewImageListener (PreviewListener* l) { listeners.push_back (l); } + + // previewimagelistener + void setImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cp); + void delImage (rtengine::IImage8* img); + void imageReady (rtengine::procparams::CropParams cp); + + // this function is called when a new preview image arrives from rtengine + void previewImageChanged (); + + // with this function it is possible to ask for a rough approximation of a (possibly zoomed) crop of the image + Glib::RefPtr getRoughImage (int x, int y, int w, int h, double zoom); + Glib::RefPtr getRoughImage (int desiredW, int desiredH, double& zoom); + rtengine::procparams::CropParams getCropParams () { return cropParams; } +}; + +#endif diff --git a/rtgui/previewwindow.cc b/rtgui/previewwindow.cc new file mode 100644 index 000000000..9c3d647dd --- /dev/null +++ b/rtgui/previewwindow.cc @@ -0,0 +1,212 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +PreviewWindow::PreviewWindow () : previewHandler(NULL), mainCropWin(NULL), isMoving(false) { + + rconn = signal_size_allocate().connect( sigc::mem_fun(*this, &PreviewWindow::on_resized) ); +} + +PreviewWindow::~PreviewWindow () { + + delete cCropMoving; +#ifndef WIN32 + delete cNormal; +#endif +} + +void PreviewWindow::on_realize () { + + Gtk::DrawingArea::on_realize (); + add_events(Gdk::EXPOSURE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::SCROLL_MASK); + cCropMoving = new Gdk::Cursor (Gdk::FLEUR); +#ifdef _WIN32 + cNormal = new Gdk::Cursor (Gdk::LAST_CURSOR); +#else + cNormal = new Gdk::Cursor (Gdk::ARROW); +#endif +} + +void PreviewWindow::getObservedFrameArea (int& x, int& y, int& w, int& h) { + + if (mainCropWin) { + int cropX, cropY, cropW, cropH; + mainCropWin->getCropRectangle (cropX, cropY, cropW, cropH); + // translate it to screen coordinates + x = imgX + cropX*zoom; + y = imgY + cropY*zoom; + w = cropW * zoom; + h = cropH * zoom; + } +} + +void PreviewWindow::updatePreviewImage () { + + int W = get_width(), H = get_height(); + backBuffer = Gdk::Pixmap::create (get_window(), W, H, -1); + backBuffer->draw_rectangle (get_style()->get_base_gc(Gtk::STATE_NORMAL), true, 0, 0, W, H); + if (previewHandler) { + Glib::RefPtr resPixbuf = previewHandler->getRoughImage (W, H, zoom); + if (resPixbuf) { + imgW = resPixbuf->get_width(); + imgH = resPixbuf->get_height(); + imgX = (W-imgW)/2; + imgY = (H-imgH)/2; + backBuffer->draw_pixbuf (get_style()->get_base_gc(Gtk::STATE_NORMAL), resPixbuf, 0, 0, imgX, imgY, -1, -1, Gdk::RGB_DITHER_NONE, 0, 0); + Cairo::RefPtr cr = backBuffer->create_cairo_context(); + if (previewHandler->getCropParams().enabled) + drawCrop (cr, imgX, imgY, imgW, imgH, 0, 0, zoom, previewHandler->getCropParams()); + } + } +} + +void PreviewWindow::setPreviewHandler (PreviewHandler* ph) { + + previewHandler = ph; + previewHandler->addPreviewImageListener (this); +} + +void PreviewWindow::on_resized (Gtk::Allocation& req) { + + updatePreviewImage (); + queue_draw (); +} + +bool PreviewWindow::on_expose_event (GdkEventExpose* event) { + + if (backBuffer) { + Glib::RefPtr window = get_window(); + + int bufferW, bufferH; + backBuffer->get_size (bufferW, bufferH); + + if (!mainCropWin) { + mainCropWin = imageArea->getMainCropWindow (); + if (mainCropWin) + mainCropWin->addCropWindowListener (this); + } + + if (get_width()!=bufferW && get_height()!=bufferH) + updatePreviewImage (); + + window->draw_drawable (get_style()->get_base_gc(Gtk::STATE_NORMAL), backBuffer, 0, 0, 0, 0, -1, -1); + + if (mainCropWin) { + Cairo::RefPtr cr = get_window()->create_cairo_context(); + int x, y, w, h; + getObservedFrameArea (x, y, w, h); + cr->set_source_rgb (1.0, 1.0, 1.0); + cr->set_line_width (3); + cr->rectangle (x-1.5, y-1.5, w+2, h+2); + cr->stroke (); + cr->set_source_rgb (1.0, 0.0, 0.0); + cr->set_line_width (1); + cr->rectangle (x-1.5, y-1.5, w+2, h+2); + cr->stroke (); + } + } + return true; +} + +void PreviewWindow::previewImageChanged () { + + updatePreviewImage (); + queue_draw (); +} + +void PreviewWindow::setImageArea (ImageArea* ia) { + + imageArea = ia; + mainCropWin = ia->getMainCropWindow (); + if (mainCropWin) + mainCropWin->addCropWindowListener (this); +} + +void PreviewWindow::cropPositionChanged (CropWindow* w) { + + queue_draw (); +} + +void PreviewWindow::cropWindowSizeChanged (CropWindow* w) { + + queue_draw (); +} + +void PreviewWindow::cropZoomChanged (CropWindow* w) { + + queue_draw (); +} + +bool PreviewWindow::on_motion_notify_event (GdkEventMotion* event) { + + if (!mainCropWin) + return true; + + int x, y, w, h; + getObservedFrameArea (x, y, w, h); + bool inside = event->x > x-6 && event->x < x+w-1+6 && event->y > y-6 && event->y < y+h-1+6; + bool moreInside = event->x > x+6 && event->x < x+w-1-6 && event->y > y+6 && event->y < y+h-1-6; + + if (isMoving) + mainCropWin->remoteMove ((event->x - press_x)/zoom, (event->y - press_y)/zoom); + else if (inside && !moreInside) + get_window()->set_cursor (*cCropMoving); + else + get_window()->set_cursor (*cNormal); + +} + +bool PreviewWindow::on_button_press_event (GdkEventButton* event) { + + if (!mainCropWin) + return true; + + int x, y, w, h; + getObservedFrameArea (x, y, w, h); + bool inside = event->x > x-6 && event->x < x+w-1+6 && event->y > y-6 && event->y < y+h-1+6; + bool moreInside = event->x > x+6 && event->x < x+w-1-6 && event->y > y+6 && event->y < y+h-1-6; + + if (!isMoving) { + isMoving = true; + if (!inside || moreInside) { + mainCropWin->remoteMove ((event->x - (x+w/2))/zoom, (event->y - (y+h/2))/zoom); + press_x = x+w/2; + press_y = y+h/2; + } + else { + press_x = event->x; + press_y = event->y; + } + get_window()->set_cursor (*cCropMoving); + } +} + +bool PreviewWindow::on_button_release_event (GdkEventButton* event) { + + if (!mainCropWin) + return true; + + if (isMoving) { + isMoving = false; + get_window()->set_cursor (*cNormal); + mainCropWin->remoteMoveReady (); + } +} diff --git a/rtgui/previewwindow.h b/rtgui/previewwindow.h new file mode 100644 index 000000000..c3fcdb8d0 --- /dev/null +++ b/rtgui/previewwindow.h @@ -0,0 +1,68 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _PREVIEWWINDOW_ +#define _PREVIEWWINDOW_ + +#include +#include +#include + +class PreviewWindow : public Gtk::DrawingArea, public PreviewListener, public CropWindowListener { + + private: + Glib::RefPtr backBuffer; + int oldwidth, oldheight; + PreviewHandler* previewHandler; + sigc::connection rconn; + CropWindow* mainCropWin; + ImageArea* imageArea; + int imgX, imgY, imgW, imgH; + double zoom; + Gdk::Cursor* cCropMoving; + Gdk::Cursor* cNormal; + int press_x, press_y; + bool isMoving; + + void updatePreviewImage (); + void getObservedFrameArea (int& x, int& y, int& w, int& h); + + public: + PreviewWindow (); + ~PreviewWindow (); + + void setPreviewHandler (PreviewHandler* ph); + void setImageArea (ImageArea* ia); + + void on_realize (); + void on_resized (Gtk::Allocation& req); + bool on_expose_event (GdkEventExpose* event); + bool on_motion_notify_event (GdkEventMotion* event); + bool on_button_press_event (GdkEventButton* event); + bool on_button_release_event(GdkEventButton* event); + + // PreviewListener interface + void previewImageChanged (); + + // CropWindowListener interface + void cropPositionChanged (CropWindow* w); + void cropWindowSizeChanged (CropWindow* w); + void cropZoomChanged (CropWindow* w); +}; + +#endif diff --git a/rtgui/procparamchangers.h b/rtgui/procparamchangers.h new file mode 100644 index 000000000..6de1c5e21 --- /dev/null +++ b/rtgui/procparamchangers.h @@ -0,0 +1,24 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#define UNKNOWN -1 +#define FILEBROWSER 1 +#define EDITOR 2 +#define BATCHEDITOR 3 +#define CACHEMGR 4 +#define SAFETYUPDATE 5 diff --git a/rtgui/procthread.h b/rtgui/procthread.h new file mode 100644 index 000000000..f992899b4 --- /dev/null +++ b/rtgui/procthread.h @@ -0,0 +1,78 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _PROCTHREAD_ +#define _PROCTHREAD_ + +#include + +template +class ProcessingThread { + + protected: + bool tostop; + bool stopped; + std::list jqueue; + Glib::Thread* thread; + bool fifo; + + public: + ProcessingThread () : tostop(false), stopped(true), fifo(true) {} + void init () { tostop = false; stopped = true; } + void add (T de) { jqueue.push_back (de); } + void removejobs () { while (!jqueue.empty()) jqueue.pop_front (); } + void stop () { if (stopped) { tostop = true; return; } gdk_threads_leave(); tostop = true; Glib::Thread::self()->yield(); if (!stopped) thread->join (); gdk_threads_enter();} + + virtual void start () {} + virtual void process (T& e) {} + virtual void processCustomOrder () {} + virtual void end () {} + + void process () { + if (stopped) + #undef THREAD_PRIORITY_NORMAL + thread = Glib::Thread::create(sigc::mem_fun(*this, &ProcessingThread::process_), (unsigned long int)0, true, true, Glib::THREAD_PRIORITY_NORMAL); + } + void process_ () { + stopped = false; + tostop = false; + + start (); // jqueue.sort (); + + + while (!tostop && !jqueue.empty ()) { + if (fifo) { + T current = jqueue.front (); + jqueue.pop_front (); + process (current); + } + else + processCustomOrder (); + } + stopped = true; + end (); + } + + bool runs () { return !stopped; } + + void terminate () { stop (); removejobs (); } + + int numOfJobs () { return jqueue.size(); } +}; + +#endif diff --git a/rtgui/profilechangelistener.h b/rtgui/profilechangelistener.h new file mode 100644 index 000000000..a57ad4d88 --- /dev/null +++ b/rtgui/profilechangelistener.h @@ -0,0 +1,33 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _PROFILECHANGELISTENER_ +#define _PROFILECHANGELISTENER_ + +#include +#include + +class ProfileChangeListener { + + public: + virtual void profileChange (const rtengine::procparams::ProcParams* nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited=NULL) {} + virtual void setDefaults (rtengine::procparams::ProcParams* defparams) {} +}; + +#endif + diff --git a/rtgui/profilepanel.cc b/rtgui/profilepanel.cc new file mode 100644 index 000000000..5849f885d --- /dev/null +++ b/rtgui/profilepanel.cc @@ -0,0 +1,385 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +extern Glib::ustring argv0; + +ProfilePanel::ProfilePanel () { + + tpc = NULL; + + profiles = Gtk::manage (new Gtk::ComboBoxText ()); + Gtk::HBox* hbox = Gtk::manage (new Gtk::HBox ()); + hbox->show (); +// pack_start (*profiles, Gtk::PACK_SHRINK, 4); + + pack_start (*hbox, Gtk::PACK_SHRINK, 4); + + save = Gtk::manage (new Gtk::Button ()); + save->add (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-save"), Gtk::ICON_SIZE_BUTTON))); + load = Gtk::manage (new Gtk::Button ()); + load->add (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-open"), Gtk::ICON_SIZE_BUTTON))); + copy = Gtk::manage (new Gtk::Button ()); + copy->add (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-copy"), Gtk::ICON_SIZE_BUTTON))); + paste = Gtk::manage (new Gtk::Button ()); + paste->add (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-paste"), Gtk::ICON_SIZE_BUTTON))); + + hbox->pack_start (*profiles); + hbox->pack_start (*load, Gtk::PACK_SHRINK, 1); + hbox->pack_start (*save, Gtk::PACK_SHRINK, 1); + hbox->pack_start (*copy, Gtk::PACK_SHRINK, 1); + hbox->pack_start (*paste, Gtk::PACK_SHRINK, 1); + + load->signal_clicked().connect( sigc::mem_fun(*this, &ProfilePanel::load_clicked) ); + save->signal_clicked().connect( sigc::mem_fun(*this, &ProfilePanel::save_clicked) ); + copy->signal_clicked().connect( sigc::mem_fun(*this, &ProfilePanel::copy_clicked) ); + paste->signal_clicked().connect( sigc::mem_fun(*this, &ProfilePanel::paste_clicked) ); + + custom = NULL; + lastphoto = NULL; + lastsaved = NULL; + dontupdate = false; + + refreshProfileList (); + + profiles->set_active (0); + old = profiles->get_active_text(); + changeconn = profiles->signal_changed().connect( sigc::mem_fun(*this, &ProfilePanel::selection_changed) ); + + save->set_tooltip_text (M("PROFILEPANEL_TOOLTIPSAVE")); + load->set_tooltip_text (M("PROFILEPANEL_TOOLTIPLOAD")); + copy->set_tooltip_text (M("PROFILEPANEL_TOOLTIPCOPY")); + paste->set_tooltip_text (M("PROFILEPANEL_TOOLTIPPASTE")); + + show_all_children (); +} + +ProfilePanel::~ProfilePanel () { + + delete custom; + delete lastsaved; + delete lastphoto; +} + +void ProfilePanel::refreshProfileList () { + + Glib::ustring oldsel = profiles->get_active_text (); + changeconn.block (true); + + // clear items + profiles->clear_items (); + pparams.clear (); + + // re-parse profile directories (deletes old ones) + profileStore.parseProfiles (); + pparams = profileStore.getProfileNames (); + for (int i=0; iappend_text (pparams[i]); + + if (custom) + profiles->append_text (Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")"); + if (lastsaved) + profiles->append_text (Glib::ustring("(") + M("PROFILEPANEL_PLASTSAVED") + ")"); + if (lastphoto) + profiles->append_text (Glib::ustring("(") + M("PROFILEPANEL_PLASTPHOTO") + ")"); + + profiles->set_active_text (oldsel); + changeconn.block (false); +} + +void ProfilePanel::save_clicked () { + + Gtk::FileChooserDialog dialog(M("PROFILEPANEL_SAVEDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_SAVE); + if (options.multiUser) + dialog.set_current_folder (Options::rtdir + "/" + options.profilePath); + else + dialog.set_current_folder (argv0 + "/" + options.profilePath); + + //Add response buttons the the dialog: + dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); + dialog.add_button(Gtk::StockID("gtk-save"), Gtk::RESPONSE_OK); + + //Add filters, so that only certain file types can be selected: + + Gtk::FileFilter filter_pp; + filter_pp.set_name(M("PROFILEPANEL_FILEDLGFILTERPP")); + filter_pp.add_pattern("*.pp2"); + dialog.add_filter(filter_pp); + + Gtk::FileFilter filter_any; + filter_any.set_name(M("PROFILEPANEL_FILEDLGFILTERANY")); + filter_any.add_pattern("*"); + dialog.add_filter(filter_any); + +// dialog.set_do_overwrite_confirmation (true); + + savedialog = &dialog; + + int result = dialog.run(); + + if (result==Gtk::RESPONSE_OK) { + + std::string fname = dialog.get_filename(); + + bool hasext = true; + int dotpos = fname.find_last_of ('.'); + if (dotpos==Glib::ustring::npos) + hasext = false; + int dirpos1 = fname.find_last_of ('/'); + if (dirpos1!=Glib::ustring::npos && dirpos1>dotpos) + hasext = false; + int dirpos2 = fname.find_last_of ('\\'); + if (dirpos2!=Glib::ustring::npos && dirpos2>dotpos) + hasext = false; + + if (!hasext) + fname = fname + ".pp2"; + + if (Glib::file_test (fname, Glib::FILE_TEST_EXISTS)) { + Glib::ustring msg_ = Glib::ustring("") + fname + ": " + M("MAIN_MSG_ALREADYEXISTS") + "\n" + M("MAIN_MSG_QOVERWRITE") + ""; + Gtk::MessageDialog msgd (msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); + int response = msgd.run (); + if (response==Gtk::RESPONSE_NO) + return; + } + + ProcParams* toSave = NULL; + if (profiles->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")") + toSave = custom; + else if (profiles->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PLASTSAVED") + ")") + toSave = lastsaved; + else if (profiles->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PLASTPHOTO") + ")") + toSave = lastphoto; + else + toSave = profileStore.getProfile (profiles->get_active_text()); + + if (toSave) { + toSave->save (fname); + refreshProfileList (); + } + } +} + +void ProfilePanel::copy_clicked () { + + ProcParams* toSave = NULL; + if (profiles->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")") + toSave = custom; + else if (profiles->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PLASTSAVED") + ")") + toSave = lastsaved; + else if (profiles->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PLASTPHOTO") + ")") + toSave = lastphoto; + else + toSave = profileStore.getProfile (profiles->get_active_text()); + + if (toSave) + clipboard.setProcParams (*toSave); +} + +void ProfilePanel::load_clicked () { + + Gtk::FileChooserDialog dialog(M("PROFILEPANEL_LOADDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN); + if (options.multiUser) + dialog.set_current_folder (Options::rtdir + "/" + options.profilePath); + else + dialog.set_current_folder (argv0 + "/" + options.profilePath); + + //Add response buttons the the dialog: + dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); + dialog.add_button(Gtk::StockID("gtk-open"), Gtk::RESPONSE_OK); + + //Add filters, so that only certain file types can be selected: + + Gtk::FileFilter filter_pp; + filter_pp.set_name(M("PROFILEPANEL_FILEDLGFILTERPP")); + filter_pp.add_pattern("*.pp2"); + dialog.add_filter(filter_pp); + + Gtk::FileFilter filter_any; + filter_any.set_name(M("PROFILEPANEL_FILEDLGFILTERANY")); + filter_any.add_pattern("*"); + dialog.add_filter(filter_any); + + int result = dialog.run(); + + if (result==Gtk::RESPONSE_OK) { + if (!custom) { + custom = new ProcParams (); + profiles->append_text (Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")"); + } + custom->load (dialog.get_filename()); + profiles->set_active_text (Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")"); + old = profiles->get_active_text(); + changeTo (custom, M("PROFILEPANEL_PFILE")); + } +} + +void ProfilePanel::paste_clicked () { + + if (!clipboard.hasProcParams()) + return; + + if (!custom) { + custom = new ProcParams (); + profiles->append_text (Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")"); + } + *custom = clipboard.getProcParams (); + profiles->set_active_text (Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")"); + old = profiles->get_active_text(); + changeTo (custom, M("HISTORY_FROMCLIPBOARD")); +} + +void ProfilePanel::changeTo (ProcParams* newpp, Glib::ustring profname) { + + if (!newpp) + return; + + // Keep transformation parameters while changing the profile + +/* int cropx = working->crop_x; + int cropy = working->crop_y; + int cropw = working->crop_w; + int croph = working->crop_h; + bool crope = working->crop_enabled; + int rotcor = working->rotate_coarse; + double rotfine = working->rotate_fine; + double lenscorr = working->lens_distortion; + bool hflip = working->horizontal_flip; + bool vflip = working->vertical_flip; + + working->copy (newpp); + + working->crop_x = cropx; + working->crop_y = cropy; + working->crop_w = cropw; + working->crop_h = croph; + working->crop_enabled = crope; + working->rotate_coarse = rotcor; + working->rotate_fine = rotfine; + working->lens_distortion = lenscorr; + working->horizontal_flip = hflip; + working->vertical_flip = vflip; +*/ + if (tpc) + tpc->profileChange (newpp, EvProfileChanged, profname); +} + +void ProfilePanel::selection_changed () { + + if (profiles->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")") { + if (!dontupdate) + changeTo (custom, Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")"); + } + else if (profiles->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PLASTSAVED") + ")") + changeTo (lastsaved, Glib::ustring("(") + M("PROFILEPANEL_PLASTSAVED") + ")"); + else if (profiles->get_active_text() == Glib::ustring("(") + M("PROFILEPANEL_PLASTPHOTO") + ")") + changeTo (lastphoto, Glib::ustring("(") + M("PROFILEPANEL_PLASTPHOTO") + ")"); + else { + ProcParams* s = profileStore.getProfile (profiles->get_active_text()); + if (s) + changeTo (s, profiles->get_active_text()); + } + old = profiles->get_active_text (); + dontupdate = false; +} + +void ProfilePanel::procParamsChanged (rtengine::procparams::ProcParams* p, rtengine::ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited) { + + // to prevent recursion filter out the events caused by the profilepanel + if (ev==EvProfileChanged || ev==EvPhotoLoaded) + return; + + if (profiles->get_active_text() != Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")") { + dontupdate = true; + if (!custom) { + custom = new ProcParams (); + profiles->append_text (Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")"); + } + *custom = *p; + profiles->set_active_text (Glib::ustring("(") + M("PROFILEPANEL_PCUSTOM") + ")"); + old = profiles->get_active_text(); + } + else + *custom = *p; +} + +void ProfilePanel::initProfile (const Glib::ustring& profname, ProcParams* lastSaved, ProcParams* lastPhoto) { + + changeconn.block (true); + + profiles->clear_items (); + pparams.clear (); + + pparams = profileStore.getProfileNames (); + for (int i=0; iappend_text (pparams[i]); + + delete custom; + custom = NULL; + delete lastsaved; + lastsaved = lastSaved; + delete lastphoto; + lastphoto = lastPhoto; + + Glib::ustring defline = profname; + ProcParams* defprofile = profileStore.getProfile (profname); + + if (lastphoto) + profiles->append_text (Glib::ustring("(") + M("PROFILEPANEL_PLASTPHOTO") + ")"); + + if (lastsaved) { + defline = Glib::ustring("(") + M("PROFILEPANEL_PLASTSAVED") + ")"; + defprofile = lastsaved; + profiles->append_text (Glib::ustring("(") + M("PROFILEPANEL_PLASTSAVED") + ")"); + } + + if (tpc) { + if (lastsaved) + tpc->setDefaults (lastsaved); + else + tpc->setDefaults (profileStore.getProfile (profname)); + } + if (defprofile) { + old = defline; + profiles->set_active_text (defline); + changeconn.block (false); + if (tpc) + tpc->profileChange (defprofile, EvPhotoLoaded, defline); + } + else { + // select first valid profile + old = ""; + profiles->set_active (0); + ProcParams* s = profileStore.getProfile (profiles->get_active_text()); + if (!s) + s = new ProcParams (); + changeconn.block (false); + if (tpc) + tpc->profileChange (s, EvPhotoLoaded, profiles->get_active_text()); + } +} + + diff --git a/rtgui/profilepanel.h b/rtgui/profilepanel.h new file mode 100644 index 000000000..2009aad8b --- /dev/null +++ b/rtgui/profilepanel.h @@ -0,0 +1,70 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _PROFILEPANEL_ +#define _PROFILEPANEL_ + +#include +#include +#include +#include +#include + +class ProfilePanel : public Gtk::VBox, public PParamsChangeListener { + + protected: + + Gtk::Button* save; + Gtk::Button* load; + Gtk::Button* copy; + Gtk::Button* paste; + Gtk::ComboBoxText* profiles; + std::vector pparams; + rtengine::procparams::ProcParams* custom; + rtengine::procparams::ProcParams* lastsaved; + rtengine::procparams::ProcParams* lastphoto; + Glib::ustring old; + ProfileChangeListener* tpc; + bool dontupdate; + sigc::connection changeconn; + Gtk::FileChooserDialog* savedialog; + + void changeTo (rtengine::procparams::ProcParams* newpp, Glib::ustring profname); + void refreshProfileList (); + + public: + + ProfilePanel (); + virtual ~ProfilePanel (); + + void setProfileChangeListener (ProfileChangeListener* ppl) { tpc = ppl; } + + void initProfile (const Glib::ustring& profname, rtengine::procparams::ProcParams* lastSaved, rtengine::procparams::ProcParams* lastPhoto); + + // PParamsChangeListener interface + void procParamsChanged (rtengine::procparams::ProcParams* params, rtengine::ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited=NULL); + + // gui callbacks + void save_clicked (); + void load_clicked (); + void copy_clicked (); + void paste_clicked (); + void selection_changed (); +}; + +#endif diff --git a/rtgui/profilestore.cc b/rtgui/profilestore.cc new file mode 100644 index 000000000..95e632ffb --- /dev/null +++ b/rtgui/profilestore.cc @@ -0,0 +1,108 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +ProfileStore profileStore; + +using namespace rtengine; +using namespace rtengine::procparams; + +extern Glib::ustring argv0; + +void ProfileStore::parseProfiles () { + + // clear loaded profiles + for (std::map::iterator i = pparams.begin(); i!=pparams.end(); i++) + delete i->second; + pparams.clear (); + + if (options.multiUser) { + Glib::ustring userPD = options.rtdir + "/" + options.profilePath; + if (!Glib::file_test (userPD, Glib::FILE_TEST_IS_DIR)) + g_mkdir_with_parents (userPD.c_str(), 511); + parseDir (userPD); + } + parseDir (argv0 + "/" + options.profilePath); +} + +void ProfileStore::parseDir (const Glib::ustring& pdir) { + + // reload the available profiles from the profile dir + if (pdir!="") { + // process directory + Glib::ustring dirname = pdir; + Glib::Dir* dir = NULL; + try { + dir = new Glib::Dir (dirname); + } + catch (const Glib::FileError& fe) { + return; + } + dirname = dirname + "/"; + for (Glib::DirIterator i = dir->begin(); i!=dir->end(); ++i) { + Glib::ustring fname = dirname + *i; + Glib::ustring sname = *i; + // ignore directories + if (!Glib::file_test (fname, Glib::FILE_TEST_IS_DIR)) { + int lastdot = sname.find_last_of ('.'); + if (lastdot!=Glib::ustring::npos && lastdot<=sname.size()-4 && !sname.casefold().compare (lastdot, 4, ".pp2")) { + printf ("Processing file %s...\n", fname.c_str()); + Glib::ustring name = sname.substr(0,lastdot); + if (pparams.find(name)!=pparams.end()) { + delete pparams[name]; + pparams.erase (pparams.find(name)); + } + ProcParams* pp = new ProcParams (); + int res = pp->load (fname); + if (!res && pp->version>=220) + pparams[name] = pp; + else + delete pp; + } + } + } + delete dir; + } +} + +rtengine::procparams::ProcParams* ProfileStore::getProfile (const Glib::ustring& profname) { + + return pparams[profname]; +} + +std::vector ProfileStore::getProfileNames () { + + std::vector ret; + for (std::map::iterator i = pparams.begin(); i!=pparams.end(); i++) + ret.push_back (i->first); + return ret; +} + +rtengine::procparams::ProcParams* ProfileStore::getDefaultProcParams (bool isRaw) { + + rtengine::procparams::ProcParams* pp = getProfile (isRaw ? options.defProfRaw : options.defProfImg); + if (!pp) { + pp = new ProcParams (); + pparams[isRaw ? options.defProfRaw : options.defProfImg] = pp; + } + return pp; +} + diff --git a/rtgui/profilestore.h b/rtgui/profilestore.h new file mode 100644 index 000000000..d54b90498 --- /dev/null +++ b/rtgui/profilestore.h @@ -0,0 +1,42 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _PROFILESTORE_ +#define _PROFILESTORE_ + +#include +#include +#include +#include + +class ProfileStore { + + std::map pparams; + void parseDir (const Glib::ustring& pdir); + + public: + + void parseProfiles (); + rtengine::procparams::ProcParams* getProfile (const Glib::ustring& profname); + std::vector getProfileNames (); + rtengine::procparams::ProcParams* getDefaultProcParams (bool isRaw); +}; + +extern ProfileStore profileStore; + +#endif diff --git a/rtgui/progressdialog.cc b/rtgui/progressdialog.cc new file mode 100644 index 000000000..cc9df4c6b --- /dev/null +++ b/rtgui/progressdialog.cc @@ -0,0 +1,56 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include + +template +ProgressDialog::ProgressDialog (const sigc::slot0& slot) { + + set_deletable (false); + operation.connect (slot); +} + +template +void ProgressDialog::start () { + + T ret = operation.emit (); +} + +template +void ProgressDialog::finish () { + + gtk_threads_enter (); + hide (); + gtk_threads_leave (); +} + +template +void ProgressDialog::setProgress (double p) { +} + +template +void ProgressDialog::setProgressStr (Glib::ustring str) { +} + +template +void ProgressDialog::setProgressState (int state) { +} + +template +void ProgressDialog::error (Glib::ustring descr) { +} diff --git a/rtgui/progressdialog.h b/rtgui/progressdialog.h new file mode 100644 index 000000000..48076194d --- /dev/null +++ b/rtgui/progressdialog.h @@ -0,0 +1,128 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _PROGRESSDIALOG_ +#define _PROGRESSDIALOG_ + +#include +#include +#include + +#undef THREAD_PRIORITY_NORMAL + +class PLDBridge : public rtengine::ProgressListener { + + Gtk::Dialog* dialog; + Gtk::Label* label; + Gtk::ProgressBar* progBar; + + public: + PLDBridge (Gtk::Dialog* d, Gtk::Label* l, Gtk::ProgressBar* pb) + : dialog(d), label(l), progBar(pb) {} + + // progresslistener interface + void setProgress (double p) { + gdk_threads_enter (); + progBar->set_fraction (p); + gdk_threads_leave (); + } + void setProgressStr (Glib::ustring str) { + gdk_threads_enter (); + Glib::ustring progrstr; + if (str=="Decoding...") + progrstr = M("PROGRESSBAR_DECODING"); + else if (str=="Ready.") + progrstr = M("PROGRESSBAR_READY"); + else if (str=="Demosaicing...") + progrstr = M("PROGRESSBAR_DEMOSAICING"); + else if (str=="Loading...") + progrstr = M("PROGRESSBAR_LOADING"); + else if (str=="Loading PNG file...") + progrstr = M("PROGRESSBAR_LOADPNG"); + else if (str=="Loading JPEG file...") + progrstr = M("PROGRESSBAR_LOADJPEG"); + else if (str=="Loading TIFF file...") + progrstr = M("PROGRESSBAR_LOADTIFF"); + else if (str=="Saving PNG file...") + progrstr = M("PROGRESSBAR_SAVEPNG"); + else if (str=="Saving JPEG file...") + progrstr = M("PROGRESSBAR_SAVEJPEG"); + else if (str=="Saving TIFF file...") + progrstr = M("PROGRESSBAR_SAVETIFF"); + else if (str=="Processing...") + progrstr = M("PROGRESSBAR_PROCESSING"); + else + progrstr = str; + + label->set_text (progrstr); + gdk_threads_leave (); + } + void setProgressState (int state) {} + void error (Glib::ustring descr) {} +}; + +template +class ProgressDialog : public Gtk::Dialog { + + sigc::signal0 operation; + T* retval; + Gtk::Label prLabel; + Gtk::ProgressBar prProgBar; + + PLDBridge* pldBridge; + + + void workingThread () { + *retval = operation.emit (); + gdk_threads_enter (); + response (1); + gdk_threads_leave (); + } + + public: + + ProgressDialog (Glib::ustring label) : Gtk::Dialog (label, true) { + pldBridge = new PLDBridge (this, &prLabel, &prProgBar); + get_vbox()->pack_start (prLabel, Gtk::PACK_SHRINK, 4); + get_vbox()->pack_start (prProgBar, Gtk::PACK_SHRINK, 4); + set_size_request (300, -1); + show_all_children (); + } + + ~ProgressDialog () { + delete pldBridge; + } + + rtengine::ProgressListener* getProgressListener () { return pldBridge; } + + void setFunc (const sigc::slot0& slot, T* rv) { + retval = rv; + operation.connect (slot); + } + + void start () { + Glib::Thread *thread = Glib::Thread::create(sigc::mem_fun(*this, &ProgressDialog::workingThread), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + int x = run (); + if (x<0) { + gdk_threads_leave (); + thread->join (); + gdk_threads_enter (); + } + } +}; +#endif diff --git a/rtgui/quickzoomlistener.h b/rtgui/quickzoomlistener.h new file mode 100644 index 000000000..958e05302 --- /dev/null +++ b/rtgui/quickzoomlistener.h @@ -0,0 +1,34 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _QZLISTENER_ +#define _QZLISTENER_ + +class QuickZoomListener { + + public: + + virtual void increaseZoom () {} + virtual void decreaseZoom () {} + virtual void quickZoom () {} + virtual void increaseCropZoom () {} + virtual void decreaseCropZoom () {} + virtual void quickCropZoom () {} +}; + +#endif diff --git a/rtgui/recentbrowser.cc b/rtgui/recentbrowser.cc new file mode 100644 index 000000000..0cb7e3d1a --- /dev/null +++ b/rtgui/recentbrowser.cc @@ -0,0 +1,53 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +RecentBrowser::RecentBrowser () : listener (NULL) { + + recentDirs = Gtk::manage (new Gtk::ComboBoxText ()); + + Gtk::Frame* frame = Gtk::manage (new Gtk::Frame (M("MAIN_FRAME_RECENT"))); + frame->add (*recentDirs); + + pack_start (*frame, Gtk::PACK_SHRINK, 4); + + conn = recentDirs->signal_changed().connect(sigc::mem_fun(*this, &RecentBrowser::selectionChanged)); + + show_all (); +} + +void RecentBrowser::selectionChanged () { + + Glib::ustring sel = recentDirs->get_active_text (); + if (sel!="" && listener) + listener->selectDir (sel); +} + +void RecentBrowser::dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile) { + + conn.block (true); + + recentDirs->remove_text (dirname); + recentDirs->prepend_text (dirname); + recentDirs->set_active_text (dirname); + + conn.block (false); +} + diff --git a/rtgui/recentbrowser.h b/rtgui/recentbrowser.h new file mode 100644 index 000000000..0a267df63 --- /dev/null +++ b/rtgui/recentbrowser.h @@ -0,0 +1,45 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _RECENTBROWSER_ +#define _RECENTBROWSER_ + +#include +#include +#include +#include + +class RecentBrowser : public Gtk::VBox, public DirSelectionListener { + + Gtk::ComboBoxText* recentDirs; + sigc::connection conn; + DirBrowserRemoteInterface* listener; + + public: + + RecentBrowser (); + + void setDirBrowserRemoteInterface (DirBrowserRemoteInterface* l) { listener = l; } + + void selectionChanged (); + void dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile=""); +}; + +#endif + + diff --git a/rtgui/recentselectionlistener.h b/rtgui/recentselectionlistener.h new file mode 100644 index 000000000..c1e865bd1 --- /dev/null +++ b/rtgui/recentselectionlistener.h @@ -0,0 +1,30 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _RECENTSELECTIONLISTENER_ +#define _RECENTSELECTIONLISTENER_ + +#include + +class RecentSelectionListener { + + public: + virtual void recentSelected (Glib::ustring recentdir) {} +}; + +#endif diff --git a/rtgui/renamedlg.cc b/rtgui/renamedlg.cc new file mode 100644 index 000000000..29c25f982 --- /dev/null +++ b/rtgui/renamedlg.cc @@ -0,0 +1,215 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +RenameDialog::RenameDialog (Gtk::Window* parent) + : Gtk::Dialog (M("FILEBROWSER_RENAMEDLGLABEL"), *parent, true, true), imageData(NULL), p(parent) { + + Gtk::Table* names = Gtk::manage (new Gtk::Table (2, 2)); + Gtk::Label* onlab = Gtk::manage (new Gtk::Label (M("FILEBROWSER_CURRENT_NAME"))); + Gtk::Label* nnlab = Gtk::manage (new Gtk::Label (M("FILEBROWSER_NEW_NAME"))); + oldName = Gtk::manage (new Gtk::Label ("alma")); + newName = Gtk::manage (new Gtk::Entry ()); + + names->attach (*onlab, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + names->attach (*oldName, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + names->attach (*nnlab, 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + names->attach (*newName, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + get_vbox()->pack_start (*names, Gtk::PACK_SHRINK, 4); + + Gtk::HBox* tbox = Gtk::manage (new Gtk::HBox()); + useTmpl = Gtk::manage (new Gtk::CheckButton (M("FILEBROWSER_USETEMPLATE"))); + templates = Gtk::manage (new Gtk::ComboBox ()); + templateModel = Gtk::ListStore::create (templateColumns); + templates->set_model (templateModel); + templates->pack_start (templateColumns.tmplName); + + tbox->pack_start (*useTmpl, Gtk::PACK_SHRINK, 4); + tbox->pack_start (*templates); + + get_vbox()->pack_start (*tbox, Gtk::PACK_SHRINK, 4); + + add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK); + add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + all = add_button ("All", RESPONSE_ALL); + + newName->set_activates_default (true); + set_default_response (Gtk::RESPONSE_OK); + + fillTemplateList (); + + templates->set_row_separator_func (sigc::mem_fun(*this, &RenameDialog::rowSeparatorFunc)); + templates->signal_changed().connect(sigc::mem_fun(*this, &RenameDialog::tmplSelectionChanged)); + useTmpl->signal_toggled().connect( sigc::mem_fun(*this, &RenameDialog::useTemplToggled) ); + + useTmpl->set_active (options.renameUseTemplates); + + show_all_children (); +} + +void RenameDialog::initName (const Glib::ustring& iname, const CacheImageData* cid) { + + imageData = cid; + oldName->set_text (iname); + newName->set_text (iname); + if (useTmpl->get_active () && isTemplSelected ()) + newName->set_text (applyTemplate (iname, cid, getActiveTemplate())); + newName->select_region (0, newName->get_text().size()); +} + +Glib::ustring RenameDialog::getNewName () { + + return newName->get_text (); +} + +void RenameDialog::fillTemplateList () { + + templateModel->clear (); + + for (int i=0; iappend (); + iter->set_value (templateColumns.tmplName, options.renameTemplates[i]); + iter->set_value (templateColumns.rowSeparator, false); + } + // append separator and the manage... item + Gtk::TreeModel::iterator iter = templateModel->append (); + iter->set_value (templateColumns.tmplName, Glib::ustring("")); + iter->set_value (templateColumns.rowSeparator, true); + iter = templateModel->append (); + iter->set_value (templateColumns.tmplName, Glib::ustring(M("FILEBROWSER_ADDDELTEMPLATE"))); + iter->set_value (templateColumns.rowSeparator, false); +} + +bool RenameDialog::rowSeparatorFunc (const Glib::RefPtr& model, const Gtk::TreeModel::iterator& iter) { + + return iter->get_value (templateColumns.rowSeparator); +} + +void RenameDialog::useTemplToggled () { + + templates->set_sensitive (useTmpl->get_active ()); + if (useTmpl->get_active () && isTemplSelected ()) { + all->set_sensitive (true); + newName->set_text (applyTemplate (oldName->get_text(), imageData, getActiveTemplate())); + } + else + all->set_sensitive (false); + newName->select_region (0, newName->get_text().size()); +} + +bool RenameDialog::isTemplSelected () { + + Gtk::TreeModel::iterator iter = templates->get_active(); + return iter && iter->get_value (templateColumns.tmplName)!=M("FILEBROWSER_ADDDELTEMPLATE"); +} + +Glib::ustring RenameDialog::getActiveTemplate () { + + Gtk::TreeModel::iterator iter = templates->get_active(); + if (iter && iter->get_value (templateColumns.tmplName)!=M("FILEBROWSER_ADDDELTEMPLATE")) + return iter->get_value (templateColumns.tmplName); + else + return ""; +} + +void RenameDialog::tmplSelectionChanged () { + + Gtk::TreeModel::iterator iter = templates->get_active(); + if (iter && iter->get_value (templateColumns.tmplName)==M("FILEBROWSER_ADDDELTEMPLATE")) { + RenameTemplateEditor* rte = new RenameTemplateEditor (p); + if (rte->run()==Gtk::RESPONSE_OK) { + fillTemplateList (); + } + delete rte; + // show add/del template dialog + } + else + useTemplToggled (); +} + +RenameTemplateEditor::RenameTemplateEditor (Gtk::Window* parent) + : Gtk::Dialog ("Edit rename templates", *parent, true, true) { + + list = Gtk::manage (new Gtk::ListViewText (1, false, Gtk::SELECTION_MULTIPLE)); + list->set_headers_visible (false); + get_vbox ()->pack_start (*list); + + Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ()); + templ = Gtk::manage (new Gtk::Entry ()); + Gtk::Button* add = Gtk::manage (new Gtk::Button ()); + Gtk::Button* del = Gtk::manage (new Gtk::Button ()); + add->add (*Gtk::manage (new Gtk::Image (argv0+"/images/list-add12.png"))); + del->add (*Gtk::manage (new Gtk::Image (argv0+"/images/list-remove12r.png"))); + hb->pack_start (*templ); + hb->pack_start (*add, Gtk::PACK_SHRINK, 2); + hb->pack_start (*del, Gtk::PACK_SHRINK, 2); + + get_vbox ()->pack_start (*hb, Gtk::PACK_SHRINK, 4); + + add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK); + + refreshTemplateList (); + + add->signal_pressed().connect( sigc::mem_fun(*this, &RenameTemplateEditor::addPressed) ); + del->signal_pressed().connect( sigc::mem_fun(*this, &RenameTemplateEditor::delPressed) ); + + show_all_children (); + + set_size_request (-1, 250); +} + +void RenameTemplateEditor::refreshTemplateList () { + + list->clear_items (); + + for (int i=0; iappend_text (options.renameTemplates[i]); +} + +void RenameTemplateEditor::addPressed () { + + if (templ->get_text()!="") { + options.renameTemplates.push_back (templ->get_text ()); + refreshTemplateList (); + templ->set_text(""); + } +} + +void RenameTemplateEditor::delPressed () { + + std::vector sel = list->get_selected (); + for (int i=0; iget_text (sel[i]); + std::vector::iterator f = std::find (options.renameTemplates.begin(), options.renameTemplates.end(), toDel); + if (f!=options.renameTemplates.end()) + options.renameTemplates.erase (f); + } + refreshTemplateList (); +} + +Glib::ustring RenameDialog::applyTemplate (const Glib::ustring& oName, const CacheImageData* cid, const Glib::ustring& templ) { + + return Glib::ustring ("szeva"); + +} + + diff --git a/rtgui/renamedlg.h b/rtgui/renamedlg.h new file mode 100644 index 000000000..e1cef34d9 --- /dev/null +++ b/rtgui/renamedlg.h @@ -0,0 +1,83 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _RENAMEDLG_ +#define _RENAMEDLG_ + +#include +#include + +#define RESPONSE_ALL 100 + +class RenameDialog : public Gtk::Dialog { + + protected: + + class TemplateColumns : public Gtk::TreeModel::ColumnRecord { + public: + Gtk::TreeModelColumn tmplName; + Gtk::TreeModelColumn rowSeparator; + TemplateColumns() { add(tmplName); add(rowSeparator); } + }; + TemplateColumns templateColumns; + Glib::RefPtr templateModel; + + Gtk::Window* p; + Gtk::Label* oldName; + Gtk::Entry* newName; + Gtk::CheckButton* useTmpl; + Gtk::ComboBox* templates; + Gtk::Button* all; + const CacheImageData* imageData; + + void fillTemplateList (); + + public: + RenameDialog (Gtk::Window* parent); + + void initName (const Glib::ustring& iname, const CacheImageData* cid); + Glib::ustring getNewName (); + + bool rowSeparatorFunc (const Glib::RefPtr& model, const Gtk::TreeModel::iterator& iter); + void tmplSelectionChanged (); + void useTemplToggled (); + + bool isTemplSelected (); + Glib::ustring getActiveTemplate (); + + static Glib::ustring applyTemplate (const Glib::ustring& oName, const CacheImageData* cid, const Glib::ustring& templ); +}; + +class RenameTemplateEditor : public Gtk::Dialog { + + protected: + Gtk::ListViewText* list; + Gtk::Entry* templ; + + void refreshTemplateList (); + public: + RenameTemplateEditor (Gtk::Window* parent); + + Glib::ustring getSelectedTemplate (); + + void addPressed (); + void delPressed (); +}; + +#endif + diff --git a/rtgui/resize.cc b/rtgui/resize.cc new file mode 100644 index 000000000..48abe579a --- /dev/null +++ b/rtgui/resize.cc @@ -0,0 +1,356 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +Resize::Resize () : maxw(100000), maxh(100000) { + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + pack_start(*enabled); + pack_start(*Gtk::manage (new Gtk::HSeparator()), Gtk::PACK_SHRINK, 2); + + Gtk::Table* combos = Gtk::manage (new Gtk::Table (2, 2)); + + method = Gtk::manage (new Gtk::ComboBoxText ()); + method->append_text (M("TP_RESIZE_NEAREST")); + method->append_text (M("TP_RESIZE_BILINEAR")); + method->append_text (M("TP_RESIZE_BICUBIC")); + method->append_text (M("TP_RESIZE_BICUBICSF")); + method->append_text (M("TP_RESIZE_BICUBICSH")); + method->append_text (M("TP_RESIZE_DOWNSCALEB")); + method->append_text (M("TP_RESIZE_DOWNSCALEF")); + method->set_active (0); + + combos->attach (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_METHOD"))), 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + combos->attach (*method, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + spec = Gtk::manage (new Gtk::ComboBoxText ()); + spec->append_text (M("TP_RESIZE_SCALE")); + spec->append_text (M("TP_RESIZE_WIDTH")); + spec->append_text (M("TP_RESIZE_HEIGHT")); + method->set_active (0); + + combos->attach (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_SPECIFY"))), 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + combos->attach (*spec, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + pack_start (*combos, Gtk::PACK_SHRINK, 4); + + scale = new Adjuster (M("TP_RESIZE_SCALE"), 0.2, 4, 0.01, 1); + scale->setAdjusterListener (this); + + pack_start (*scale, Gtk::PACK_SHRINK, 4); + + sizeBox = Gtk::manage (new Gtk::VBox ()); + + Gtk::HBox* sbox = Gtk::manage (new Gtk::HBox ()); + Gtk::HBox* wbox = Gtk::manage (new Gtk::HBox ()); + Gtk::HBox* hbox = Gtk::manage (new Gtk::HBox ()); + w = Gtk::manage (new Gtk::SpinButton ()); + h = Gtk::manage (new Gtk::SpinButton ()); + wbox->pack_start (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_W"))), Gtk::PACK_SHRINK, 4); + wbox->pack_start (*w); + hbox->pack_start (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_H"))), Gtk::PACK_SHRINK, 4); + hbox->pack_start (*h); + sbox->pack_start (*wbox); + sbox->pack_start (*hbox); + + sizeBox->pack_start (*sbox, Gtk::PACK_SHRINK, 4); + sizeBox->show_all (); + sizeBox->reference (); + + w->set_digits (0); + w->set_increments (1,100); + w->set_value (800); + w->set_range (32, 4*maxw); + + h->set_digits (0); + h->set_increments (1,100); + h->set_value (600); + h->set_range (32, 4*maxh); + + wconn = w->signal_value_changed().connect ( sigc::mem_fun(*this, &Resize::entryWChanged), true); + hconn = h->signal_value_changed().connect ( sigc::mem_fun(*this, &Resize::entryHChanged), true); + method->signal_changed().connect ( sigc::mem_fun(*this, &Resize::methodChanged) ); + spec->signal_changed().connect ( sigc::mem_fun(*this, &Resize::specChanged) ); + enaConn = enabled->signal_toggled().connect ( sigc::mem_fun(*this, &Resize::enabledToggled) ); + + show_all(); +} + +Resize::~Resize () { + + delete scale; + delete sizeBox; +} + +void Resize::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + wconn.block (true); + hconn.block (true); + + scale->setValue (pp->resize.scale); + w->set_value (pp->resize.width); + h->set_value (pp->resize.height); + enabled->set_active (pp->resize.enabled); + spec->set_active (pp->resize.dataspec); + + method->set_active (2); + if (pp->resize.method == "Nearest") + method->set_active (0); + else if (pp->resize.method == "Bilinear") + method->set_active (1); + else if (pp->resize.method == "Bicubic") + method->set_active (2); + else if (pp->resize.method == "Bicubic (Softer)") + method->set_active (3); + else if (pp->resize.method == "Bicubic (Sharper)") + method->set_active (4); + else if (pp->resize.method == "Downscale (Better)") + method->set_active (5); + else if (pp->resize.method == "Downscale (Faster)") + method->set_active (6); + + wDirty = false; + hDirty = false; + + if (pedited) { + wDirty = pedited->resize.width; + hDirty = pedited->resize.height; + scale->setEditedState (pedited->resize.scale ? Edited : UnEdited); + if (!pedited->resize.method) + method->set_active (5); + if (!pedited->resize.dataspec) + spec->set_active (3); + enabled->set_inconsistent (!pedited->resize.enabled); + } + + lastEnabled = pp->resize.enabled; + + wconn.block (false); + hconn.block (false); + enableListener (); +} + +void Resize::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->resize.scale = scale->getValue (); + pp->resize.method = "Bicubic"; + if (method->get_active_row_number() == 0) + pp->resize.method = "Nearest"; + else if (method->get_active_row_number() == 1) + pp->resize.method = "Bilinear"; + else if (method->get_active_row_number() == 2) + pp->resize.method = "Bicubic"; + else if (method->get_active_row_number() == 3) + pp->resize.method = "Bicubic (Softer)"; + else if (method->get_active_row_number() == 4) + pp->resize.method = "Bicubic (Sharper)"; + else if (method->get_active_row_number() == 5) + pp->resize.method = "Downscale (Better)"; + else if (method->get_active_row_number() == 6) + pp->resize.method = "Downscale (Faster)"; + + pp->resize.dataspec = spec->get_active_row_number(); + pp->resize.width = round (w->get_value ()); + pp->resize.height = round(h->get_value ()); + pp->resize.enabled = enabled->get_active (); + + if (pedited) { + pedited->resize.enabled = !enabled->get_inconsistent(); + pedited->resize.dataspec = spec->get_active_row_number() != 3; + pedited->resize.method = method->get_active_row_number() != 5; + if (pedited->resize.dataspec) { + pedited->resize.scale = scale->getEditedState (); + pedited->resize.width = wDirty; + pedited->resize.height = hDirty; + } + else { + pedited->resize.scale = false; + pedited->resize.width = false; + pedited->resize.height = false; + } + } +} + +void Resize::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + scale->setDefault (defParams->resize.scale); + + if (pedited) + scale->setDefaultEditedState (pedited->resize.scale ? Edited : UnEdited); + else + scale->setDefaultEditedState (Irrelevant); +} + +void Resize::adjusterChanged (Adjuster* a, double newval) { + + if (!batchMode) { + wconn.block (true); + hconn.block (true); + h->set_value (maxh * a->getValue ()); + w->set_value (maxw * a->getValue ()); + wconn.block (false); + hconn.block (false); + } + + if (listener && (enabled->get_active () || batchMode)) + listener->panelChanged (EvResizeScale, Glib::ustring::format (std::setw(5), std::fixed, std::setprecision(4), scale->getValue())); +} + +void Resize::methodChanged () { + + if (listener && (enabled->get_active () || batchMode)) + listener->panelChanged (EvResizeMethod, method->get_active_text()); +} + +struct setrdimparams { + Resize* resize; + int mw; + int mh; + int ow; + int oh; +}; + +int setrdim (void* data) { + + gdk_threads_enter (); + setrdimparams* params = (setrdimparams*)data; + params->resize->setDimensions (params->mw, params->mh, params->ow, params->oh); + delete params; + gdk_threads_leave (); + return 0; +} + +void Resize::sizeChanged (int mw, int mh, int ow, int oh) { + + setrdimparams* params = new setrdimparams; + params->mw = mw; + params->mh = mh; + params->ow = ow; + params->oh = oh; + params->resize = this; + g_idle_add (setrdim, params); +} + +void Resize::setDimensions (int mw, int mh, int ow, int oh) { + + maxw = ow; + maxh = oh; + + wconn.block (true); + hconn.block (true); + + w->set_range (32, 4*maxw); + h->set_range (32, 4*maxh); + + wconn.block (false); + hconn.block (false); +} + +void Resize::entryWChanged () { + + wDirty = true; + + if (!batchMode && listener) { + hconn.block (true); + h->set_value (w->get_value () * maxh / maxw); + hconn.block (false); + scale->setValue (w->get_value () / maxw); + } + + if (listener && (enabled->get_active () || batchMode)) + listener->panelChanged (EvResizeWidth, Glib::ustring::format ((int)w->get_value())); + + +} + +void Resize::entryHChanged () { + + hDirty = true; + + if (!batchMode && listener) { + wconn.block (true); + w->set_value (h->get_value () * maxw / maxh); + wconn.block (false); + scale->setValue (h->get_value () / maxh); + } + + if (listener && (enabled->get_active () || batchMode)) + listener->panelChanged (EvResizeHeight, Glib::ustring::format ((int)h->get_value())); +} + +void Resize::specChanged () { + + removeIfThere (this, scale, false); + removeIfThere (this, sizeBox, false); + + if (spec->get_active_row_number() == 0) { + pack_start (*scale, Gtk::PACK_SHRINK, 4); + scale->sliderChanged (); + } + else if (spec->get_active_row_number() == 1) { + pack_start (*sizeBox, Gtk::PACK_SHRINK, 4); + w->set_sensitive (true); + h->set_sensitive (false); + entryWChanged (); + } + else if (spec->get_active_row_number() == 2) { + pack_start (*sizeBox, Gtk::PACK_SHRINK, 4); + h->set_sensitive (true); + w->set_sensitive (false); + entryHChanged (); + } +} + +void Resize::setBatchMode (bool batchMode) { + + method->append_text (M("GENERAL_UNCHANGED")); + spec->append_text (M("GENERAL_UNCHANGED")); + ToolPanel::setBatchMode (batchMode); + scale->showEditedCB (); +} + +void Resize::enabledToggled () { + + if (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaConn.block (true); + enabled->set_active (false); + enaConn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_active ()) + listener->panelChanged (EvResizeEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvResizeEnabled, M("GENERAL_DISABLED")); + } +} + diff --git a/rtgui/resize.h b/rtgui/resize.h new file mode 100644 index 000000000..5f9a3f2b6 --- /dev/null +++ b/rtgui/resize.h @@ -0,0 +1,60 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _RESIZE_H_ +#define _RESIZE_H_ + +#include +#include +#include + +class Resize : public Gtk::VBox, public AdjusterListener, public ToolPanel, public rtengine::SizeListener { + + protected: + Gtk::CheckButton* enabled; + Adjuster* scale; + Gtk::VBox* sizeBox; + Gtk::ComboBoxText* method; + Gtk::ComboBoxText* spec; + Gtk::SpinButton* w; + Gtk::SpinButton* h; + int maxw, maxh; + sigc::connection wconn, hconn, enaConn; + bool wDirty, hDirty, lastEnabled; + + public: + + Resize (); + ~Resize (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void entryWChanged (); + void entryHChanged (); + void methodChanged (); + void specChanged (); + void sizeChanged (int w, int h, int ow, int oh); + void setDimensions (int w, int h, int ow, int oh); + void enabledToggled (); +}; + +#endif diff --git a/rtgui/rotate.cc b/rtgui/rotate.cc new file mode 100644 index 000000000..f0411f7e2 --- /dev/null +++ b/rtgui/rotate.cc @@ -0,0 +1,157 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +extern Glib::ustring argv0; + +using namespace rtengine; +using namespace rtengine::procparams; + +Rotate::Rotate () : ToolPanel (), degAdd(false) { + + rlistener = NULL; + + degree = Gtk::manage (new Adjuster (M("TP_ROTATE_DEGREE"), -45, 45, 0.01, 0)); + degree->setAdjusterListener (this); + pack_start (*degree); + + fill = Gtk::manage (new Gtk::CheckButton (M("TP_ROTATE_FILL"))); + pack_start (*fill); + + selectStraight = Gtk::manage (new Gtk::Button (M("TP_ROTATE_SELECTLINE"))); + Gtk::Image* selimg = Gtk::manage (new Gtk::Image (argv0+"/images/straighten16.png")); + selectStraight->set_image (*selimg); + pack_start (*selectStraight, Gtk::PACK_SHRINK, 2); + + autoCrop = Gtk::manage (new Gtk::Button (M("TP_ROTATE_AUTOCROP"))); + pack_start (*autoCrop, Gtk::PACK_SHRINK, 2); + + selectStraight->signal_pressed().connect( sigc::mem_fun(*this, &Rotate::selectStraightPressed) ); + autoCrop->signal_pressed().connect( sigc::mem_fun(*this, &Rotate::autoCropPressed) ); + fillConn = fill->signal_toggled().connect( sigc::mem_fun(*this, &Rotate::fillPressed) ); + + fill->set_active (true); + show_all (); +} + +void Rotate::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + degree->setEditedState (pedited->rotate.degree ? Edited : UnEdited); + fill->set_inconsistent (!pedited->rotate.fill); + } + + degree->setValue (pp->rotate.degree); + fillConn.block (true); + fill->set_active (pp->rotate.fill); + fillConn.block (false); + + lastFill = pp->rotate.fill; + + enableListener (); +} + +void Rotate::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->rotate.degree = degree->getValue (); + pp->rotate.fill = fill->get_active (); + + if (pedited) { + pedited->rotate.degree = degree->getEditedState (); + pedited->rotate.fill = !fill->get_inconsistent(); + } +} + +void Rotate::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + degree->setDefault (defParams->rotate.degree); + + if (pedited) + degree->setDefaultEditedState (pedited->rotate.degree ? Edited : UnEdited); + else + degree->setDefaultEditedState (Irrelevant); +} + +void Rotate::adjusterChanged (Adjuster* a, double newval) { + + if (listener) + listener->panelChanged (EvROTDegree, Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), degree->getValue())); +} + +void Rotate::straighten (double deg) { + + degree->setValue (degree->getValue()+deg); + degree->setEditedState (Edited); + if (listener) + listener->panelChanged (EvROTDegree, Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), degree->getValue())); +} + +void Rotate::selectStraightPressed () { + + if (rlistener) + rlistener->straightenRequested (); +} + +void Rotate::autoCropPressed () { + + if (rlistener) + rlistener->autoCropRequested (); +} + +void Rotate::fillPressed () { + + if (batchMode) { + if (fill->get_inconsistent()) { + fill->set_inconsistent (false); + fillConn.block (true); + fill->set_active (false); + fillConn.block (false); + } + else if (lastFill) + fill->set_inconsistent (true); + + lastFill = fill->get_active (); + } + + if (listener) { + if (fill->get_active()) + listener->panelChanged (EvROTDegree, M("TP_ROTATE_FILL")+' '+M("GENERAL_ENABLED")); + else + listener->panelChanged (EvROTFill, M("TP_ROTATE_FILL")+' '+M("GENERAL_DISABLED")); + } +} + +void Rotate::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + degree->showEditedCB (); + removeIfThere (this, autoCrop); +} + +void Rotate::setAdjusterBehavior (bool brotadd) { + + if (!degAdd && brotadd || degAdd && !brotadd) + degree->setLimits (-45, 45, 0.01, 0); + + degAdd = brotadd; +} diff --git a/rtgui/rotate.h b/rtgui/rotate.h new file mode 100644 index 000000000..17019fcb2 --- /dev/null +++ b/rtgui/rotate.h @@ -0,0 +1,64 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _ROTATE_H_ +#define _ROTATE_H_ + +#include +#include +#include + +class RotateListener { + + public: + virtual void straightenRequested () {} + virtual void autoCropRequested () {} +}; + +class Rotate : public Gtk::VBox, public AdjusterListener, public ToolPanel { + + protected: + Adjuster* degree; + Gtk::Button* selectStraight; + Gtk::Button* autoCrop; + RotateListener* rlistener; + Gtk::CheckButton* fill; + bool degAdd; + bool lastFill; + sigc::connection fillConn; + + public: + + Rotate (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void straighten (double deg); + + void adjusterChanged (Adjuster* a, double newval); + void setAdjusterBehavior (bool brotadd); + void selectStraightPressed (); + void fillPressed (); + void autoCropPressed (); + void setRotateListener (RotateListener* l) { rlistener = l; } +}; + +#endif diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc new file mode 100644 index 000000000..d4ec85a53 --- /dev/null +++ b/rtgui/rtwindow.cc @@ -0,0 +1,245 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include + +RTWindow::RTWindow () { + + cacheMgr.init (); + +#ifdef GLIBMM_EXCEPTIONS_ENABLED + try { set_default_icon_from_file (argv0+"/images/logoicon16.png"); + } catch(Glib::Exception& ex) { printf ("%s\n", ex.what().c_str()); } +#else + { std::auto_ptr error; + set_default_icon_from_file (argv0+"/images/logoicon16.png", error); + } +#endif //GLIBMM_EXCEPTIONS_ENABLED + + set_title("RawTherapee "+versionString); + property_allow_shrink() = true; + set_default_size(options.windowWidth, options.windowHeight); + set_modal(false); + set_resizable(true); + property_destroy_with_parent().set_value(false); + + mainNB = Gtk::manage (new Gtk::Notebook ()); + mainNB->set_scrollable (true); + + fpanel = new FilePanel (); + fpanel->setParent (this); + + // decorate tab + Gtk::HBox* hbf = Gtk::manage (new Gtk::HBox ()); + hbf->pack_start (*Gtk::manage (new Gtk::Image (Gtk::Stock::DIRECTORY, Gtk::ICON_SIZE_MENU))); + hbf->pack_start (*Gtk::manage (new Gtk::Label (M("MAIN_FRAME_FILEBROWSER")))); + hbf->set_spacing (2); + hbf->show_all (); + mainNB->append_page (*fpanel, *hbf); + + bpanel = new BatchQueuePanel (); + bpanel->setParent (this); + + // decorate tab + Gtk::HBox* hbb = Gtk::manage (new Gtk::HBox ()); + hbb->pack_start (*Gtk::manage (new Gtk::Image (Gtk::Stock::EXECUTE, Gtk::ICON_SIZE_MENU))); + hbb->pack_start (*Gtk::manage (new Gtk::Label (M("MAIN_FRAME_BATCHQUEUE")))); + hbb->set_spacing (2); + hbb->show_all (); + mainNB->append_page (*bpanel, *hbb); + + signal_key_press_event().connect( sigc::mem_fun(*this, &RTWindow::keyPressed) ); + + Gtk::VBox* mainBox = Gtk::manage (new Gtk::VBox ()); + mainBox->pack_start (*mainNB); + Gtk::HBox* bottomBox = Gtk::manage (new Gtk::HBox ()); + mainBox->pack_start (*bottomBox, Gtk::PACK_SHRINK, 1); + + // filling bottom box + Gtk::LinkButton* rtWeb = Gtk::manage (new Gtk::LinkButton ("http://rawtherapee.com")); + Gtk::Button* preferences = Gtk::manage (new Gtk::Button (M("MAIN_BUTTON_PREFERENCES"))); + preferences->set_image (*Gtk::manage(new Gtk::Image (Gtk::StockID("gtk-preferences"), Gtk::ICON_SIZE_BUTTON))); + preferences->set_relief (Gtk::RELIEF_NONE); + preferences->signal_clicked().connect( sigc::mem_fun(*this, &RTWindow::showPreferences) ); + btn_fullscreen = Gtk::manage( new Gtk::Button(M("MAIN_BUTTON_FULLSCREEN"))); + btn_fullscreen->signal_clicked().connect( sigc::mem_fun(*this, &RTWindow::toggle_fullscreen) ); + bottomBox->pack_start (*preferences, Gtk::PACK_SHRINK, 0); + bottomBox->pack_start (*rtWeb, Gtk::PACK_SHRINK, 4); + bottomBox->pack_end (*btn_fullscreen, Gtk::PACK_SHRINK, 4); + + Glib::RefPtr style = Gtk::RcStyle::create (); + style->set_xthickness (0); + style->set_ythickness (0); + rtWeb->modify_style (style); + preferences->modify_style (style); + + add (*mainBox); + show_all (); +} + +void RTWindow::on_realize () { + + Gtk::Window::on_realize (); + + cursorManager.init (get_window()); +} + +void RTWindow::addEditorPanel (EditorPanel* ep) { + + ep->setParent (this); + + // construct closeable tab for the image + Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ()); + hb->pack_start (*Gtk::manage (new Gtk::Image (Gtk::Stock::FILE, Gtk::ICON_SIZE_MENU))); + hb->pack_start (*Gtk::manage (new Gtk::Label (ep->getShortName ()))); + Gtk::Button* closeb = Gtk::manage (new Gtk::Button ()); + closeb->set_image (*Gtk::manage(new Gtk::Image (Gtk::Stock::CLOSE, Gtk::ICON_SIZE_MENU))); + closeb->set_relief (Gtk::RELIEF_NONE); + closeb->set_focus_on_click (false); + // make the button as small as possible + Glib::RefPtr style = Gtk::RcStyle::create (); + style->set_xthickness (0); + style->set_ythickness (0); + + closeb->modify_style (style); + closeb->signal_clicked().connect( sigc::bind (sigc::mem_fun(*this, &RTWindow::remEditorPanel) , ep)); + hb->pack_end (*closeb); + hb->set_spacing (2); + hb->show_all (); + mainNB->append_page (*ep, *hb); + mainNB->set_current_page (mainNB->page_num (*ep)); + mainNB->set_tab_reorderable (*ep, true); + + epanels[ep->getFileName()] = ep; + filesEdited.insert (ep->getFileName ()); + fpanel->refreshEditedState (filesEdited); +} + +void RTWindow::remEditorPanel (EditorPanel* ep) { + + if (ep->beforeClosing ()) { + ep->saveOptions (); + epanels.erase (ep->getFileName()); + filesEdited.erase (ep->getFileName ()); + fpanel->refreshEditedState (filesEdited); + + mainNB->remove_page (*ep); + + if (mainNB->get_current_page () == mainNB->page_num (*bpanel)) + mainNB->set_current_page (mainNB->page_num (*fpanel)); + } + // TODO: ask what to do: close & apply, close & apply selection, close & revert, cancel +} + +bool RTWindow::keyPressed (GdkEventKey* event) { + if(event->keyval == GDK_F11) { + toggle_fullscreen(); + } + + if (mainNB->get_nth_page (mainNB->get_current_page()) == fpanel) { + } +// else if (mainNB->get_nth_page (mainNB->get_current_page()) == bqpanel) { +// } + else { + EditorPanel* ep = (EditorPanel*)mainNB->get_nth_page (mainNB->get_current_page()); + return ep->handleShortcutKey (event); + } + return false; +} + +void RTWindow::imageDeveloped (Glib::ustring fname) { + +// fpanel->refreshThumbnail (fname); +} + +void RTWindow::addBatchQueueJob (BatchQueueEntry* bqe, bool head) { + + bpanel->addBatchQueueJob (bqe, head); + fpanel->queue_draw (); +} + +bool RTWindow::on_delete_event(GdkEventAny* event) { + + fpanel->saveOptions (); + bpanel->saveOptions (); + +/* if (fileBrowser->getFileCatalog()->getBatchQueue()->hasJobs()) { + Gtk::MessageDialog msgd (M("MAIN_MSG_EXITJOBSINQUEUEQUEST"), false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true); + msgd.set_secondary_text (M("MAIN_MSG_EXITJOBSINQUEUEINFO")); + int response = msgd.run (); + if (response==Gtk::RESPONSE_NO) + return true; + } + + editCoord->close (); + + if (options.startupDir==STARTUPDIR_LAST && fileBrowser->lastSelectedDir ()!="") + options.startupPath = fileBrowser->lastSelectedDir (); + fileBrowser->close (); + cacheMgr.closeCache (); + + + options.lastScale = editorPanel->zoomBar->getScale (); + options.lastCropSize = editorPanel->zoomBar->getCropSize (); + if (options.showFilePanelState==0 || options.showFilePanelState==2) + options.fileBrowserHeight = fileBrowser->get_height (); + options.historyPanelWidth = ppaned->get_position (); + options.toolPanelWidth = vboxright->get_width();//hpaned->get_width() - hpaned->get_position (); + options.showHistory = editorPanel->hidehp->get_active (); + options.showInfo = editorPanel->info->get_active (); + options.showClippedHighlights = editorPanel->indclippedh->get_active (); + options.showClippedShadows = editorPanel->indclippeds->get_active (); + options.bgcolor = editorPanel->iarea->imageArea->getBGColor (); + options.lastSaveAsPath = saveAsDialog->getDirectory (); + options.procQueueEnabled = fileBrowser->getFileCatalog()->getBatchQueue()->isEnabled(); + options.fbArrangement = fileBrowser->getFileCatalog()->getArrangement (); + options.firstRun = false; +*/ + options.windowWidth = get_width(); + options.windowHeight = get_height(); + + + Options::save (); + hide(); + return true; +} + +void RTWindow::showPreferences () { + + Preferences *pref = new Preferences (); + pref->run (); + delete pref; + + fpanel->optionsChanged (); +} + +void RTWindow::toggle_fullscreen () { + if(is_fullscreen){ + unfullscreen(); + is_fullscreen = false; + btn_fullscreen->set_label(M("MAIN_BUTTON_FULLSCREEN")); + } + else { + fullscreen(); + is_fullscreen = true; + btn_fullscreen->set_label(M("MAIN_BUTTON_UNFULLSCREEN")); + } +} diff --git a/rtgui/rtwindow.h b/rtgui/rtwindow.h new file mode 100644 index 000000000..e69ee3ff8 --- /dev/null +++ b/rtgui/rtwindow.h @@ -0,0 +1,57 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _RTWINDOW_ +#define _RTWINDOW_ + +#include +#include +#include +#include +#include + +class RTWindow : public Gtk::Window { + + private: + Gtk::Notebook* mainNB; + FilePanel* fpanel; + BatchQueuePanel* bpanel; + std::set filesEdited; + std::map epanels; + + bool is_fullscreen; + Gtk::Button * btn_fullscreen; + + public: + RTWindow (); + + void addEditorPanel (EditorPanel* ep); + void remEditorPanel (EditorPanel* ep); + + void addBatchQueueJob (BatchQueueEntry* bqe, bool head=false); + + bool keyPressed (GdkEventKey* event); + bool on_delete_event(GdkEventAny* event); + + void imageDeveloped (Glib::ustring fname); // called by the batchqueue when it finishes an image + void showPreferences (); + void on_realize (); + void toggle_fullscreen (); +}; + +#endif diff --git a/rtgui/safegtk.cc b/rtgui/safegtk.cc new file mode 100644 index 000000000..867a7119d --- /dev/null +++ b/rtgui/safegtk.cc @@ -0,0 +1,152 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ + +#include +#include + +Glib::RefPtr safe_create_from_file(const std::string& filename) +{ + Glib::RefPtr res; +#ifdef GLIBMM_EXCEPTIONS_ENABLED + try { + res = Gdk::Pixbuf::create_from_file (filename); + } + catch (Glib::Exception& ex) { + printf ("%s\n", ex.what().c_str()); + } +#else + std::auto_ptr error; + res = Gdk::Pixbuf::create_from_file (filename, error); + if (error.get()) + printf ("%s\n", error->what().c_str()); +#endif + + return res; +} + + +Glib::RefPtr safe_query_file_info (Glib::RefPtr &file) +{ + Glib::RefPtr info; +#ifdef GLIBMM_EXCEPTIONS_ENABLED + try { info = file->query_info(); }catch (...) { } +#else + std::auto_ptr error; + info = file->query_info("*", Gio::FILE_QUERY_INFO_NONE, error); +#endif + return info; +} + +#ifdef GLIBMM_EXCEPTIONS_ENABLED +# define SAFE_ENUMERATOR_CODE_START \ + do{try { if ((dirList = dir->enumerate_children ())) \ + for (Glib::RefPtr info = dirList->next_file(); info; info = dirList->next_file()) { + +# define SAFE_ENUMERATOR_CODE_END \ + }} catch (Glib::Exception& ex) { printf ("%s\n", ex.what().c_str()); }}while(0) +#else +# define SAFE_ENUMERATOR_CODE_START \ + do{std::auto_ptr error; Glib::RefPtr cancellable; \ + if ((dirList = dir->enumerate_children (cancellable, "*", Gio::FILE_QUERY_INFO_NONE, error))) \ + for (Glib::RefPtr info = dirList->next_file(cancellable, error); !error.get() && info; info = dirList->next_file(cancellable, error)) { + +# define SAFE_ENUMERATOR_CODE_END } if (error.get()) printf ("%s\n", error->what().c_str());}while (0) +#endif + +void safe_build_file_list (Glib::RefPtr &dir, std::vector &flist) +{ + Glib::RefPtr dirList; + if (dir) { + SAFE_ENUMERATOR_CODE_START + flist.push_back (FileMTimeInfo (removeExtension(info->get_name()), info->modification_time())); + SAFE_ENUMERATOR_CODE_END; + } +} + +void safe_build_file_list (Glib::RefPtr &dir, std::vector &names, const Glib::ustring &directory) +{ + Glib::RefPtr dirList; + if (dir) { + SAFE_ENUMERATOR_CODE_START + names.push_back (Glib::build_filename (directory, info->get_name())); + SAFE_ENUMERATOR_CODE_END; + } +} + + +void safe_build_subdir_list (Glib::RefPtr &dir, std::vector &subDirs, bool add_hidden) +{ + Glib::RefPtr dirList; + if (dir) + { + SAFE_ENUMERATOR_CODE_START + if (info->get_file_type() == Gio::FILE_TYPE_DIRECTORY && (!info->is_hidden() || add_hidden)) + subDirs.push_back (info->get_name()); + SAFE_ENUMERATOR_CODE_END; + } +} + +bool safe_spawn_command_line_async (const Glib::ustring& cmd_utf8) +{ + std::string cmd; + bool success = false; +#ifdef GLIBMM_EXCEPTIONS_ENABLED + try { + cmd = Glib::filename_from_utf8(cmd_utf8); + printf ("command line: |%s|\n", cmd.c_str()); + Glib::spawn_command_line_async (cmd); + success = true; + } catch (Glib::Exception& ex) { + printf ("%s\n", ex.what().c_str()); + } +#else + std::auto_ptr error; + cmd = Glib::filename_from_utf8(cmd_utf8, error); + if (!error.get()) { + printf ("command line: |%s|\n", cmd.c_str()); + Glib::spawn_command_line_async (cmd, error); + } + if (error.get()) + printf ("%s\n", error->what().c_str()); + else + success = true; +#endif + return success; +} + +std::string safe_locale_from_utf8 (const Glib::ustring& utf8_str) +{ + std::string str; +#ifdef GLIBMM_EXCEPTIONS_ENABLED + try { + str = Glib::locale_from_utf8(utf8_str); + } + catch (const Glib::ConvertError& e) { + //utf8_str = Glib::convert_with_fallback(src, "UTF8", "LATIN1","?"); + } +#else + { + std::auto_ptr error; + str = Glib::locale_from_utf8(utf8_str, error); + if (error.get()) + {/*utf8_str = Glib::convert_with_fallback(src, "UTF8", "LATIN1","?", error);*/} + } +#endif //GLIBMM_EXCEPTIONS_ENABLED + return str; +} diff --git a/rtgui/safegtk.h b/rtgui/safegtk.h new file mode 100644 index 000000000..02809f308 --- /dev/null +++ b/rtgui/safegtk.h @@ -0,0 +1,32 @@ +#ifndef SAFE_GTK_H_INCLUDED +#define SAFE_GTK_H_INCLUDED + +#include +#include +#include + +Glib::RefPtr safe_create_from_file(const std::string& filename); + +class FileMTimeInfo { + + public: + Glib::ustring fname; + Glib::TimeVal mtime; + + FileMTimeInfo (Glib::ustring name, Glib::TimeVal mtime) : fname(name), mtime(mtime) {} + bool operator<(const FileMTimeInfo& other) const { return mtime safe_query_file_info (Glib::RefPtr &file); +void safe_build_file_list (Glib::RefPtr &dir, std::vector &flist); +void safe_build_file_list (Glib::RefPtr &dir, std::vector &names, const Glib::ustring &directory = ""); +void safe_build_subdir_list (Glib::RefPtr &dir, std::vector &subDirs, bool add_hidden); + +bool safe_spawn_command_line_async (const Glib::ustring& cmd_utf8); + +Glib::ustring safe_locale_to_utf8 (const std::string& src); // from rtengine +std::string safe_locale_from_utf8 (const Glib::ustring& utf8_str); + + + +#endif diff --git a/rtgui/saveasdlg.cc b/rtgui/saveasdlg.cc new file mode 100644 index 000000000..088eef363 --- /dev/null +++ b/rtgui/saveasdlg.cc @@ -0,0 +1,141 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include "saveasdlg.h" +#include + +extern Options options; +SaveAsDialog::SaveAsDialog (Glib::ustring initialDir) { + + Gtk::VBox* vbox = get_vbox (); + + fchooser = new Gtk::FileChooserWidget (Gtk::FILE_CHOOSER_ACTION_SAVE); + fchooser->set_current_folder (initialDir); + + filter_jpg.set_name(M("SAVEDLG_JPGFILTER")); + filter_jpg.add_pattern("*.jpg"); + + filter_tif.set_name(M("SAVEDLG_JPGFILTER")); + filter_tif.add_pattern("*.tif"); + + filter_png.set_name(M("SAVEDLG_JPGFILTER")); + filter_png.add_pattern("*.png"); + + vbox->pack_start (*fchooser); + + Gtk::HSeparator* hsep1 = new Gtk::HSeparator (); + vbox->pack_start (*hsep1, Gtk::PACK_SHRINK, 2); + +// Output Options +// ~~~~~~~~~~~~~~ + formatOpts = new SaveFormatPanel (); + formatOpts->init (options.saveFormat); + formatOpts->setListener (this); + + vbox->pack_start (*formatOpts, Gtk::PACK_SHRINK, 4); + + Gtk::HSeparator* hsep2 = new Gtk::HSeparator (); + vbox->pack_start (*hsep2, Gtk::PACK_SHRINK, 2); + +// queue/immediate +// ~~~~~~~~~~~~~ + immediately = new Gtk::RadioButton (M("SAVEDLG_SAVEIMMEDIATELY")); + putToQueueHead = new Gtk::RadioButton (M("SAVEDLG_PUTTOQUEUEHEAD")); + putToQueueTail = new Gtk::RadioButton (M("SAVEDLG_PUTTOQUEUETAIL")); + vbox->pack_start (*immediately, Gtk::PACK_SHRINK, 4); + vbox->pack_start (*putToQueueHead, Gtk::PACK_SHRINK, 4); + vbox->pack_start (*putToQueueTail, Gtk::PACK_SHRINK, 4); + immediately->set_active (true); + Gtk::RadioButton::Group g = immediately->get_group(); + putToQueueHead->set_group (g); + putToQueueTail->set_group (g); + +// buttons +// ~~~~~~ + Gtk::Button* ok = new Gtk::Button (M("GENERAL_OK")); + Gtk::Button* cancel = new Gtk::Button (M("GENERAL_CANCEL")); + + ok->set_image (*(new Gtk::Image (Gtk::StockID("gtk-ok"), Gtk::ICON_SIZE_BUTTON))); + cancel->set_image (*(new Gtk::Image (Gtk::StockID("gtk-cancel"), Gtk::ICON_SIZE_BUTTON))); + + ok->signal_clicked().connect( sigc::mem_fun(*this, &SaveAsDialog::okPressed) ); + cancel->signal_clicked().connect( sigc::mem_fun(*this, &SaveAsDialog::cancelPressed) ); + + get_action_area()->pack_end (*ok, Gtk::PACK_SHRINK, 4); + get_action_area()->pack_end (*cancel, Gtk::PACK_SHRINK, 4); + + set_border_width (4); + show_all_children (); +} + +bool SaveAsDialog::getImmediately () { + + return immediately->get_active (); +} + +bool SaveAsDialog::getToHeadOfQueue () { + + return putToQueueHead->get_active (); +} + +bool SaveAsDialog::getToTailOfQueue () { + + return putToQueueTail->get_active (); +} + +Glib::ustring SaveAsDialog::getFileName () { + + return fname; +} + +Glib::ustring SaveAsDialog::getDirectory () { + + return fchooser->get_current_folder (); +} + +SaveFormat SaveAsDialog::getFormat () { + + return formatOpts->getFormat (); +} + +void SaveAsDialog::okPressed () { + + fname = fchooser->get_filename(); + hide (); +} + +void SaveAsDialog::cancelPressed () { + + fname = ""; + hide (); +} + +void SaveAsDialog::formatChanged (Glib::ustring f) { + + if (f=="jpg") + fchooser->set_filter (filter_jpg); + else if (f=="png") + fchooser->set_filter (filter_png); + else if (f=="tif") + fchooser->set_filter (filter_tif); +} + +void SaveAsDialog::setInitialFileName (Glib::ustring fname) { + + fchooser->set_current_name(fname); +} diff --git a/rtgui/saveasdlg.h b/rtgui/saveasdlg.h new file mode 100644 index 000000000..f038bc62a --- /dev/null +++ b/rtgui/saveasdlg.h @@ -0,0 +1,58 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _SAVEASDLG_ +#define _SAVEASDLG_ + +#include +#include +#include +#include + +class SaveAsDialog : public Gtk::Dialog, public FormatChangeListener { + + protected: + Gtk::FileChooserWidget* fchooser; + SaveFormatPanel* formatOpts; + Glib::ustring fname; + Gtk::FileFilter filter_jpg; + Gtk::FileFilter filter_tif; + Gtk::FileFilter filter_png; + Gtk::RadioButton* immediately; + Gtk::RadioButton* putToQueueHead; + Gtk::RadioButton* putToQueueTail; + + public: + SaveAsDialog (Glib::ustring initialDir); + + Glib::ustring getFileName (); + Glib::ustring getDirectory (); + SaveFormat getFormat (); + bool getImmediately (); + bool getToHeadOfQueue (); + bool getToTailOfQueue (); + + void setInitialFileName (Glib::ustring iname); + + void okPressed (); + void cancelPressed (); + void formatChanged (Glib::ustring f); +}; + + +#endif diff --git a/rtgui/saveformatpanel.cc b/rtgui/saveformatpanel.cc new file mode 100644 index 000000000..3c2b0d699 --- /dev/null +++ b/rtgui/saveformatpanel.cc @@ -0,0 +1,132 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +SaveFormatPanel::SaveFormatPanel () : listener (NULL) { + + jpegqual = new Adjuster (M("SAVEDLG_JPEGQUAL"), 0, 100, 1, 100); + jpegqual->setAdjusterListener (this); + jpegqual->show (); + pngcompr = new Adjuster (M("SAVEDLG_PNGCOMPR"), 0, 6, 1, 6); + pngcompr->setAdjusterListener (this); + pngcompr->show (); + + Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ()); + Gtk::Label* flab = Gtk::manage (new Gtk::Label (M("SAVEDLG_FILEFORMAT")+":")); + hb1->pack_start (*flab, Gtk::PACK_SHRINK,4); + format = Gtk::manage (new Gtk::ComboBoxText ()); + format->append_text ("JPEG (8 bit)"); + format->append_text ("TIFF (8 bit)"); + format->append_text ("TIFF (16 bit)"); + format->append_text ("PNG (8 bit)"); + format->append_text ("PNG (16 bit)"); + format->set_active (0); + oformat = 0; + format->signal_changed().connect( sigc::mem_fun(*this, &SaveFormatPanel::formatChanged) ); + hb1->pack_start (*format); + pack_start (*hb1, Gtk::PACK_SHRINK, 4); + + formatopts = Gtk::manage (new Gtk::VBox ()); + formatopts->pack_start (*jpegqual, Gtk::PACK_SHRINK, 4); + pack_start (*formatopts, Gtk::PACK_SHRINK, 4); + + savespp = Gtk::manage (new Gtk::CheckButton (M("SAVEDLG_SAVESPP"))); + pack_start (*savespp, Gtk::PACK_SHRINK, 4); + + show_all (); + set_border_width (4); + + fstr[0] = "jpg"; + fstr[1] = "tif"; + fstr[2] = "tif"; + fstr[3] = "png"; + fstr[4] = "png"; +} + +void SaveFormatPanel::init (SaveFormat &sf) { + + FormatChangeListener* tmp = listener; + listener = NULL; + + if (sf.format=="jpg") + format->set_active (0); + else if (sf.format=="png" && sf.pngBits==16) + format->set_active (4); + else if (sf.format=="png" && sf.pngBits==8) + format->set_active (3); + else if (sf.format=="tif" && sf.tiffBits==16) + format->set_active (2); + else if (sf.format=="tif" && sf.tiffBits==8) + format->set_active (1); + + pngcompr->setValue (sf.pngCompression); + jpegqual->setValue (sf.jpegQuality); + savespp->set_active (sf.saveParams); + listener = tmp; +} + +SaveFormat SaveFormatPanel::getFormat () { + + SaveFormat sf; + + int sel = format->get_active_row_number(); + sf.format = fstr[sel]; + if (sel==4) + sf.pngBits = 16; + else + sf.pngBits = 8; + if (sel==2) + sf.tiffBits = 16; + else + sf.tiffBits = 8; + sf.pngCompression = (int) pngcompr->getValue (); + sf.jpegQuality = (int) jpegqual->getValue (); + sf.saveParams = savespp->get_active (); + return sf; +} + +void SaveFormatPanel::formatChanged () { + + if (oformat==0) + removeIfThere (formatopts, jpegqual); + else if (oformat==3 || oformat==4) + removeIfThere (formatopts, pngcompr); + + int act = format->get_active_row_number(); + if (act<0 || act>4) + return; + + Glib::ustring fr = fstr[act]; + if (fr=="jpg") + formatopts->pack_start (*jpegqual, Gtk::PACK_SHRINK,4); + else if (fr=="png") + formatopts->pack_start (*pngcompr, Gtk::PACK_SHRINK,4); + + oformat = act; + + if (listener) + listener->formatChanged (fr); +} + +void SaveFormatPanel::adjusterChanged (Adjuster* a, double newval) { + + formatChanged (); +} diff --git a/rtgui/saveformatpanel.h b/rtgui/saveformatpanel.h new file mode 100644 index 000000000..2add74c45 --- /dev/null +++ b/rtgui/saveformatpanel.h @@ -0,0 +1,58 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef __SAVEFORMATPANEL_H__ +#define __SAVEFORMATPANEL_H__ + +#include +#include +#include + +class FormatChangeListener { + + public: + virtual void formatChanged (Glib::ustring f) {} + +}; + +class SaveFormatPanel : public Gtk::VBox, public AdjusterListener { + + protected: + Adjuster* jpegqual; + Adjuster* pngcompr; + Gtk::ComboBoxText* format; + Gtk::VBox* formatopts; + int oformat; + FormatChangeListener* listener; + Glib::ustring fstr[5]; + Gtk::CheckButton* savespp; + + + public: + + SaveFormatPanel (); + void setListener (FormatChangeListener* l) { listener = l; } + + void init (SaveFormat& sf); + SaveFormat getFormat (); + + void formatChanged (); + void adjusterChanged (Adjuster* a, double newval); +}; + +#endif diff --git a/rtgui/shadowshighlights.cc b/rtgui/shadowshighlights.cc new file mode 100644 index 000000000..224d94a65 --- /dev/null +++ b/rtgui/shadowshighlights.cc @@ -0,0 +1,254 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +ShadowsHighlights::ShadowsHighlights () : ToolPanel() { + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (false); + pack_start (*enabled); + enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &ShadowsHighlights::enabledChanged) ); + + pack_start (*Gtk::manage (new Gtk::HSeparator())); + + hq = Gtk::manage (new Gtk::CheckButton (M("GENERAL_HIGH_QUALITY"))); + hq->set_active (false); + pack_start (*hq); + hqConn = hq->signal_toggled().connect( sigc::mem_fun(*this, &ShadowsHighlights::hqChanged) ); + + pack_start (*Gtk::manage (new Gtk::HSeparator())); + highlights = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_HIGHLIGHTS"), 0, 100, 1, 0)); + h_tonalwidth = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_HLTONALW"), 10, 100, 1, 80)); + pack_start (*highlights); + pack_start (*h_tonalwidth); + + pack_start (*Gtk::manage (new Gtk::HSeparator())); + + shadows = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_SHADOWS"), 0, 100, 1, 0)); + s_tonalwidth = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_SHTONALW"), 10, 100, 1, 80)); + pack_start (*shadows); + pack_start (*s_tonalwidth); + + pack_start (*Gtk::manage (new Gtk::HSeparator())); + + lcontrast = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_LOCALCONTR"), 0, 100, 1, 0)); + pack_start (*lcontrast); + + pack_start (*Gtk::manage (new Gtk::HSeparator())); + + radius = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_RADIUS"), 5, 100, 1, 30)); + pack_start (*radius); + + radius->setAdjusterListener (this); + highlights->setAdjusterListener (this); + h_tonalwidth->setAdjusterListener (this); + shadows->setAdjusterListener (this); + s_tonalwidth->setAdjusterListener (this); + lcontrast->setAdjusterListener (this); + + show_all_children (); +} + +void ShadowsHighlights::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + radius->setEditedState (pedited->sh.radius ? Edited : UnEdited); + lcontrast->setEditedState (pedited->sh.localcontrast ? Edited : UnEdited); + highlights->setEditedState (pedited->sh.highlights ? Edited : UnEdited); + h_tonalwidth->setEditedState (pedited->sh.htonalwidth ? Edited : UnEdited); + shadows->setEditedState (pedited->sh.shadows ? Edited : UnEdited); + s_tonalwidth->setEditedState (pedited->sh.stonalwidth ? Edited : UnEdited); + enabled->set_inconsistent (!pedited->sh.enabled); + hq->set_inconsistent (!pedited->sh.hq); + } + + enaConn.block (true); + enabled->set_active (pp->sh.enabled); + enaConn.block (false); + hqConn.block (true); + hq->set_active (pp->sh.hq); + hqConn.block (false); + + lastEnabled = pp->sh.enabled; + lastHQ = pp->sh.hq; + + radius->setValue (pp->sh.radius); + lcontrast->setValue (pp->sh.localcontrast); + highlights->setValue (pp->sh.highlights); + h_tonalwidth->setValue (pp->sh.htonalwidth); + shadows->setValue (pp->sh.shadows); + s_tonalwidth->setValue (pp->sh.stonalwidth); + + enableListener (); +} + +void ShadowsHighlights::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->sh.radius = (int)radius->getValue (); + pp->sh.localcontrast = (int)lcontrast->getValue (); + pp->sh.highlights = (int)highlights->getValue (); + pp->sh.htonalwidth = (int)h_tonalwidth->getValue (); + pp->sh.shadows = (int)shadows->getValue (); + pp->sh.stonalwidth = (int)s_tonalwidth->getValue (); + pp->sh.enabled = enabled->get_active(); + pp->sh.hq = hq->get_active(); + + if (pedited) { + pedited->sh.radius = radius->getEditedState (); + pedited->sh.localcontrast = lcontrast->getEditedState (); + pedited->sh.highlights = highlights->getEditedState (); + pedited->sh.htonalwidth = h_tonalwidth->getEditedState (); + pedited->sh.shadows = shadows->getEditedState (); + pedited->sh.stonalwidth = s_tonalwidth->getEditedState (); + pedited->sh.enabled = !enabled->get_inconsistent(); + pedited->sh.hq = !hq->get_inconsistent(); + } +} + +void ShadowsHighlights::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + radius->setDefault (defParams->sh.radius); + lcontrast->setDefault (defParams->sh.localcontrast); + highlights->setDefault (defParams->sh.highlights); + h_tonalwidth->setDefault (defParams->sh.htonalwidth); + shadows->setDefault (defParams->sh.shadows); + s_tonalwidth->setDefault (defParams->sh.stonalwidth); + + if (pedited) { + radius->setDefaultEditedState (pedited->sh.radius ? Edited : UnEdited); + lcontrast->setDefaultEditedState (pedited->sh.localcontrast ? Edited : UnEdited); + highlights->setDefaultEditedState (pedited->sh.highlights ? Edited : UnEdited); + h_tonalwidth->setDefaultEditedState (pedited->sh.htonalwidth ? Edited : UnEdited); + shadows->setDefaultEditedState (pedited->sh.shadows ? Edited : UnEdited); + s_tonalwidth->setDefaultEditedState (pedited->sh.stonalwidth ? Edited : UnEdited); + } + else { + radius->setDefaultEditedState (Irrelevant); + lcontrast->setDefaultEditedState (Irrelevant); + highlights->setDefaultEditedState (Irrelevant); + h_tonalwidth->setDefaultEditedState (Irrelevant); + shadows->setDefaultEditedState (Irrelevant); + s_tonalwidth->setDefaultEditedState (Irrelevant); + } +} + +void ShadowsHighlights::adjusterChanged (Adjuster* a, double newval) { + + if (listener && enabled->get_active()) { + + Glib::ustring costr = Glib::ustring::format ((int)a->getValue()); + + if (a==highlights) + listener->panelChanged (EvSHHighlights, costr); + else if (a==h_tonalwidth) + listener->panelChanged (EvSHHLTonalW, costr); + else if (a==shadows) + listener->panelChanged (EvSHShadows, costr); + else if (a==s_tonalwidth) + listener->panelChanged (EvSHSHTonalW, costr); + else if (a==radius) + listener->panelChanged (EvSHRadius, costr); + else if (a==lcontrast) + listener->panelChanged (EvSHLContrast, costr); + } +} + +void ShadowsHighlights::enabledChanged () { + + if (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaConn.block (true); + enabled->set_active (false); + enaConn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_active()) + listener->panelChanged (EvSHEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvSHEnabled, M("GENERAL_DISABLED")); + } +} + +void ShadowsHighlights::hqChanged () { + + if (batchMode) { + if (hq->get_inconsistent()) { + hq->set_inconsistent (false); + hqConn.block (true); + hq->set_active (false); + hqConn.block (false); + } + else if (lastHQ) + hq->set_inconsistent (true); + + lastHQ = hq->get_active (); + } + + if (listener) { + if (hq->get_active()) + listener->panelChanged (EvSHHighQuality, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvSHHighQuality, M("GENERAL_DISABLED")); + } +} + +void ShadowsHighlights::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + radius->showEditedCB (); + lcontrast->showEditedCB (); + highlights->showEditedCB (); + h_tonalwidth->showEditedCB (); + shadows->showEditedCB (); + s_tonalwidth->showEditedCB (); +} + +void ShadowsHighlights::setAdjusterBehavior (bool hadd, bool sadd, bool lcadd) { + + if (!hAdd && hadd) + highlights->setLimits (-100, 100, 1, 0); + else if (hAdd && !hadd) + highlights->setLimits (0, 100, 1, 0); + + if (!sAdd && sadd) + shadows->setLimits (-100, 100, 1, 0); + else if (sAdd && !sadd) + shadows->setLimits (0, 100, 1, 0); + + if (!lcAdd && lcadd) + lcontrast->setLimits (-100, 100, 1, 0); + else if (lcAdd && !lcadd) + lcontrast->setLimits (0, 100, 1, 0); + + hAdd = hadd; + sAdd = sadd; + lcAdd = lcadd; +} diff --git a/rtgui/shadowshighlights.h b/rtgui/shadowshighlights.h new file mode 100644 index 000000000..c65ebea05 --- /dev/null +++ b/rtgui/shadowshighlights.h @@ -0,0 +1,57 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _SHADOWSHIGHLIGHTS_H_ +#define _SHADOWSHIGHLIGHTS_H_ + +#include +#include +#include + +class ShadowsHighlights : public Gtk::VBox, public AdjusterListener, public ToolPanel { + + protected: + Adjuster* highlights; + Adjuster* h_tonalwidth; + Adjuster* shadows; + Adjuster* s_tonalwidth; + Adjuster* lcontrast; + Adjuster* radius; + Gtk::CheckButton* enabled; + Gtk::CheckButton* hq; + bool hAdd, sAdd, lcAdd; + bool lastEnabled, lastHQ; + sigc::connection enaConn, hqConn; + + public: + + ShadowsHighlights (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void enabledChanged (); + void hqChanged (); + + void setAdjusterBehavior (bool hadd, bool sadd, bool lcadd); +}; + +#endif diff --git a/rtgui/sharpening.cc b/rtgui/sharpening.cc new file mode 100644 index 000000000..249747b5b --- /dev/null +++ b/rtgui/sharpening.cc @@ -0,0 +1,461 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +Sharpening::Sharpening () : ToolPanel () { + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (true); + pack_start(*enabled); + enabled->show (); + Gtk::HSeparator *hsep6aa = Gtk::manage (new Gtk::HSeparator()); + pack_start(*hsep6aa, Gtk::PACK_SHRINK, 2); + hsep6aa->show (); + + Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ()); + hb->set_border_width (4); + hb->show (); + Gtk::Label* ml = Gtk::manage (new Gtk::Label (M("TP_SHARPENING_METHOD")+":")); + ml->show (); + method = Gtk::manage (new Gtk::ComboBoxText ()); + method->append_text (M("TP_SHARPENING_USM")); + method->append_text (M("TP_SHARPENING_RLD")); + method->show (); + hb->pack_start(*ml, Gtk::PACK_SHRINK, 4); + hb->pack_start(*method); + pack_start (*hb); + + rld = new Gtk::VBox (); + dradius = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDRADIUS"), 0.5, 2.5, 0.01, 0.75)); + damount = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_AMOUNT"), 0.0, 100, 1, 75)); + ddamping = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_DAMPING"), 0, 100, 1, 20)); + diter = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_ITERATIONS"), 5, 100, 1, 30)); + rld->pack_start (*dradius); + rld->pack_start (*damount); + rld->pack_start (*ddamping); + rld->pack_start (*diter); + dradius->show (); + damount->show (); + ddamping->show (); + diter->show (); + rld->show (); + + usm = new Gtk::VBox (); + usm->show (); + + + Gtk::HSeparator *hsep6a = Gtk::manage (new Gtk::HSeparator()); + amount = Gtk::manage (new Adjuster (M("TP_SHARPENING_AMOUNT"), 1, 1000, 1, 150)); + radius = Gtk::manage (new Adjuster (M("TP_SHARPENING_RADIUS"), 0.3, 3, 0.01, 0.8)); + threshold = Gtk::manage (new Adjuster (M("TP_SHARPENING_THRESHOLD"), 0, 16384, 1024, 1)); + pack_start(*hsep6a, Gtk::PACK_SHRINK, 2); + + pack_start (*usm); + + usm->pack_start(*radius); + usm->pack_start(*amount); + usm->pack_start(*threshold); + hsep6a->show (); + radius->show (); + amount->show (); + threshold->show (); + + Gtk::HSeparator *hsep6 = Gtk::manage (new Gtk::HSeparator()); + edgesonly = Gtk::manage (new Gtk::CheckButton (M("TP_SHARPENING_ONLYEDGES"))); + edgesonly->set_active (false); + edgebox = new Gtk::VBox (); + eradius = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDRADIUS"), 0.5, 2.5, 0.1, 1.9)); + etolerance = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDTOLERANCE"), 10, 10000, 100, 1000)); + usm->pack_start(*hsep6, Gtk::PACK_SHRINK, 2); + usm->pack_start(*edgesonly); + edgebox->pack_start(*eradius); + edgebox->pack_start(*etolerance); + edgebox->show (); + edgebin = Gtk::manage (new Gtk::VBox ()); + usm->pack_start (*edgebin); + edgebin->show (); + hsep6->show(); + edgesonly->show(); + eradius->show(); + etolerance->show(); + + Gtk::HSeparator *hsep6b = Gtk::manage (new Gtk::HSeparator()); + halocontrol = Gtk::manage (new Gtk::CheckButton (M("TP_SHARPENING_HALOCONTROL"))); + halocontrol->set_active (false); + hcbox = new Gtk::VBox (); + hcamount = Gtk::manage (new Adjuster (M("TP_SHARPENING_HCAMOUNT"), 1, 100, 1, 75)); + usm->pack_start(*hsep6b, Gtk::PACK_SHRINK, 2); + usm->pack_start(*halocontrol); + hcbox->pack_start(*hcamount); + hcbox->show (); + hcbin = Gtk::manage (new Gtk::VBox ()); + usm->pack_start (*hcbin); + hcbin->show (); + hsep6b->show (); + halocontrol->show (); + hcamount->show (); + + dradius->setAdjusterListener (this); + damount->setAdjusterListener (this); + ddamping->setAdjusterListener (this); + diter->setAdjusterListener (this); + radius->setAdjusterListener (this); + amount->setAdjusterListener (this); + threshold->setAdjusterListener (this); + eradius->setAdjusterListener (this); + etolerance->setAdjusterListener (this); + hcamount->setAdjusterListener (this); + + edgebox->reference (); + hcbox->reference (); + usm->reference (); + rld->reference (); + + enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &Sharpening::enabled_toggled) ); + eonlyConn = edgesonly->signal_toggled().connect( sigc::mem_fun(*this, &Sharpening::edgesonly_toggled) ); + hcConn = halocontrol->signal_toggled().connect( sigc::mem_fun(*this, &Sharpening::halocontrol_toggled) ); + method->signal_changed().connect( sigc::mem_fun(*this, &Sharpening::method_changed) ); +} + +Sharpening::~Sharpening () { + + delete usm; + delete rld; + delete edgebox; + delete hcbox; +} + + +void Sharpening::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + amount->setEditedState (pedited->sharpening.amount ? Edited : UnEdited); + radius->setEditedState (pedited->sharpening.radius ? Edited : UnEdited); + threshold->setEditedState (pedited->sharpening.threshold ? Edited : UnEdited); + eradius->setEditedState (pedited->sharpening.edges_radius ? Edited : UnEdited); + etolerance->setEditedState (pedited->sharpening.edges_tolerance ? Edited : UnEdited); + hcamount->setEditedState (pedited->sharpening.halocontrol_amount ? Edited : UnEdited); + damount->setEditedState (pedited->sharpening.deconvamount ? Edited : UnEdited); + dradius->setEditedState (pedited->sharpening.deconvradius ? Edited : UnEdited); + diter->setEditedState (pedited->sharpening.deconviter ? Edited : UnEdited); + ddamping->setEditedState (pedited->sharpening.deconvdamping ? Edited : UnEdited); + + enabled->set_inconsistent (!pedited->sharpening.enabled); + halocontrol->set_inconsistent (!pedited->sharpening.halocontrol); + edgesonly->set_inconsistent (!pedited->sharpening.edgesonly); + } + + enaConn.block (true); + enabled->set_active (pp->sharpening.enabled); + enaConn.block (false); + lastEnabled = pp->sharpening.enabled; + + eonlyConn.block (true); + edgesonly->set_active (pp->sharpening.edgesonly); + eonlyConn.block (false); + lastEdgesOnly = pp->sharpening.edgesonly; + + hcConn.block (true); + halocontrol->set_active (pp->sharpening.halocontrol); + hcConn.block (false); + lastHaloControl = pp->sharpening.halocontrol; + + amount->setValue (pp->sharpening.amount); + radius->setValue (pp->sharpening.radius); + threshold->setValue (pp->sharpening.threshold); + eradius->setValue (pp->sharpening.edges_radius); + etolerance->setValue (pp->sharpening.edges_tolerance); + hcamount->setValue (pp->sharpening.halocontrol_amount); + + dradius->setValue (pp->sharpening.deconvradius); + damount->setValue (pp->sharpening.deconvamount); + diter->setValue (pp->sharpening.deconviter); + ddamping->setValue (pp->sharpening.deconvdamping); + + if (!batchMode) { + removeIfThere (edgebin, edgebox, false); + if (edgesonly->get_active ()) + edgebin->pack_start (*edgebox); + + removeIfThere (hcbin, hcbox, false); + if (halocontrol->get_active ()) + hcbin->pack_start (*hcbox); + + } + if (pedited && !pedited->sharpening.method) + method->set_active (2); + else if (pp->sharpening.method=="usm") + method->set_active (0); + else if (pp->sharpening.method=="rld") + method->set_active (1); + + enableListener (); +} + +void Sharpening::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->sharpening.amount = (int)amount->getValue(); + pp->sharpening.enabled = enabled->get_active (); + pp->sharpening.radius = radius->getValue (); + pp->sharpening.threshold = (int)threshold->getValue (); + pp->sharpening.edgesonly = edgesonly->get_active (); + pp->sharpening.edges_radius = eradius->getValue (); + pp->sharpening.edges_tolerance = (int)etolerance->getValue (); + pp->sharpening.halocontrol = halocontrol->get_active (); + pp->sharpening.halocontrol_amount = (int)hcamount->getValue (); + pp->sharpening.deconvradius = dradius->getValue (); + pp->sharpening.deconviter = (int)diter->getValue (); + pp->sharpening.deconvamount = (int)damount->getValue (); + pp->sharpening.deconvdamping = (int)ddamping->getValue (); + + if (method->get_active_row_number()==0) + pp->sharpening.method = "usm"; + else if (method->get_active_row_number()==1) + pp->sharpening.method = "rld"; + + if (pedited) { + pedited->sharpening.amount = amount->getEditedState (); + pedited->sharpening.radius = radius->getEditedState (); + pedited->sharpening.threshold = threshold->getEditedState (); + pedited->sharpening.edges_radius = eradius->getEditedState (); + pedited->sharpening.edges_tolerance = etolerance->getEditedState (); + pedited->sharpening.halocontrol_amount = hcamount->getEditedState (); + pedited->sharpening.deconvamount = damount->getEditedState (); + pedited->sharpening.deconvradius = dradius->getEditedState (); + pedited->sharpening.deconviter = diter->getEditedState (); + pedited->sharpening.deconvdamping = ddamping->getEditedState (); + pedited->sharpening.method = method->get_active_row_number()!=2; + pedited->sharpening.halocontrol = !halocontrol->get_inconsistent(); + pedited->sharpening.edgesonly = !edgesonly->get_inconsistent(); + pedited->sharpening.enabled = !enabled->get_inconsistent(); + } +} + +void Sharpening::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + amount->setDefault (defParams->sharpening.amount); + radius->setDefault (defParams->sharpening.radius); + threshold->setDefault (defParams->sharpening.threshold); + eradius->setDefault (defParams->sharpening.edges_radius); + etolerance->setDefault (defParams->sharpening.edges_tolerance); + hcamount->setDefault (defParams->sharpening.halocontrol_amount); + damount->setDefault (defParams->sharpening.deconvamount); + dradius->setDefault (defParams->sharpening.deconvradius); + diter->setDefault (defParams->sharpening.deconviter); + ddamping->setDefault (defParams->sharpening.deconvdamping); + + if (pedited) { + amount->setDefaultEditedState (pedited->sharpening.amount ? Edited : UnEdited); + radius->setDefaultEditedState (pedited->sharpening.radius ? Edited : UnEdited); + threshold->setDefaultEditedState (pedited->sharpening.threshold ? Edited : UnEdited); + eradius->setDefaultEditedState (pedited->sharpening.edges_radius ? Edited : UnEdited); + etolerance->setDefaultEditedState (pedited->sharpening.edges_tolerance ? Edited : UnEdited); + hcamount->setDefaultEditedState (pedited->sharpening.halocontrol_amount ? Edited : UnEdited); + damount->setDefaultEditedState (pedited->sharpening.deconvamount ? Edited : UnEdited); + dradius->setDefaultEditedState (pedited->sharpening.deconvradius ? Edited : UnEdited); + diter->setDefaultEditedState (pedited->sharpening.deconviter ? Edited : UnEdited); + ddamping->setDefaultEditedState (pedited->sharpening.deconvdamping ? Edited : UnEdited); + } + else { + amount->setDefaultEditedState (Irrelevant); + radius->setDefaultEditedState (Irrelevant); + threshold->setDefaultEditedState (Irrelevant); + eradius->setDefaultEditedState (Irrelevant); + etolerance->setDefaultEditedState (Irrelevant); + hcamount->setDefaultEditedState (Irrelevant); + damount->setDefaultEditedState (Irrelevant); + dradius->setDefaultEditedState (Irrelevant); + diter->setDefaultEditedState (Irrelevant); + ddamping->setDefaultEditedState (Irrelevant); + } +} + +void Sharpening::adjusterChanged (Adjuster* a, double newval) { + + if (listener && enabled->get_active()) { + + Glib::ustring costr; + if (a==radius || a==dradius) + costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue()); + else if (a==eradius) + costr = Glib::ustring::format (std::setw(2), std::fixed, std::setprecision(1), a->getValue()); + else + costr = Glib::ustring::format ((int)a->getValue()); + + if (a==amount) + listener->panelChanged (EvShrAmount, costr); + else if (a==radius) + listener->panelChanged (EvShrRadius, costr); + else if (a==threshold) + listener->panelChanged (EvShrThresh, costr); + else if (a==eradius) + listener->panelChanged (EvShrEdgeRadius, costr); + else if (a==etolerance) + listener->panelChanged (EvShrEdgeTolerance, costr); + else if (a==hcamount) + listener->panelChanged (EvShrHaloAmount, costr); + else if (a==dradius) + listener->panelChanged (EvShrDRadius, costr); + else if (a==damount) + listener->panelChanged (EvShrDAmount, costr); + else if (a==ddamping) + listener->panelChanged (EvShrDDamping, costr); + else if (a==diter) + listener->panelChanged (EvShrDIterations, costr); + } +} + +void Sharpening::enabled_toggled () { + + if (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaConn.block (true); + enabled->set_active (false); + enaConn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_active ()) + listener->panelChanged (EvShrEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvShrEnabled, M("GENERAL_DISABLED")); + } +} + +void Sharpening::edgesonly_toggled () { + + if (batchMode) { + if (edgesonly->get_inconsistent()) { + edgesonly->set_inconsistent (false); + eonlyConn.block (true); + edgesonly->set_active (false); + eonlyConn.block (false); + } + else if (lastEdgesOnly) + edgesonly->set_inconsistent (true); + + lastEdgesOnly = edgesonly->get_active (); + } + + if (!batchMode) { + removeIfThere (edgebin, edgebox, false); + if (edgesonly->get_active ()) + edgebin->pack_start (*edgebox); + } + + if (listener && enabled->get_active()) { + if (edgesonly->get_active ()) + listener->panelChanged (EvShrEdgeOnly, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvShrEdgeOnly, M("GENERAL_DISABLED")); + } +} + +void Sharpening::halocontrol_toggled () { + + if (batchMode) { + if (halocontrol->get_inconsistent()) { + halocontrol->set_inconsistent (false); + hcConn.block (true); + halocontrol->set_active (false); + hcConn.block (false); + } + else if (lastHaloControl) + halocontrol->set_inconsistent (true); + + lastHaloControl = halocontrol->get_active (); + } + + if (!batchMode) { + removeIfThere (hcbin, hcbox, false); + if (halocontrol->get_active ()) + hcbin->pack_start (*hcbox); + } + + if (listener && enabled->get_active()) { + if (halocontrol->get_active ()) + listener->panelChanged (EvShrHaloControl, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvShrHaloControl, M("GENERAL_DISABLED")); + } +} + +void Sharpening::method_changed () { + + removeIfThere (this, usm, false); + removeIfThere (this, rld, false); + + if (method->get_active_row_number()==0) + pack_start (*usm); + else if (method->get_active_row_number()==1) + pack_start (*rld); + + if (listener && enabled->get_active ()) + listener->panelChanged (EvShrMethod, method->get_active_text ()); + +} + +void Sharpening::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + + removeIfThere (hcbin, hcbox, false); + hcbin->pack_start (*hcbox); + removeIfThere (edgebin, edgebox, false); + edgebin->pack_start (*edgebox); + + radius->showEditedCB (); + amount->showEditedCB (); + threshold->showEditedCB (); + eradius->showEditedCB (); + etolerance->showEditedCB (); + hcamount->showEditedCB (); + dradius->showEditedCB (); + damount->showEditedCB (); + ddamping->showEditedCB (); + diter->showEditedCB (); + method->append_text (M("GENERAL_UNCHANGED")); +} + +void Sharpening::setAdjusterBehavior (bool bamountadd) { + + if (!amountAdd && bamountadd) { + amount->setLimits (-100, 100, 1, 0); + damount->setLimits (-100, 100, 1, 0); + } + else if (amountAdd && !bamountadd) { + amount->setLimits (1, 1000, 1, 150); + damount->setLimits (0, 100, 1, 75); + } + amountAdd = bamountadd; +} diff --git a/rtgui/sharpening.h b/rtgui/sharpening.h new file mode 100644 index 000000000..cb3ad2a43 --- /dev/null +++ b/rtgui/sharpening.h @@ -0,0 +1,79 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _SHARPENING_H_ +#define _SHARPENING_H_ + +#include +#include +#include + +class Sharpening : public Gtk::VBox, public AdjusterListener, public ToolPanel { + + protected: + Gtk::ComboBoxText* method; + Adjuster* dradius; + Adjuster* damount; + Adjuster* ddamping; + Adjuster* diter; + Gtk::VBox* usm; + Gtk::VBox* rld; + + Adjuster* radius; + Adjuster* amount; + Adjuster* threshold; + Adjuster* eradius; + Adjuster* etolerance; + Adjuster* hcamount; + Gtk::VBox* edgebin; + Gtk::VBox* hcbin; + Gtk::VBox* edgebox; + Gtk::VBox* hcbox; + Gtk::CheckButton* enabled; + bool lastEnabled; + sigc::connection enaConn; + Gtk::CheckButton* edgesonly; + bool lastEdgesOnly; + sigc::connection eonlyConn; + Gtk::CheckButton* halocontrol; + bool lastHaloControl; + sigc::connection hcConn; + bool amountAdd; + + + + public: + + Sharpening (); + virtual ~Sharpening (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void enabled_toggled (); + void edgesonly_toggled (); + void halocontrol_toggled (); + void method_changed (); + + void setAdjusterBehavior (bool bamountadd); +}; + +#endif diff --git a/rtgui/shcselector.cc b/rtgui/shcselector.cc new file mode 100644 index 000000000..0b699e052 --- /dev/null +++ b/rtgui/shcselector.cc @@ -0,0 +1,166 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ + +#include +#include + +SHCSelector::SHCSelector() : movingPosition(-1), cl(NULL) { + + positions[0] = 0.25; + positions[1] = 0.5; + positions[2] = 0.75; +} + +void SHCSelector::setPositions (double spos, double cpos, double hpos) { + + positions[0] = spos; + positions[1] = cpos; + positions[2] = hpos; + + queue_draw (); +} + +void SHCSelector::getPositions (double& spos, double& cpos, double& hpos) { + + spos = positions[0]; + cpos = positions[1]; + hpos = positions[2]; +} + +void SHCSelector::on_realize() { + + Gtk::DrawingArea::on_realize(); + + add_events(Gdk::EXPOSURE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK); +} + +bool SHCSelector::on_expose_event(GdkEventExpose* event) { + + Cairo::RefPtr cr = get_window()->create_cairo_context(); + + int w = get_width (); + int h = get_height (); + + wslider = h *2.0 / 5.0; + + Gdk::Color bgc = get_style()->get_bg (Gtk::STATE_NORMAL); + Gdk::Color fgc = get_style()->get_text (Gtk::STATE_NORMAL); + + // clear bg + cr->set_source_rgb (bgc.get_red_p(), bgc.get_green_p(), bgc.get_blue_p()); + cr->rectangle (0, 0, w, h); + cr->fill(); + + // draw gradient background + Cairo::RefPtr< Cairo::LinearGradient > bggradient = Cairo::LinearGradient::create (0, 0, w, 0); + bggradient->add_color_stop_rgb (0, 0, 0, 0); + bggradient->add_color_stop_rgb (1, 1, 1, 1); + + cr->set_line_width (1.0); + cr->set_source (bggradient); + cr->rectangle (0.5, h*2.0/7.0 + 0.5, w-0.5, h*3.0/7.0-0.5); + cr->fill_preserve(); + cr->set_source_rgb (fgc.get_red_p(), fgc.get_green_p(), fgc.get_blue_p()); + cr->stroke (); + + // draw sliders + cr->set_line_width (1.0); + for (int i=0; i<3; i++) { + cr->move_to (w*positions[i]-wslider/2+0.5, h-0.5); + cr->line_to (w*positions[i]-wslider/2+0.5, wslider/2 + 0.5); + cr->line_to (w*positions[i], 0.5); + cr->line_to (w*positions[i]+wslider/2-0.5, wslider/2 + 0.5); + cr->line_to (w*positions[i]+wslider/2-0.5, h-0.5); + cr->line_to (w*positions[i]-wslider/2+0.5, h-0.5); + cr->set_source_rgb (bgc.get_red_p(), bgc.get_green_p(), bgc.get_blue_p()); + cr->fill_preserve (); + cr->set_source_rgb (fgc.get_red_p(), fgc.get_green_p(), fgc.get_blue_p()); + cr->stroke (); + } + + // draw text for the slider that is being moved + Glib::RefPtr context = get_pango_context () ; + cr->set_line_width (0.5); + if (movingPosition >= 0) { + int i = movingPosition; + Glib::RefPtr layout = create_pango_layout(Glib::ustring::format(std::setprecision(2), positions[i])); + cr->move_to (w*positions[i]+wslider/2-0.5, 0); + cr->set_source_rgb (bgc.get_red_p(), bgc.get_green_p(), bgc.get_blue_p()); + layout->add_to_cairo_context (cr); + cr->fill_preserve (); + cr->stroke (); + cr->move_to (w*positions[i]+wslider/2+0.5, 1); + layout->add_to_cairo_context (cr); + cr->fill_preserve (); + cr->stroke (); + cr->set_source_rgb (fgc.get_red_p(), fgc.get_green_p(), fgc.get_blue_p()); + cr->move_to (w*positions[i]+wslider/2, 0.5); + layout->add_to_cairo_context (cr); + cr->fill_preserve (); + cr->stroke (); + } +} + +bool SHCSelector::on_button_press_event (GdkEventButton* event) { + + // check if a slider is under the cursor + int w = get_width (); + movingPosition = -1; + for (int i=0; i<3; i++) + if (event->x > w*positions[i]-wslider/2 && event->x < w*positions[i]+wslider/2) { + movingPosition = i; + tmpX = event->x; + tmpPos = positions[i]; + break; + } + queue_draw (); +} + +bool SHCSelector::on_button_release_event (GdkEventButton* event) { + + if (movingPosition >= 0) { + movingPosition = -1; + queue_draw (); + } +} + +bool SHCSelector::on_motion_notify_event (GdkEventMotion* event) { + + if (movingPosition >= 0) { + int w = get_width (); + positions[movingPosition] = tmpPos + (event->x - tmpX) / w; + if (positions[movingPosition] < 0) + positions[movingPosition] = 0.0; + else if (movingPosition > 0 && positions[movingPosition] < positions[movingPosition-1]+wslider/w) + positions[movingPosition] = positions[movingPosition-1]+wslider/w; + if (positions[movingPosition] > 1.0) + positions[movingPosition] = 1.0; + else if (movingPosition <3 && positions[movingPosition] > positions[movingPosition+1]-wslider/w) + positions[movingPosition] = positions[movingPosition+1]-wslider/w; + + if (cl) + cl->shcChanged (); + queue_draw (); + } +} + +void SHCSelector::styleChanged (const Glib::RefPtr& style) { + + queue_draw (); +} diff --git a/rtgui/shcselector.h b/rtgui/shcselector.h new file mode 100644 index 000000000..3199e4ae9 --- /dev/null +++ b/rtgui/shcselector.h @@ -0,0 +1,61 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _SHCSELECTOR_ +#define _SHCSELECTOR_ + +#include + +class SHCListener { + public: + virtual void shcChanged () {} +}; + +class SHCSelector : public Gtk::DrawingArea { + + protected: + + Glib::RefPtr gc_; + Glib::RefPtr backBuffer; + + int movingPosition; + double tmpX, tmpPos; + + double positions[3]; + double wslider; + + SHCListener* cl; + + public: + + SHCSelector(); + + void setSHCListener (SHCListener* l) { cl = l;; } + + void setPositions (double spos, double cpos, double hpos); + void getPositions (double& spos, double& cpos, double& hpos); + void on_realize(); + bool on_expose_event(GdkEventExpose* event); + bool on_button_press_event (GdkEventButton* event); + bool on_button_release_event (GdkEventButton* event); + bool on_motion_notify_event (GdkEventMotion* event); + void styleChanged (const Glib::RefPtr& style); +}; + +#endif + diff --git a/rtgui/splash.cc b/rtgui/splash.cc new file mode 100644 index 000000000..222742409 --- /dev/null +++ b/rtgui/splash.cc @@ -0,0 +1,98 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +extern Glib::ustring argv0; +extern Glib::ustring versionString; + +SplashImage::SplashImage () { + + pixbuf = safe_create_from_file (argv0+"/images/splash.png"); + set_size_request (pixbuf->get_width(), pixbuf->get_height()); +} + +void SplashImage::on_realize () { + + Gtk::DrawingArea::on_realize(); + add_events(Gdk::EXPOSURE_MASK); + + gc_ = Gdk::GC::create (get_window()); + Glib::RefPtr colormap = get_default_colormap(); + Gdk::Color fontc = Gdk::Color ("white"); + colormap->alloc_color (fontc); + gc_->set_foreground (fontc); + +} + +bool SplashImage::on_expose_event (GdkEventExpose* event) { + + Glib::RefPtr window = get_window(); + pixbuf->render_to_drawable (window, gc_, 0, 0, 0, 0, pixbuf->get_width(), pixbuf->get_height(), Gdk::RGB_DITHER_NONE, 0, 0); + + Cairo::FontOptions cfo; + cfo.set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + Glib::RefPtr context = get_pango_context () ; + context->set_cairo_font_options (cfo); + Pango::FontDescription fontd = context->get_font_description (); + fontd.set_weight (Pango::WEIGHT_SEMIBOLD); + fontd.set_size (12*Pango::SCALE); + context->set_font_description (fontd); + + version = create_pango_layout (versionString); + int w, h; + version->get_pixel_size (w, h); + window->draw_layout(gc_, pixbuf->get_width() - w - 28, 44-h, version); + + return true; +} + +Splash::Splash (int maxtime) { + + set_title (M("GENERAL_ABOUT")); + + splashImage = new SplashImage (); +// add (*splashImage); + get_vbox()->pack_start (*splashImage); + set_has_separator (false); + splashImage->show (); + + if (maxtime>0) + Glib::signal_timeout().connect (sigc::mem_fun(*this, &Splash::on_timer), maxtime); + set_position (Gtk::WIN_POS_CENTER); + if (maxtime>0) + set_decorated (false); + add_events(Gdk::BUTTON_RELEASE_MASK); + set_resizable (false); + + set_keep_above (true); +} + +bool Splash::on_timer () { + + hide (); + return false; +} + +bool Splash::on_button_release_event (GdkEventButton* event) { + + hide (); + return true; +} diff --git a/rtgui/splash.h b/rtgui/splash.h new file mode 100644 index 000000000..b8c1b38af --- /dev/null +++ b/rtgui/splash.h @@ -0,0 +1,50 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef __SPLASH__ +#define __SPLASH__ + +#include + +class SplashImage : public Gtk::DrawingArea { + + private: + Glib::RefPtr gc_; + Glib::RefPtr pixbuf; + Glib::RefPtr version; + + public: + SplashImage (); + void on_realize (); + bool on_expose_event (GdkEventExpose* event); +}; + +//class Splash : public Gtk::Window { +class Splash : public Gtk::Dialog { + + private: + SplashImage* splashImage; + + public: + Splash (int maxtime); + + bool on_timer (); + virtual bool on_button_release_event (GdkEventButton* event); +}; + +#endif diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc new file mode 100644 index 000000000..0dd697641 --- /dev/null +++ b/rtgui/thumbbrowserbase.cc @@ -0,0 +1,548 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include + +ThumbBrowserBase::ThumbBrowserBase () + : previewHeight(options.thumbSize), lastClicked(NULL) { + + inW = -1; inH = -1; + + Gtk::HBox* hb1 = new Gtk::HBox (); + Gtk::HBox* hb2 = new Gtk::HBox (); + Gtk::Frame* frame = new Gtk::Frame (); + frame->add (internal); + frame->set_shadow_type (Gtk::SHADOW_IN ); + hb1->pack_start (*frame); + hb1->pack_end (vscroll, Gtk::PACK_SHRINK, 0); + + pack_start (*hb1); + + Gtk::HBox* tmp = new Gtk::HBox (); + hb2->pack_start (hscroll); + Gtk::Requisition vcr = vscroll.size_request (); + tmp->set_size_request (vcr.width, vcr.width); + hb2->pack_end (*tmp, Gtk::PACK_SHRINK, 0); + + pack_start (*hb2,Gtk::PACK_SHRINK, 0); + + internal.setParent (this); + + show_all (); + + hscroll.set_update_policy (Gtk::UPDATE_CONTINUOUS); + vscroll.set_update_policy (Gtk::UPDATE_CONTINUOUS); + + vscroll.signal_value_changed().connect( sigc::mem_fun(*this, &ThumbBrowserBase::scrollChanged) ); + hscroll.signal_value_changed().connect( sigc::mem_fun(*this, &ThumbBrowserBase::scrollChanged) ); + + internal.signal_size_allocate().connect( sigc::mem_fun(*this, &ThumbBrowserBase::internalAreaResized) ); + signal_style_changed().connect( sigc::mem_fun(*this, &ThumbBrowserBase::styleChanged) ); +} + +void ThumbBrowserBase::scrollChanged () { + + for (int i=0; isetOffset ((int)(hscroll.get_value()), (int)(vscroll.get_value())); + + internal.setPosition ((int)(hscroll.get_value()), (int)(vscroll.get_value())); + + if (!internal.isDirty()) { + internal.setDirty (); + internal.queue_draw (); +// gdk_window_process_updates (get_window()->gobj(), true); + } +} + +void ThumbBrowserBase::scroll (int direction) { + + if (arrangement==TB_Vertical) + vscroll.set_value (vscroll.get_value() + (direction==GDK_SCROLL_DOWN ? +1 : -1) * vscroll.get_adjustment()->get_step_increment()); + else + hscroll.set_value (hscroll.get_value() + (direction==GDK_SCROLL_DOWN ? +1 : -1) * hscroll.get_adjustment()->get_step_increment()); +} + +void ThumbBrowserBase::resizeThumbnailArea (int w, int h) { + + inW = w; + inH = h; + + if (hscroll.get_value() + internal.get_width() > inW) + hscroll.set_value (inW - internal.get_width()); + if (vscroll.get_value() + internal.get_height() > inH) + vscroll.set_value (inH - internal.get_height()); + + configScrollBars (); +} + +void ThumbBrowserBase::internalAreaResized (Gtk::Allocation& req) { + + if (inW>0 && inH>0) { + configScrollBars (); + redraw (); + } +} + +void ThumbBrowserBase::configScrollBars () { + + if (inW>0 && inH>0) { + + int iw = internal.get_width (); + int ih = internal.get_height (); + + hscroll.get_adjustment()->set_upper (inW); + vscroll.get_adjustment()->set_upper (inH); + hscroll.get_adjustment()->set_lower (0); + vscroll.get_adjustment()->set_lower (0); + hscroll.get_adjustment()->set_step_increment (32); + vscroll.get_adjustment()->set_step_increment (32); + hscroll.get_adjustment()->set_page_increment (iw); + vscroll.get_adjustment()->set_page_increment (ih); + hscroll.get_adjustment()->set_page_size (iw); + vscroll.get_adjustment()->set_page_size (ih); + } +} + +void ThumbBrowserBase::arrangeFiles () { + + int N = fd.size (); + // apply filter + for (int i=0; ifiltered = !checkFilter (fd[i]); + + int rowHeight = 0; + // compute size of the items + for (int i=0; ifiltered && fd[i]->getMinimalHeight() > rowHeight) + rowHeight = fd[i]->getMinimalHeight (); + + if (arrangement==TB_Horizontal) { + + int numOfRows = 1; + if (rowHeight>0) { + numOfRows = (internal.get_height()+rowHeight/2)/rowHeight; + if (numOfRows<1) + numOfRows = 1; + } + + int ct = 0; + int currx = 0; int curry = 0; + while (ctgetMinimalWidth() > maxw) + maxw = fd[ct+i]->getMinimalWidth (); + + // arrange items in the column + curry = 0; + for (int i=0; ctfiltered) + fd[ct++]->drawable = false; + if (ctsetPosition (currx, curry, maxw, rowHeight); + fd[ct]->drawable = true; + curry += rowHeight; + } + } + currx += maxw; + } + resizeThumbnailArea (currx, numOfRows*rowHeight); + } + else { + int availWidth = internal.get_width(); + // initial number of columns + int numOfCols = 0; + int currColNum = 0; + int colsWidth = 0; + for (int i=0; ifiltered && colsWidth + fd[i]->getMinimalWidth() <= availWidth) { + colsWidth += fd[numOfCols]->getMinimalWidth (); + numOfCols++; + } + if (numOfCols<1) + numOfCols = 1; + std::vector colWidths; + for (; numOfCols>0; numOfCols--) { + // compute column widths + colWidths.resize (numOfCols); + for (int i=0; ifiltered && fd[i]->getMinimalWidth() > colWidths[j%numOfCols]) + colWidths[j%numOfCols] = fd[i]->getMinimalWidth (); + if (!fd[i]->filtered) + j++; + } + // if not wider than the space available, arrange it and we are ready + colsWidth = 0; + for (int i=0; ifiltered) + fd[ct++]->drawable = false; + if (ctsetPosition (currx, curry, colWidths[i%numOfCols], rowHeight); + fd[ct]->drawable = true; + currx += colWidths[i%numOfCols]; + } + } + if (currx>0) // there were thumbnails placed in the row + curry += rowHeight; + } + resizeThumbnailArea (colsWidth, curry); + } +} + + +void ThumbBrowserBase::Internal::on_realize() +{ + Cairo::FontOptions cfo; + cfo.set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + get_pango_context()->set_cairo_font_options (cfo); + + Gtk::DrawingArea::on_realize(); + Glib::RefPtr window = get_window(); + set_flags (Gtk::CAN_FOCUS); + add_events(Gdk::EXPOSURE_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::SCROLL_MASK | Gdk::KEY_PRESS_MASK); + gc_ = Gdk::GC::create(window); + set_has_tooltip (true); + signal_query_tooltip().connect( sigc::mem_fun(*this, &ThumbBrowserBase::Internal::on_query_tooltip) ); +} + +bool ThumbBrowserBase::Internal::on_query_tooltip (int x, int y, bool keyboard_tooltip, const Glib::RefPtr& tooltip) { + + Glib::ustring ttip = ""; + for (int i=0; ifd.size(); i++) + if (parent->fd[i]->drawable && parent->fd[i]->inside (x, y)) { + ttip = parent->fd[i]->getToolTip (x, y); + break; + } + if (ttip!="") { + tooltip->set_text (ttip); + return true; + } + else + return false; +} + +void ThumbBrowserBase::styleChanged (const Glib::RefPtr& style) { + + refreshThumbImages (); +} + +ThumbBrowserBase::Internal::Internal () : parent(NULL), ofsX(0), ofsY(0), dirty(true) { +} + +void ThumbBrowserBase::Internal::setParent (ThumbBrowserBase* p) { + + parent = p; +} + +void ThumbBrowserBase::Internal::setPosition (int x, int y) { + + ofsX = x; + ofsY = y; +} + +bool ThumbBrowserBase::Internal::on_key_press_event (GdkEventKey* event) { + + return parent->keyPressed (event); +} + +bool ThumbBrowserBase::Internal::on_button_press_event (GdkEventButton* event) { + + grab_focus (); + + parent->eventTime = event->time; + + parent->buttonPressed ((int)event->x, (int)event->y, event->button, event->type, event->state, 0, 0, get_width(), get_height()); + Glib::RefPtr window = get_window(); + + GdkRectangle rect; + rect.x = 0; + rect.y = 0; + window->get_size (rect.width, rect.height); + + gdk_window_invalidate_rect (window->gobj(), &rect, true); + gdk_window_process_updates (window->gobj(), true); + return true; +} + +void ThumbBrowserBase::buttonPressed (int x, int y, int button, GdkEventType type, int state, int clx, int cly, int clw, int clh) { + + ThumbBrowserEntryBase* fileDescr = NULL; + bool handled = false; + for (int i=0; idrawable) { + if (fd[i]->inside (x, y) && fd[i]->insideWindow (clx, cly, clw, clh)) + fileDescr = fd[i]; + bool b = fd[i]->pressNotify (button, type, state, x, y); + handled = handled || b; + } + + if (handled || (fileDescr && fileDescr->processing)) + return; + + if (selected.size()==1 && type==GDK_2BUTTON_PRESS && button==1) + doubleClicked (selected[0]); + else if (button==1 && type==GDK_BUTTON_PRESS) { + if (fileDescr && state & GDK_SHIFT_MASK) { + if (selected.size()==0) { + selected.push_back (fileDescr); + fileDescr->selected = true; + lastClicked = fileDescr; + selectionChanged (); + } + else { + // find the start and the end of the selection interval + int startx = fd.size()-1; + if (lastClicked) { + for (; startx>=0; startx--) + if (fd[startx]==lastClicked) + break; + } + else { + for (; startx>=0; startx--) + if (fd[startx]==selected[0]) + break; + } + int endx = 0; + for (; endxselected = false; + selected.clear (); + // select thumbnails in the interval + for (int i=startx; i<=endx; i++) { + if (!fd[i]->filtered) { + fd[i]->selected = true; + selected.push_back (fd[i]); + } + } + selectionChanged (); + } + } + else if (fileDescr && state & GDK_CONTROL_MASK) { + std::vector::iterator i = std::find (selected.begin(), selected.end(), fileDescr); + if (i!=selected.end()) { + (*i)->selected = false; + selected.erase (i); + } + else { + selected.push_back (fileDescr); + fileDescr->selected = true; + } + lastClicked = fileDescr; + selectionChanged (); + } + else { + for (int i=0; iselected = false; + selected.clear (); + if (fileDescr) { + selected.push_back (fileDescr); + fileDescr->selected = true; + } + lastClicked = fileDescr; + selectionChanged (); + } + } + else if (fileDescr && button==3 && type==GDK_BUTTON_PRESS) { + if (!fileDescr->selected) { + for (int i=0; iselected = false; + selected.clear (); + fileDescr->selected = true; + selected.push_back (fileDescr); + lastClicked = fileDescr; + selectionChanged (); + } + rightClicked (fileDescr); + } +} + +bool ThumbBrowserBase::Internal::on_expose_event(GdkEventExpose* event) { + + dirty = false; + + Glib::RefPtr window = get_window(); + + int w = get_width(); + int h = get_height(); + + window->clear(); + // draw thumbnails + Glib::RefPtr context = get_pango_context (); + context->set_font_description (get_style()->get_font()); + for (int i=0; ifd.size(); i++) { + if (!parent->fd[i]->drawable || !parent->fd[i]->insideWindow (0, 0, w, h)) + parent->fd[i]->updatepriority = false; + else { + parent->fd[i]->updatepriority = true; + parent->fd[i]->draw (); + } + } + + return true; +} + +bool ThumbBrowserBase::Internal::on_button_release_event (GdkEventButton* event) { + + int w = get_width(); + int h = get_height(); + + for (int i=0; ifd.size(); i++) + if (parent->fd[i]->drawable && parent->fd[i]->insideWindow (0, 0, w, h)) + parent->fd[i]->releaseNotify (event->button, event->type, event->state, (int)event->x, (int)event->y); + return true; +} + +bool ThumbBrowserBase::Internal::on_motion_notify_event (GdkEventMotion* event) { + + int w = get_width(); + int h = get_height(); + + for (int i=0; ifd.size(); i++) + if (parent->fd[i]->drawable && parent->fd[i]->insideWindow (0, 0, w, h)) + parent->fd[i]->motionNotify ((int)event->x, (int)event->y); + return true; +} + +bool ThumbBrowserBase::Internal::on_scroll_event (GdkEventScroll* event) { + + parent->scroll (event->direction); + return true; +} + + +void ThumbBrowserBase::redraw () { + + arrangeFiles (); + queue_draw (); +} + +void ThumbBrowserBase::zoomChanged (bool zoomIn) { + + int newHeight; + int i=0; + if (zoomIn) + for (i=0; i options.thumbSize) + break; + } + else + for (i=options.thumbnailZoomRatios.size()-1; i>=0; i--) { + newHeight = (int)(options.thumbnailZoomRatios[i] * options.maxThumbnailHeight); + if (newHeight < options.thumbSize) + break; + } + previewHeight = options.thumbSize = newHeight; + for (int i=0; iresize (previewHeight); + redraw (); +#ifdef _WIN32 + gdk_window_process_updates (get_window()->gobj(), true); +#endif +} +void ThumbBrowserBase::refreshThumbImages () { + + for (int i=0; iresize (previewHeight); // TODO!!! Might be performance bottleneck + fd[i]->refreshThumbnailImage (); + } + + redraw (); +} + +void ThumbBrowserBase::refreshEditedState (const std::set& efiles) { + + editedFiles = efiles; + for (int i=0; iframed = editedFiles.find (fd[i]->filename)!=editedFiles.end(); + queue_draw (); +} + +void ThumbBrowserBase::setArrangement (Arrangement a) { + + arrangement = a; + redraw (); +} + +void ThumbBrowserBase::initEntry (ThumbBrowserEntryBase* entry) { + + entry->setOffset ((int)(hscroll.get_value()), (int)(vscroll.get_value())); +} +void ThumbBrowserBase::getScrollPosition (double& h, double& v) { + + h = hscroll.get_value (); + v = vscroll.get_value (); +} + +void ThumbBrowserBase::setScrollPosition (double h, double v) { + + hscroll.set_value (h>hscroll.get_adjustment()->get_upper() ? hscroll.get_adjustment()->get_upper() : h); + vscroll.set_value (v>vscroll.get_adjustment()->get_upper() ? vscroll.get_adjustment()->get_upper() : v); +} + +/*void PreviewImgUpdater::processCustomOrder () { + + // find first filtered entry, if any + std::list::iterator i; + for (i=jqueue.begin (); i!=jqueue.end(); i++) + if (!(*i)->filtered) + break; + if (i==jqueue.end()) + i = jqueue.begin(); + + ThumbBrowserEntryBase* current = *i; + jqueue.erase (i); + + current->updateImg (); + if (parent) { + gdk_threads_enter (); + parent->queue_draw (); + if (parent->get_window()) + gdk_window_process_updates (parent->get_window()->gobj(), true); + gdk_threads_leave (); + } +} +*/ + diff --git a/rtgui/thumbbrowserbase.h b/rtgui/thumbbrowserbase.h new file mode 100644 index 000000000..80ae72299 --- /dev/null +++ b/rtgui/thumbbrowserbase.h @@ -0,0 +1,118 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _THUMBNAILBROWSERBASE_ +#define _THUMBNAILBROWSERBASE_ + +#include +#include +#include + +class ThumbBrowserBase : public Gtk::VBox { + + class Internal : public Gtk::DrawingArea { + + Glib::RefPtr gc_; + int ofsX, ofsY; + ThumbBrowserBase* parent; + bool dirty; + public: + Internal (); + void setParent (ThumbBrowserBase* p); + void on_realize(); + bool on_expose_event(GdkEventExpose* event); + bool on_button_press_event (GdkEventButton* event); + bool on_button_release_event (GdkEventButton* event); + bool on_motion_notify_event (GdkEventMotion* event); + bool on_scroll_event (GdkEventScroll* event); + bool on_key_press_event (GdkEventKey* event); + bool on_query_tooltip (int x, int y, bool keyboard_tooltip, const Glib::RefPtr& tooltip); + void setPosition (int x, int y); + + void setDirty () { dirty = true; } + bool isDirty () { return dirty; } + }; + + protected: + + Internal internal; + Gtk::HScrollbar hscroll; + Gtk::VScrollbar vscroll; + + int inW, inH; + + void resizeThumbnailArea (int w, int h); + void internalAreaResized (Gtk::Allocation& req); + void buttonPressed (int x, int y, int button, GdkEventType type, int state, int clx, int cly, int clw, int clh); + + public: + + enum Arrangement {TB_Horizontal, TB_Vertical}; + void configScrollBars (); + void scrollChanged (); + void scroll (int direction); + + protected: + + int eventTime; + + std::vector fd; + std::vector selected; + ThumbBrowserEntryBase* lastClicked; + + int previewHeight; + + Arrangement arrangement; + + std::set editedFiles; + + void arrangeFiles (); + void zoomChanged (bool zoomIn); + + public: + + ThumbBrowserBase (); + + void zoomIn () { zoomChanged (true); } + void zoomOut () { zoomChanged (false); } + + const std::vector& getEntries () { return fd; } + void styleChanged (const Glib::RefPtr& style); + void redraw (); // arrange files and draw area + void refreshThumbImages (); // refresh thumbnail sizes, re-generate thumbnail images, arrange and draw + void refreshEditedState (const std::set& efiles); + + void initEntry (ThumbBrowserEntryBase* entry); + + void getScrollPosition (double& h, double& v); + void setScrollPosition (double h, double v); + + void setArrangement (Arrangement a); + virtual bool checkFilter (ThumbBrowserEntryBase* entry) { return true; } + virtual void rightClicked (ThumbBrowserEntryBase* entry) {} + virtual void doubleClicked (ThumbBrowserEntryBase* entry) {} + virtual bool keyPressed (GdkEventKey* event) {return true;} + virtual void selectionChanged () {} + + virtual void redrawNeeded (ThumbBrowserEntryBase* entry) {} + virtual void thumbRearrangementNeeded () {} + + Gtk::Widget* getDrawingArea () { return &internal; } +}; + +#endif diff --git a/rtgui/thumbbrowserentry.cc b/rtgui/thumbbrowserentry.cc new file mode 100644 index 000000000..79531775b --- /dev/null +++ b/rtgui/thumbbrowserentry.cc @@ -0,0 +1,63 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include + +FileBrowserEntry::FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname) + : ThumbBrowserEntryBase (fname), thumbnail(thm) { + + previewOwner = false; + italicstyle = thumbnail->getType() != FT_Raw; + datetimeline = thumbnail->getDateTimeString (); + exifline = thumbnail->getExifString (); +} + +void ThumbBrowserEntry::obtainThumbnailImage () { + + preview = thumbnail ? (guint8*) thumbnail->getThumbnailImage (prew, preh) : NULL; +} + +void ThumbBrowserEntry::obtainThumbnailSize () { + + if (thumbnail) + thumbnail->getThumbnailSize (prew, preh); +} +Glib::RefPtr ThumbBrowserEntry::editedIcon; +Glib::RefPtr ThumbBrowserEntry::recentlySavedIcon; +Glib::RefPtr ThumbBrowserEntry::enqueuedIcon; +std::vector > ThumbBrowserEntry::getIconsOnImageArea () { + + std::vector > ret; + + if (!thumbnail) + return ret; + + if (thumbnail->hasProcParams() && editedIcon) + ret.push_back (editedIcon); + if (thumbnail->isRecentlySaved() && recentlySavedIcon) + ret.push_back (recentlySavedIcon); + if (thumbnail->isEnqueued () && enqueuedIcon) + ret.push_back (enqueuedIcon); + + return ret; +} + +ThumbnailButtonSet* ThumbBrowserEntry::getThumbButtonSet () { + + return (ThumbnailButtonSet*)buttonSet; +} diff --git a/rtgui/thumbbrowserentrybase.cc b/rtgui/thumbbrowserentrybase.cc new file mode 100644 index 000000000..3ee3feae9 --- /dev/null +++ b/rtgui/thumbbrowserentrybase.cc @@ -0,0 +1,414 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include + +ThumbBrowserEntryBase::ThumbBrowserEntryBase (const Glib::ustring& fname) + : filename(fname), selected(false), drawable(false),framed(false), processing(false), + italicstyle(false), preview(NULL), exifline(""), datetimeline(""), + buttonSet(NULL), updatepriority(false), redrawRequests(0), + parent(NULL), exp_width(0), exp_height(0) { + + shortname = Glib::path_get_basename (fname); + dispname = shortname; + + upperMargin = 6; + borderWidth = 1; + sideMargin = 8; + lowerMargin = 8; + textGap = 6; + + ofsX = ofsY = 0; +} + +ThumbBrowserEntryBase::~ThumbBrowserEntryBase () { + + delete [] preview; + delete buttonSet; +} + +void ThumbBrowserEntryBase::addButtonSet (LWButtonSet* bs) { + + buttonSet = bs; +} + +void ThumbBrowserEntryBase::updateBackBuffer () { + + if (!parent) + return; + + Gtk::Widget* w = parent->getDrawingArea (); + + backBuffer = Gdk::Pixmap::create (w->get_window(), exp_width, exp_height); + + // If thumbnail is hidden by a filter drawing to it will crash + int backbuffer_w =0, backbuffer_h = 0; + backBuffer->get_size(backbuffer_w, backbuffer_h); + // if either with or height is zero then return early + if (backbuffer_w * backbuffer_h == 0) return; + + bbSelected = selected; + bbFramed = framed; + bbPreview = preview; + + Glib::RefPtr gc_ = Gdk::GC::create (backBuffer); + + Gdk::Color textn = w->get_style()->get_text(Gtk::STATE_NORMAL); + Gdk::Color texts = w->get_style()->get_text(Gtk::STATE_SELECTED); + Gdk::Color bgn = w->get_style()->get_bg(Gtk::STATE_NORMAL); + Gdk::Color bgs = w->get_style()->get_bg(Gtk::STATE_SELECTED); + + // clear area, draw frames and background + gc_->set_foreground (bgn); + gc_->set_background (bgn); + backBuffer->draw_rectangle (gc_, true, 0, 0, exp_width, exp_height); + Cairo::RefPtr cr = backBuffer->create_cairo_context(); + drawFrame (cr, bgs, bgn); + + // calculate height of button set + int bsHeight = 0; + if (buttonSet) { + int tmp; + buttonSet->getAllocatedDimensions (tmp, bsHeight); + } + + // draw preview frame + backBuffer->draw_rectangle (gc_, false, (exp_width-prew)/2, upperMargin+bsHeight, prew+1, preh+1); + // draw thumbnail image + if (preview) { + prex = borderWidth + (exp_width-prew)/2; + prey = upperMargin+bsHeight+borderWidth; + backBuffer->draw_rgb_image (gc_, prex, prey, prew, preh, Gdk::RGB_DITHER_NONE, preview, prew*3); + } + + customBackBufferUpdate (cr); + + // draw icons onto the thumbnail area + bbIcons = getIconsOnImageArea (); + + int infow, infoh; + getTextSizes (infow, infoh); + + int iofs_x = 4, iofs_y = 4; + int igap = 2; + int istartx = prex; + int istarty = prey; + + if (options.showFileNames && options.overlayedFileNames) { + cr->begin_new_path (); + cr->rectangle (istartx, istarty, prew, fnlabh+dtlabh+exlabh+2*iofs_y); + if ((texts.get_red_p()+texts.get_green_p()+texts.get_blue_p())/3 > 0.5) + cr->set_source_rgba (0, 0, 0, 0.5); + else + cr->set_source_rgba (1, 1, 1, 0.5); + cr->fill (); + } + + istartx += iofs_x; + istarty += iofs_y; + + if (bbIcons.size()>0) { + int iwidth = igap; + int iheight = 0; + for (int i=0; iget_width() + igap; + if (bbIcons[i]->get_height() > iheight) + iheight = bbIcons[i]->get_height(); + } + iheight += 2*igap; + if (!options.overlayedFileNames) { + cr->begin_new_path (); + cr->rectangle (istartx-igap, istarty-igap, iwidth, iheight); + cr->set_source_rgba (0, 0, 0, 0.75); + cr->fill (); + } + for (int i=0; idraw_pixbuf (gc_, bbIcons[i], 0, 0, istartx, istarty, bbIcons[i]->get_width(), bbIcons[i]->get_height(), Gdk::RGB_DITHER_NONE, 0, 0); + istartx += bbIcons[i]->get_width() + igap; + } + } + + if( options.showFileNames ){ + int textposx_fn, textposx_ex, textposx_dt, textposy, textw; + if (!options.overlayedFileNames) { + textposx_fn = exp_width/2 - fnlabw/2; + if (textposx_fn<0) textposx_fn = 0; + textposx_ex = exp_width/2 - exlabw/2; + if (textposx_ex<0) textposx_ex = 0; + textposx_dt = exp_width/2 - dtlabw/2; + if (textposx_dt<0) textposx_dt = 0; + textposy = upperMargin + bsHeight + 2*borderWidth + preh + borderWidth + textGap; + textw = exp_width - 2*textGap; + gc_->set_foreground (selected ? texts : textn); + } + else { + textposx_fn = istartx; + textposx_ex = istartx; + textposx_dt = istartx; + textposy = istarty; + textw = prew - (istartx - prex); + gc_->set_foreground (texts); + } + + // draw file name + Glib::RefPtr context = w->get_pango_context () ; + Pango::FontDescription fontd = context->get_font_description (); + fontd.set_weight (Pango::WEIGHT_BOLD); + if (italicstyle) + fontd.set_style (Pango::STYLE_ITALIC); + else + fontd.set_style (Pango::STYLE_NORMAL); + + context->set_font_description (fontd); + Glib::RefPtr fn = w->create_pango_layout (dispname); + fn->set_width (textw*Pango::SCALE); + fn->set_ellipsize (Pango::ELLIPSIZE_MIDDLE); + backBuffer->draw_layout(gc_, textposx_fn, textposy, fn); + + fontd.set_weight (Pango::WEIGHT_NORMAL); + fontd.set_style (Pango::STYLE_NORMAL); + context->set_font_description (fontd); + + // draw date/time label + int tpos = fnlabh; + if (options.fbShowDateTime && datetimeline!="") { + fn = w->create_pango_layout (datetimeline); + fn->set_width (textw*Pango::SCALE); + fn->set_ellipsize (Pango::ELLIPSIZE_MIDDLE); + backBuffer->draw_layout(gc_, textposx_dt, textposy + tpos, fn); + tpos += dtlabh; + } + // draw basic exif info + if (options.fbShowBasicExif && exifline!="") { + fn = w->create_pango_layout (exifline); + fn->set_width (textw*Pango::SCALE); + fn->set_ellipsize (Pango::ELLIPSIZE_MIDDLE); + backBuffer->draw_layout (gc_, textposx_ex, textposy + tpos, fn); + tpos += exlabh; + } + } +} + +void ThumbBrowserEntryBase::getTextSizes (int& infow, int& infoh) { + + if (!parent) + return; + + Gtk::Widget* w = parent->getDrawingArea (); + + // calculate dimensions of the text based fields + dispname = shortname; + + Glib::RefPtr context = w->get_pango_context () ; + context->set_font_description (w->get_style()->get_font()); + + // filename: + Pango::FontDescription fontd = context->get_font_description (); + fontd.set_weight (Pango::WEIGHT_BOLD); + context->set_font_description (fontd); + Glib::RefPtr fn = w->create_pango_layout(shortname); + fn->get_pixel_size (fnlabw, fnlabh); + + // datetime + fontd.set_weight (Pango::WEIGHT_NORMAL); + context->set_font_description (fontd); + fn = w->create_pango_layout (datetimeline); + fn->get_pixel_size (dtlabw, dtlabh); + + // basic exif data + fn = w->create_pango_layout (exifline); + fn->get_pixel_size (exlabw, exlabh); + + // calculate cummulated height of all info fields + infoh = fnlabh; + infow = 0; + // add date/tile size: + if (options.fbShowDateTime) { + infoh += dtlabh; + if (dtlabw + 2*sideMargin > infow) + infow = dtlabw + 2*sideMargin; + } + if (options.fbShowBasicExif) { + infoh += exlabh; + if (exlabw + 2*sideMargin > infow) + infow = exlabw + 2*sideMargin; + } +} + +void ThumbBrowserEntryBase::resize (int h) { + + delete [] preview; + preview = NULL; + height = h; + + // dimensions of the button set + int bsw=0, bsh=0; + if (buttonSet) + buttonSet->getMinimalDimensions (bsw, bsh); + + // calculate the height remaining for the thumbnail image + preh = height - upperMargin - 2*borderWidth - lowerMargin - bsh; + int infow, infoh; + if (options.showFileNames && !options.overlayedFileNames) { + // dimensions of the info text + getTextSizes (infow, infoh); + preh -= infoh + textGap; + } + + calcThumbnailSize (); + width = prew + 2*sideMargin + 2*borderWidth; + if (options.showFileNames && !options.overlayedFileNames) { + width = prew + 2*sideMargin + 2*borderWidth; + if (width cr, const Gdk::Color& bg, const Gdk::Color& fg) { + + int radius = 8; + if (selected || framed) { + cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + cr->move_to (radius, 0); + cr->arc (exp_width-1-radius, radius, radius, -M_PI/2, 0); + cr->arc (exp_width-1-radius, exp_height-1-radius, radius, 0, M_PI/2); + cr->arc (radius, exp_height-1-radius, radius, M_PI/2, M_PI); + cr->arc (radius, radius, radius, M_PI, -M_PI/2); + cr->close_path (); + if (selected) { + cr->set_source_rgb (bg.get_red_p(), bg.get_green_p(), bg.get_blue_p()); + cr->fill_preserve (); + } + cr->set_source_rgb (bg.get_red_p()*2/3, bg.get_green_p()*2/3, bg.get_blue_p()*2/3); + cr->set_line_width (1.0); + cr->stroke (); + + } + + if (framed) { + cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + cr->move_to (+2+0.5+radius, +2+0.5); + cr->arc (-2+0.5+exp_width-1-radius, +2+0.5+radius, radius, -M_PI/2, 0); + cr->arc (-2+0.5+exp_width-1-radius, -2+0.5+exp_height-1-radius, radius, 0, M_PI/2); + cr->arc (+2+0.5+radius, -2+exp_height-1-radius, radius, M_PI/2, M_PI); + cr->arc (+2+0.5+radius, +2+radius, radius, M_PI, -M_PI/2); + cr->close_path (); + cr->set_source_rgb (fg.get_red_p(), fg.get_green_p(), fg.get_blue_p()); + cr->set_line_width (2.0); + cr->stroke (); + } +} + +void ThumbBrowserEntryBase::draw () { + + if (!drawable) + return; + + int bbWidth, bbHeight; + if (backBuffer) + backBuffer->get_size (bbWidth, bbHeight); + + + if (!backBuffer || selected!=bbSelected || framed!=bbFramed || preview!=bbPreview + || exp_width!=bbWidth || exp_height!=bbHeight || getIconsOnImageArea ()!=bbIcons) + updateBackBuffer (); + + if (!parent) + return; + + Gtk::Widget* w = parent->getDrawingArea (); + + Glib::RefPtr gc_ = Gdk::GC::create (w->get_window()); + + Gdk::Color textn = w->get_style()->get_text(Gtk::STATE_NORMAL); + Gdk::Color texts = w->get_style()->get_text(Gtk::STATE_SELECTED); + Gdk::Color bgn = w->get_style()->get_bg(Gtk::STATE_NORMAL); + Gdk::Color bgs = w->get_style()->get_bg(Gtk::STATE_SELECTED); + + w->get_window()->draw_drawable (gc_, backBuffer, 0, 0, startx + ofsX, starty + ofsY); + + // check icon set changes!!! + +// drawProgressBar (window, gc_, selected ? texts : textn, selected ? bgs : bgn, ofsX+startx, exp_width, ofsY+starty + upperMargin+bsHeight+borderWidth+preh+borderWidth+textGap+tpos, fnlabh); + + // redraw button set above the thumbnail + if (buttonSet) { + buttonSet->setColors (selected ? bgs : bgn, selected ? bgn : bgs); + buttonSet->redraw (w->get_window()->create_cairo_context()); + } +} + +void ThumbBrowserEntryBase::setPosition (int x, int y, int w, int h) { + + exp_width = w; + exp_height = h; + startx = x; + starty = y; + + if (buttonSet) + buttonSet->arrangeButtons (ofsX+x+sideMargin, ofsY+y+upperMargin, w-2*sideMargin, -1); +} + +void ThumbBrowserEntryBase::setOffset (int x, int y) { + + ofsX = -x; + ofsY = -y; + + if (buttonSet) + buttonSet->move (ofsX+startx+sideMargin, ofsY+starty+upperMargin); +} + +bool ThumbBrowserEntryBase::inside (int x, int y) { + + return x>ofsX+startx && xofsY+starty && yx+w || ofsX+startx+exp_widthy+h || ofsY+starty+exp_heightmotionNotify (x, y) : false; +} + +bool ThumbBrowserEntryBase::pressNotify (int button, int type, int bstate, int x, int y) { + + return buttonSet ? buttonSet->pressNotify (x, y) : false; +} + +bool ThumbBrowserEntryBase::releaseNotify (int button, int type, int bstate, int x, int y) { + + return buttonSet ? buttonSet->releaseNotify (x, y) : false; +} +Glib::ustring ThumbBrowserEntryBase::getToolTip (int x, int y) { + + return buttonSet ? buttonSet->getToolTip (x, y) : ""; +} + + diff --git a/rtgui/thumbbrowserentrybase.h b/rtgui/thumbbrowserentrybase.h new file mode 100644 index 000000000..c69737db0 --- /dev/null +++ b/rtgui/thumbbrowserentrybase.h @@ -0,0 +1,125 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _THUMBNAILBROWSERENTRYBASE_ +#define _THUMBNAILBROWSERENTRYBASE_ + +#include +#include + +class ThumbBrowserBase; +class ThumbBrowserEntryBase { + +protected: + int fnlabw, fnlabh; // dimensions of the filename label + int dtlabw, dtlabh; // dimensions of the date/time label + int exlabw, exlabh; // dimensions of the exif label + int prew; // width of the thumbnail + int preh; // height of the thumbnail + int prex; + int prey; + + int upperMargin; + int borderWidth; + int textGap; + int sideMargin; + int lowerMargin; + + guint8* preview; + + Glib::ustring dispname; + + LWButtonSet* buttonSet; + + int width; // minimal width + int height; // minimal height +// set by arrangeFiles() of thumbbrowser + int exp_width; // arranged width + int exp_height; // arranged height + int startx; // x coord. in the widget + int starty; // y coord. in the widget + + int ofsX, ofsY; // offset due to the scrolling of the parent + + int redrawRequests; + + ThumbBrowserBase* parent; + + Glib::RefPtr backBuffer; + bool bbSelected, bbFramed; + guint8* bbPreview; + std::vector > bbIcons; + + void drawFrame (Cairo::RefPtr cr, const Gdk::Color& bg, const Gdk::Color& fg); + void getTextSizes (int& w, int& h); + + virtual void customBackBufferUpdate (Cairo::RefPtr c) {} + + public: + +// thumbnail preview properties: + Glib::ustring filename; + Glib::ustring shortname; + Glib::ustring exifline; + Glib::ustring datetimeline; + +// misc attributes + bool selected; + bool drawable; + bool filtered; + bool framed; + bool processing; + bool italicstyle; + bool edited; + bool recentlysaved; + bool updatepriority; + + ThumbBrowserEntryBase (const Glib::ustring& fname); + virtual ~ThumbBrowserEntryBase (); + + void setParent (ThumbBrowserBase* l) { parent = l; } + + void updateBackBuffer (); + void resize (int h); + virtual void draw (); + + void addButtonSet (LWButtonSet* bs); + int getMinimalHeight () { return height; } + int getMinimalWidth () { return width; } + bool inside (int x, int y); + bool insideWindow (int x, int y, int w, int h); + void setPosition (int x, int y, int w, int h); + void setOffset (int x, int y); + + bool operator< (ThumbBrowserEntryBase& other) { return shortname.casefold()>other.shortname.casefold(); } + + virtual void refreshThumbnailImage () {} + virtual void calcThumbnailSize () {} + + virtual void drawProgressBar (Glib::RefPtr win, Glib::RefPtr gc, const Gdk::Color& foregr, const Gdk::Color& backgr, int x, int w, int y, int h) {} + + virtual std::vector > getIconsOnImageArea () { std::vector > r; return r; } + virtual void getIconSize (int& w, int& h) { w=0; h=0; } + + virtual bool motionNotify (int x, int y); + virtual bool pressNotify (int button, int type, int bstate, int x, int y); + virtual bool releaseNotify (int button, int type, int bstate, int x, int y); + Glib::ustring getToolTip (int x, int y); +}; + +#endif diff --git a/rtgui/thumbimageupdater.cc b/rtgui/thumbimageupdater.cc new file mode 100644 index 000000000..2dfaf066c --- /dev/null +++ b/rtgui/thumbimageupdater.cc @@ -0,0 +1,166 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +ThumbImageUpdater thumbImageUpdater; + +ThumbImageUpdater::ThumbImageUpdater () + : tostop(false), stopped(true), qMutex(NULL), startMutex(NULL) { + +} + +void ThumbImageUpdater::add (Thumbnail* t, const rtengine::procparams::ProcParams& params, int height, bool* priority, ThumbImageUpdateListener* l) { + + if (!qMutex) + qMutex = new Glib::Mutex (); + if (!startMutex) + startMutex = new Glib::Mutex (); + + qMutex->lock (); + // look up if an older version is in the queue + std::list::iterator i; + for (i=jqueue.begin(); i!=jqueue.end(); i++) + if (i->thumbnail==t && i->listener==l) { + i->pparams = params; + i->height = height; + i->priority = priority; + break; + } + // not found, create and append new job + if (i==jqueue.end ()) { + Job j; + j.thumbnail = t; + j.pparams = params; + j.height = height; + j.listener = l; + j.priority = priority; + jqueue.push_back (j); + } + qMutex->unlock (); +} + +void ThumbImageUpdater::process () { + + if (stopped) { + #undef THREAD_PRIORITY_NORMAL + stopped = false; + thread = Glib::Thread::create(sigc::mem_fun(*this, &ThumbImageUpdater::process_), (unsigned long int)0, true, true, Glib::THREAD_PRIORITY_NORMAL); + } +} + +void ThumbImageUpdater::process_ () { + + stopped = false; + tostop = false; + + #define threadNum 4 // IF LCMS GETS THREAD SAFETY WE CAN ENABLE MORE THREADS + Glib::Thread **threadPool = new Glib::Thread* [threadNum]; + + while (!tostop && !jqueue.empty ()) { + + qMutex->lock (); + int threads = 0; + for (; threads::iterator i; + for (i=jqueue.begin (); i!=jqueue.end(); i++) + if (*(i->priority)) + break; + if (i==jqueue.end()) + i = jqueue.begin(); + Job current = *i; + jqueue.erase (i); + if (current.listener) + threadPool[threads] = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ThumbImageUpdater::processJob), current), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + else + threadPool[threads] = NULL; + } + qMutex->unlock (); + + for (int j=0; jjoin (); + } + stopped = true; +} + +void ThumbImageUpdater::processJob (Job current) { + + if (current.listener) { + double scale = 1.0; + rtengine::IImage8* img = current.thumbnail->processThumbImage (current.pparams, current.height, scale); + if (img) + current.listener->updateImage (img, scale, current.pparams.crop); + } + +} + +void ThumbImageUpdater::stop () { + + if (stopped) { + tostop = true; + return; } + + gdk_threads_leave(); + tostop = true; + Glib::Thread::self()->yield(); + if (!stopped) + thread->join (); + gdk_threads_enter(); +} + +void ThumbImageUpdater::removeJobs () { + + if (!qMutex) + return; + + qMutex->lock (); + while (!jqueue.empty()) + jqueue.pop_front (); + qMutex->unlock (); +} + +void ThumbImageUpdater::removeJobs (ThumbImageUpdateListener* listener) { + + if (!qMutex) + return; + + qMutex->lock (); + bool ready = false; + while (!ready) { + ready = true; + std::list::iterator i; + for (i=jqueue.begin(); i!=jqueue.end(); i++) + if (i->listener == listener) { + jqueue.erase (i); + ready = false; + break; + } + } + qMutex->unlock (); +} + +void ThumbImageUpdater::terminate () { + + stop (); + removeJobs (); +} + + diff --git a/rtgui/thumbimageupdater.h b/rtgui/thumbimageupdater.h new file mode 100644 index 000000000..91c0d6956 --- /dev/null +++ b/rtgui/thumbimageupdater.h @@ -0,0 +1,66 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _THUMBIMAGEUPDATER_ +#define _THUMBIMAGEUPDATER_ + +#include +#include +#include + +class ThumbImageUpdateListener { + + public: + virtual void updateImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cropParams) {} +}; + +class ThumbImageUpdater { + + struct Job { + Thumbnail* thumbnail; + rtengine::procparams::ProcParams pparams; + int height; + bool* priority; + ThumbImageUpdateListener* listener; + }; + + protected: + bool tostop; + bool stopped; + std::list jqueue; + Glib::Thread* thread; + Glib::Mutex* qMutex; + Glib::Mutex* startMutex; + + public: + ThumbImageUpdater (); + + void add (Thumbnail* t, const rtengine::procparams::ProcParams& params, int height, bool* priority, ThumbImageUpdateListener* l); + void process (); + void stop (); + void removeJobs (); + void removeJobs (ThumbImageUpdateListener* listener); + void terminate (); + + void process_ (); + void processJob (Job current); +}; + +extern ThumbImageUpdater thumbImageUpdater; + +#endif diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc new file mode 100644 index 000000000..f39cae764 --- /dev/null +++ b/rtgui/thumbnail.cc @@ -0,0 +1,447 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace rtengine::procparams; + +Thumbnail::Thumbnail (CacheManager* cm, const Glib::ustring& fname, CacheImageData* cf) + : cachemgr(cm), cfs(*cf), pparamsValid(false), fname(fname), + lastImg(NULL), ref(1), enqueueNumber(0), tpp(NULL), needsReProcessing(true) { + + mutex = new Glib::Mutex (); + cfs.load (getCacheFileName ("data")+".txt"); + loadProcParams (); + loadThumbnail (); + generateExifDateTimeStrings (); +} + +Thumbnail::Thumbnail (CacheManager* cm, const Glib::ustring& fname, const std::string& md5) + : cachemgr(cm), pparamsValid(false), lastImg(NULL), fname(fname), + ref(1), enqueueNumber(0), tpp(NULL), needsReProcessing(true) { + + mutex = new Glib::Mutex (); + + cfs.md5 = md5; + generateThumbnailImage (); + loadProcParams (); + cfs.recentlySaved = false; +} + +void Thumbnail::generateThumbnailImage (bool internal) { + + if (!internal) + mutex->lock (); + +// delete everything loaded into memory + delete tpp; + tpp = NULL; + delete [] lastImg; + lastImg = NULL; + tw = -1; + th = options.maxThumbnailHeight; + +// generate thumbnail image + + Glib::ustring ext = getExtension (fname); + if (ext=="") + return; + cfs.supported = false; + cfs.exifValid = false; + cfs.timeValid = false; + + delete tpp; + tpp = NULL; + if (ext.lowercase()=="jpg" || ext.lowercase()=="png" || ext.lowercase()=="tif" || ext.lowercase()=="tiff") + tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, 1); + if (tpp) { + if (ext.lowercase()=="jpg") { + cfs.format = FT_Jpeg; + infoFromImage (fname); + } + else if (ext.lowercase()=="png") + cfs.format = FT_Png; + else if (ext.lowercase()=="tif" || ext.lowercase()=="tiff") { + cfs.format = FT_Tiff; + infoFromImage (fname); + } + } + else { + rtengine::RawMetaDataLocation ri; + tpp = rtengine::Thumbnail::loadFromRaw (fname, ri, tw, th, 1); + if (tpp) { + cfs.format = FT_Raw; + infoFromImage (fname, &ri); + } + } + if (tpp) { + // save thumbnail image to cache + saveThumbnail (); + cfs.supported = true; + } + needsReProcessing = true; + + cfs.save (getCacheFileName ("data")+".txt"); + + generateExifDateTimeStrings (); + + if (!internal) + mutex->unlock (); +} + +bool Thumbnail::isSupported () { + + return cfs.supported; +} + +const ProcParams& Thumbnail::getProcParams () { + + if (pparamsValid) + return pparams; + else { + rtengine::procparams::ProcParams* pp = profileStore.getDefaultProcParams (getType()==FT_Raw); + if (pp->wb.method=="Camera") { + double ct; + getCamWB (ct, pp->wb.green); + pp->wb.temperature = ct; + } + else if (pp->wb.method=="Auto") { + double ct; + getAutoWB (ct, pp->wb.green); + pp->wb.temperature = ct; + } + if (pp) + return *pp; + } + return pparams; // there is no valid pp to return, but we have to return something +} + +void Thumbnail::loadProcParams () { + + pparamsValid = false; + if (options.paramsLoadLocation==PLL_Input) { + // try to load it from pp2 file next to the image file + int ppres = pparams.load (fname + ".pp2"); + pparamsValid = !ppres && pparams.version>=220; + if (!pparamsValid) + pparamsValid = !pparams.load (getCacheFileName ("profiles")+".pp2"); + } + else { + // try to load it from cache + pparamsValid = !pparams.load (getCacheFileName ("profiles")+".pp2"); + // if no success, load it from pp2 file next to the image file + if (!pparamsValid) { + int ppres = pparams.load (fname + ".pp2"); + pparamsValid = !ppres && pparams.version>=220; + } + } +} + +void Thumbnail::clearProcParams (int whoClearedIt) { + + cfs.recentlySaved = false; + pparamsValid = false; + needsReProcessing = true; + // remove pp2 file from cache + Glib::ustring fname_ = getCacheFileName ("profiles")+".pp2"; + if (Glib::file_test (fname_, Glib::FILE_TEST_EXISTS)) + ::g_remove (fname_.c_str()); + // remove pp2 file located next to the file +// fname_ = removeExtension(fname) + ".pp2"; + fname_ = fname + ".pp2"; + if (Glib::file_test (fname_, Glib::FILE_TEST_EXISTS)) + ::g_remove (fname_.c_str()); + fname_ = removeExtension(fname) + ".pp2"; + if (Glib::file_test (fname_, Glib::FILE_TEST_EXISTS)) + ::g_remove (fname_.c_str()); + + for (int i=0; iprocParamsChanged (this, whoClearedIt); +} + +bool Thumbnail::hasProcParams () { + + return pparamsValid; +} + +void Thumbnail::setProcParams (const ProcParams& pp, int whoChangedIt, bool updateCacheNow) { + + if (pparams!=pp) + cfs.recentlySaved = false; + + pparams = pp; + pparamsValid = true; + needsReProcessing = true; + if (updateCacheNow) + updateCache (); + + for (int i=0; iprocParamsChanged (this, whoChangedIt); +} + +bool Thumbnail::isRecentlySaved () { + + return cfs.recentlySaved; +} + +void Thumbnail::imageDeveloped () { + + cfs.recentlySaved = true; + cfs.save (getCacheFileName ("data")+".txt"); + pparams.save (getCacheFileName ("profiles")+".pp2"); +} + +void Thumbnail::imageEnqueued () { + + enqueueNumber++; +} + +void Thumbnail::imageRemovedFromQueue () { + + enqueueNumber--; +} + +bool Thumbnail::isEnqueued () { + + return enqueueNumber > 0; +} + +void Thumbnail::increaseRef () { ref++; } +void Thumbnail::decreaseRef () { ref--; if (!ref) cachemgr->closeThumbnail (this); } + +void Thumbnail::getThumbnailSize (int &w, int &h) { + + if (tpp) + w = tpp->getImageWidth (getProcParams(), h); + else + w = tw * h / th; +} + +rtengine::IImage8* Thumbnail::processThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale) { + + mutex->lock (); + + if (!tpp) + return NULL; + + rtengine::IImage8* res = tpp->processImage (pparams, h, rtengine::TI_Bilinear, scale); + + mutex->unlock (); + return res; +} + +void Thumbnail::generateExifDateTimeStrings () { + + exifString = ""; + dateTimeString = ""; + + if (!cfs.exifValid) + return; + + exifString = Glib::ustring::compose ("f/%1 %2s %3%4", Glib::ustring(rtengine::ImageData::apertureToString(cfs.fnumber)), Glib::ustring(rtengine::ImageData::shutterToString(cfs.shutter)), M("QINFO_ISO"), cfs.iso); + + std::string dateFormat = options.dateFormat; + std::ostringstream ostr; + bool spec = false; + for (int i=0; ihasExif()) { + cfs.shutter = idata->getShutterSpeed (); + cfs.fnumber = idata->getFNumber (); + cfs.focalLen = idata->getFocalLen (); + cfs.iso = idata->getISOSpeed (); + cfs.year = 1900 + idata->getDateTime().tm_year; + cfs.month = idata->getDateTime().tm_mon + 1; + cfs.day = idata->getDateTime().tm_mday; + cfs.hour = idata->getDateTime().tm_hour; + cfs.min = idata->getDateTime().tm_min; + cfs.sec = idata->getDateTime().tm_sec; + cfs.timeValid = true; + cfs.exifValid = true; + cfs.lens = idata->getLens(); + cfs.camera = idata->getMake() + " " + idata->getModel(); + } + else { + cfs.lens = "Unknown"; + cfs.camera = "Unknown"; + } + delete idata; +} + +void Thumbnail::loadThumbnail (bool internal, bool firstTrial) { + + if (!internal) + mutex->lock (); + + needsReProcessing = true; + delete tpp; + tpp = new rtengine::Thumbnail (); + tpp->isRaw = (cfs.format == (int) FT_Raw); + + // load supplementary data + bool succ = tpp->readData (getCacheFileName ("data")+".txt"); + + // thumbnail image + succ = succ && tpp->readImage (getCacheFileName ("images")); + + if (!succ && firstTrial) { + generateThumbnailImage (true); + if (cfs.supported && firstTrial) + loadThumbnail (true, false); + } + else if (!succ) { + delete tpp; + tpp = NULL; + } + else { + // load aehistogram + tpp->readAEHistogram (getCacheFileName ("aehistograms")); + + // load embedded profile + tpp->readEmbProfile (getCacheFileName ("embprofiles")+".icc"); + + tpp->init (); + + } + if (!internal) + mutex->unlock (); +} + +void Thumbnail::saveThumbnail () { + + if (!tpp) + return; + + ::g_remove ((getCacheFileName ("images")+".cust").c_str()); + ::g_remove ((getCacheFileName ("images")+".cust16").c_str()); + ::g_remove ((getCacheFileName ("images")+".jpg").c_str()); + + // save thumbnail image + if (options.thumbnailFormat == FT_Custom) + tpp->writeImage (getCacheFileName ("images")+".cust", 1); + else if (options.thumbnailFormat == FT_Custom16) + tpp->writeImage (getCacheFileName ("images")+".cust16", 2); + else if (options.thumbnailFormat == FT_Jpeg) + tpp->writeImage (getCacheFileName ("images")+".jpg", 3); + + // save aehistogram + tpp->writeAEHistogram (getCacheFileName ("aehistograms")); + + // save embedded profile + tpp->writeEmbProfile (getCacheFileName ("embprofiles")+".icc"); + + // save supplementary data + tpp->writeData (getCacheFileName ("data")+".txt"); +} + +void Thumbnail::updateCache () { + + if (pparamsValid) { + if (options.saveParamsCache) + pparams.save (getCacheFileName ("profiles")+".pp2"); + if (options.saveParamsFile) +// pparams.save (removeExtension(fname) + ".pp2"); + pparams.save (fname + ".pp2"); + } + cfs.save (getCacheFileName ("data")+".txt"); +} + +Thumbnail::~Thumbnail () { + + delete [] lastImg; + delete tpp; +} + +Glib::ustring Thumbnail::getCacheFileName (Glib::ustring subdir) { + + return cachemgr->getCacheFileName (subdir, fname, cfs.md5); +} + +void Thumbnail::setFileName (const Glib::ustring fn) { + + fname = fn; + cfs.md5 = cachemgr->getMD5 (fname); +} + +void Thumbnail::addThumbnailListener (ThumbnailListener* tnl) { + + listeners.push_back (tnl); +} + +void Thumbnail::removeThumbnailListener (ThumbnailListener* tnl) { + + std::vector::iterator f = std::find (listeners.begin(), listeners.end(), tnl); + if (f!=listeners.end()) + listeners.erase (f); +} + diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h new file mode 100644 index 000000000..389e8e872 --- /dev/null +++ b/rtgui/thumbnail.h @@ -0,0 +1,130 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _THUMBNAIL_ +#define _THUMBNAIL_ + +#include +#include +#include +#include +#include +#include +#include +#include + +class CacheManager; +class Thumbnail { + + Glib::Mutex* mutex; + + Glib::ustring fname; // file name corresponding to the thumbnail + CacheImageData cfs; // cache entry corresponding to the thumbnail + CacheManager* cachemgr; // parent + int ref; // variable for reference counting + int enqueueNumber; // the number of instances in the batch queue corresponding to this thumbnail + + // if the thumbnail is in processed mode, this class holds its data: + rtengine::Thumbnail* tpp; + int tw, th; // dimensions of timgdata (it stores tpp->width and tpp->height in processed mode for simplicity) +// double scale; // portion of the sizes of the processed thumbnail image and the full scale image + + rtengine::procparams::ProcParams pparams; + bool pparamsValid; + bool pparamsSet; + bool needsReProcessing; + + // these are the data of the result image of the last getthumbnailimage call (for caching purposes) + unsigned char* lastImg; + int lastW; + int lastH; + + // exif & date/time strings + Glib::ustring exifString; + Glib::ustring dateTimeString; + + // vector of listeners + std::vector listeners; + + void infoFromImage (const Glib::ustring& fname, rtengine::RawMetaDataLocation* rml=NULL); + void loadThumbnail (bool internal=false, bool firstTrial=true); + void saveThumbnail (); + void generateExifDateTimeStrings (); + + Glib::ustring getCacheFileName (Glib::ustring subdir); + + public: + Thumbnail (CacheManager* cm, const Glib::ustring& fname, CacheImageData* cf); + Thumbnail (CacheManager* cm, const Glib::ustring& fname, const std::string& md5); + ~Thumbnail (); + + bool hasProcParams (); + const rtengine::procparams::ProcParams& getProcParams (); + void setProcParams (const rtengine::procparams::ProcParams& pp, int whoChangedIt=-1, bool updateCacheNow=true); + void clearProcParams (int whoClearedIt=-1); + void loadProcParams (); + + bool isRecentlySaved (); + void imageDeveloped (); + void imageEnqueued (); + void imageRemovedFromQueue (); + bool isEnqueued (); + +// unsigned char* getThumbnailImage (int &w, int &h, int fixwh=1); // fixwh = 0: fix w and calculate h, =1: fix h and calculate w + rtengine::IImage8* processThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale); + void processThumbImage2 (const rtengine::procparams::ProcParams& pparams, int h, rtengine::IImage8*& img, double& scale) { img = processThumbImage(pparams, h, scale); } + void getThumbnailSize (int &w, int &h); + void getFinalSize (const rtengine::procparams::ProcParams& pparams, int& w, int& h) { if (tpp) tpp->getFinalSize (pparams, w, h); } + + void generateThumbnailImage (bool internal=false); + + const Glib::ustring& getExifString (); + const Glib::ustring& getDateTimeString (); + void getCamWB (double& temp, double& green) { if (tpp) tpp->getCamWB (temp, green); } + void getAutoWB (double& temp, double& green) { if (tpp) tpp->getAutoWB (temp, green); } + void getSpotWB (int x, int y, int rect, double& temp, double& green) { if (tpp) tpp->getSpotWB (getProcParams(), x, y, rect, temp, green); } + void applyAutoExp (rtengine::procparams::ProcParams& pparams) { if (tpp) tpp->applyAutoExp (pparams); } + + ThFileType getType (); + Glib::ustring getFileName () { return fname; } + void setFileName (const Glib::ustring fn); + + bool isSupported (); + + const CacheImageData* getCacheImageData() { return &cfs; } + std::string getMD5 () { return cfs.md5; } + + int getRank () { return cfs.rank; } + void setRank (int rank) { cfs.rank = rank; } + + int getStage () { return cfs.inTrash; } + void setStage (int stage) { cfs.inTrash = stage; } + + void addThumbnailListener (ThumbnailListener* tnl); + void removeThumbnailListener (ThumbnailListener* tnl); + + void increaseRef (); + void decreaseRef (); + + void updateCache (); + void reSaveThumbnail () { mutex->lock (); saveThumbnail(); mutex->unlock(); } +}; + + +#endif + diff --git a/rtgui/thumbnailbrowser.h b/rtgui/thumbnailbrowser.h new file mode 100644 index 000000000..9f0731cf4 --- /dev/null +++ b/rtgui/thumbnailbrowser.h @@ -0,0 +1,95 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _THUMBNAILBROWSER_ +#define _THUMBNAILBROWSER_ + +#include +#include +#include + +class ThumbBrowserEntry { + +public: +// set by arrangeFiles(): + int width; // minimal width + int height; // minimal height + int exp_width; // ararnged width + int startx; // x coord. in the widget + int starty; // y coord. in the widget +// thumbnail preview properties: + int prew; // width of the thumbnail + int preh; // height of the thumbnail + guint8* preview; +// file and directory attributes: + Glib::ustring filename; + Glib::ustring shortname; + Glib::ustring dirname; +// the associated thumbnail instance: + Thumbnail* thumbnail; + + ThumbBrowserEntry (Thumbnail* thm, Glib::ustring fname, Glib::ustring sname, Glib::ustring dname, int h) + : thumbnail(thm), filename(fname), shortname(sname), dirname(dname), preh(h) { + preview = thumbnail ? (guint8*) thumbnail->getThumbnailImage (prew, preh) : NULL; + } + + bool operator< (FileDescr& other) { + return shortname>other.shortname; + } +}; + +class ThumbBrowser : public Gtk::DrawingArea { + + protected: + int dx, dy, w, h; + + Glib::RefPtr gc_; + Gdk::Color black; + Gdk::Color white; + Gdk::Color blue; + Gdk::Color bluew; + + std::vector fd; + std::vector selected; + + int rowHeight; + int numOfRows; + + ThumbBrowserListener* tbl; + + void arrangeFiles (int rows); + + public: + + ThumbBrowser (); + + void addEntry (ThumbBrowserEntry* entry); + void setThumbBrowserListener (ThumbBrowserListener* l) { tbl = l; } + + virtual void on_realize(); + virtual bool on_expose_event(GdkEventExpose* event); + virtual bool on_button_press_event (GdkEventButton* event); + virtual bool on_button_release_event (GdkEventButton* event); + virtual void previewReady (FileDescr* fdn); + + void resized (Gtk::Allocation& req); + void redraw (); + void styleChanged (const Glib::RefPtr& style); +}; + +#endif diff --git a/rtgui/thumbnaillistener.h b/rtgui/thumbnaillistener.h new file mode 100644 index 000000000..49a4eace9 --- /dev/null +++ b/rtgui/thumbnaillistener.h @@ -0,0 +1,34 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _THUMBNAILLISTENER_ +#define _THUMBNAILLISTENER_ + +#include + +class Thumbnail; +class ThumbnailListener { + + public: + + virtual void procParamsChanged (Thumbnail* thm, int whoChangedIt) {} + +}; + +#endif + diff --git a/rtgui/tonecurve.cc b/rtgui/tonecurve.cc new file mode 100644 index 000000000..4f3f80110 --- /dev/null +++ b/rtgui/tonecurve.cc @@ -0,0 +1,364 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +ToneCurve::ToneCurve () : ToolPanel(), expAdd(false), blackAdd(false), brAdd(false), contrAdd(false) { + +//----------- Auto Levels ---------------------------------- + abox = Gtk::manage (new Gtk::HBox ()); + abox->set_border_width (2); + + autolevels = Gtk::manage (new Gtk::ToggleButton (M("TP_EXPOSURE_AUTOLEVELS"))); + autoconn = autolevels->signal_toggled().connect( sigc::mem_fun(*this, &ToneCurve::autolevels_toggled) ); + + sclip = Gtk::manage (new Gtk::SpinButton ()); + sclip->set_range (0.0, 0.9999); + sclip->set_increments (0.0001, 0.01); + sclip->set_value (0.002); + sclip->set_digits (4); + sclip->signal_value_changed().connect( sigc::mem_fun(*this, &ToneCurve::clip_changed) ); + + abox->pack_start (*autolevels); + abox->pack_end (*sclip); + abox->pack_end (*Gtk::manage (new Gtk::Label (M("TP_EXPOSURE_CLIP")))); + pack_start (*abox); + + pack_start (*Gtk::manage (new Gtk::HSeparator())); + +//----------- Exposure Compensation ------------------------ + expcomp = Gtk::manage (new Adjuster (M("TP_EXPOSURE_EXPCOMP"), -5, 5, 0.01, 0)); + pack_start (*expcomp); + hlcompr = Gtk::manage (new Adjuster (M("TP_EXPOSURE_COMPRHIGHLIGHTS"), 0, 150, 1, 0)); + pack_start (*hlcompr); + +//----------- Black Level ---------------------------------- + black = Gtk::manage (new Adjuster (M("TP_EXPOSURE_BLACKLEVEL"), 0, 32768, 1, 0)); + pack_start (*black); + shcompr = Gtk::manage (new Adjuster (M("TP_EXPOSURE_COMPRSHADOWS"), 0, 150, 1, 0)); + pack_start (*shcompr); + + pack_start (*Gtk::manage (new Gtk::HSeparator())); + +//---------Brightness / Contrast ------------------------- + brightness = Gtk::manage (new Adjuster (M("TP_EXPOSURE_BRIGHTNESS"), -100, 100, 1, 0)); + pack_start (*brightness); + contrast = Gtk::manage (new Adjuster (M("TP_EXPOSURE_CONTRAST"), -100, 100, 1, 0)); + pack_start (*contrast); + + +//----------- Curve ------------------------------ + pack_start (*Gtk::manage (new Gtk::HSeparator())); + + shape = Gtk::manage (new CurveEditor ()); + shape->setCurveListener (this); + curvexp = Gtk::manage (new Gtk::Expander (M("TP_EXPOSURE_CURVEEDITOR"))); + curvexp->add (*shape); + + pack_start (*curvexp, Gtk::PACK_SHRINK, 4); + +// --------- Set Up Listeners ------------- + expcomp->setAdjusterListener (this); + brightness->setAdjusterListener (this); + black->setAdjusterListener (this); + hlcompr->setAdjusterListener (this); + shcompr->setAdjusterListener (this); + contrast->setAdjusterListener (this); +} + +void ToneCurve::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + expcomp->setEditedState (pedited->toneCurve.expcomp ? Edited : UnEdited); + black->setEditedState (pedited->toneCurve.black ? Edited : UnEdited); + hlcompr->setEditedState (pedited->toneCurve.hlcompr ? Edited : UnEdited); + shcompr->setEditedState (pedited->toneCurve.shcompr ? Edited : UnEdited); + brightness->setEditedState (pedited->toneCurve.brightness ? Edited : UnEdited); + contrast->setEditedState (pedited->toneCurve.contrast ? Edited : UnEdited); + autolevels->set_inconsistent (!pedited->toneCurve.autoexp); + clipDirty = pedited->toneCurve.clip; + shape->setUnChanged (!pedited->toneCurve.curve); + } + + autoconn.block (true); + autolevels->set_active (pp->toneCurve.autoexp); + autoconn.block (false); + lastAuto = pp->toneCurve.autoexp; + sclip->set_value (pp->toneCurve.clip); + + expcomp->setValue (pp->toneCurve.expcomp); + black->setValue (pp->toneCurve.black); + hlcompr->setValue (pp->toneCurve.hlcompr); + shcompr->setValue (pp->toneCurve.shcompr); + brightness->setValue (pp->toneCurve.brightness); + contrast->setValue (pp->toneCurve.contrast); + shape->setCurve (pp->toneCurve.curve); + + enableListener (); +} + +void ToneCurve::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->toneCurve.autoexp = autolevels->get_active(); + pp->toneCurve.clip = sclip->get_value (); + pp->toneCurve.expcomp = expcomp->getValue (); + pp->toneCurve.black = (int)black->getValue (); + pp->toneCurve.hlcompr = (int)hlcompr->getValue (); + pp->toneCurve.shcompr = (int)shcompr->getValue (); + pp->toneCurve.brightness = (int)brightness->getValue (); + pp->toneCurve.contrast = (int)contrast->getValue (); + pp->toneCurve.curve = shape->getCurve (); + + if (pedited) { + pedited->toneCurve.expcomp = expcomp->getEditedState (); + pedited->toneCurve.black = black->getEditedState (); + pedited->toneCurve.hlcompr = hlcompr->getEditedState (); + pedited->toneCurve.shcompr = shcompr->getEditedState (); + pedited->toneCurve.brightness = brightness->getEditedState (); + pedited->toneCurve.contrast = contrast->getEditedState (); + pedited->toneCurve.autoexp = !autolevels->get_inconsistent(); + pedited->toneCurve.clip = clipDirty; + pedited->toneCurve.curve = !shape->isUnChanged (); + } +} + +void ToneCurve::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + expcomp->setDefault (defParams->toneCurve.expcomp); + brightness->setDefault (defParams->toneCurve.brightness); + black->setDefault (defParams->toneCurve.black); + hlcompr->setDefault (defParams->toneCurve.hlcompr); + shcompr->setDefault (defParams->toneCurve.shcompr); + contrast->setDefault (defParams->toneCurve.contrast); + + if (pedited) { + expcomp->setDefaultEditedState (pedited->toneCurve.expcomp ? Edited : UnEdited); + black->setDefaultEditedState (pedited->toneCurve.black ? Edited : UnEdited); + hlcompr->setDefaultEditedState (pedited->toneCurve.hlcompr ? Edited : UnEdited); + shcompr->setDefaultEditedState (pedited->toneCurve.shcompr ? Edited : UnEdited); + brightness->setDefaultEditedState (pedited->toneCurve.brightness ? Edited : UnEdited); + contrast->setDefaultEditedState (pedited->toneCurve.contrast ? Edited : UnEdited); + } + else { + expcomp->setDefaultEditedState (Irrelevant); + black->setDefaultEditedState (Irrelevant); + hlcompr->setDefaultEditedState (Irrelevant); + shcompr->setDefaultEditedState (Irrelevant); + brightness->setDefaultEditedState (Irrelevant); + contrast->setDefaultEditedState (Irrelevant); + } +} + +void ToneCurve::curveChanged () { + + if (listener) { + listener->panelChanged (EvToneCurve, M("HISTORY_CUSTOMCURVE")); + } +} + +void ToneCurve::adjusterChanged (Adjuster* a, double newval) { + + if (autolevels->get_active() && (a==expcomp || a==black || a==hlcompr || a==shcompr)) { + autolevels->set_active (false); + autolevels->set_inconsistent (false); + } + + if (!listener) + return; + + Glib::ustring costr; + if (a==expcomp) + costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue()); + else + costr = Glib::ustring::format ((int)a->getValue()); + + if (a==expcomp) + listener->panelChanged (EvExpComp, costr); + else if (a==brightness) + listener->panelChanged (EvBrightness, costr); + else if (a==black) + listener->panelChanged (EvBlack, costr); + else if (a==contrast) + listener->panelChanged (EvContrast, costr); + else if (a==hlcompr) + listener->panelChanged (EvHLCompr, costr); + else if (a==shcompr) + listener->panelChanged (EvSHCompr, costr); +} + +void ToneCurve::autolevels_toggled () { + + if (batchMode) { + if (autolevels->get_inconsistent()) { + autolevels->set_inconsistent (false); + autoconn.block (true); + autolevels->set_active (false); + autoconn.block (false); + } + else if (lastAuto) + autolevels->set_inconsistent (true); + + lastAuto = autolevels->get_active (); + } + + if (!batchMode && autolevels->get_active() && listener) { + listener->panelChanged (EvAutoExp, M("GENERAL_ENABLED")); + waitForAutoExp (); + } + + if (batchMode) { + expcomp->setEditedState (UnEdited); + black->setEditedState (UnEdited); + if (expAdd) + expcomp->setValue (0); + if (blackAdd) + black->setValue (0); + listener->panelChanged (EvAutoExp, M("GENERAL_ENABLED")); + } +} + +void ToneCurve::clip_changed () { + + clipDirty = true; + if (autolevels->get_active() && listener) + Glib::signal_idle().connect (sigc::mem_fun(*this, &ToneCurve::clip_changed_)); +} + +bool ToneCurve::clip_changed_ () { + + if (listener) { + listener->panelChanged (EvClip, Glib::ustring::format (std::setprecision(5), sclip->get_value())); + if (!batchMode) + waitForAutoExp (); + } + return false; +} + +void ToneCurve::waitForAutoExp () { + + sclip->set_sensitive (false); + expcomp->setEnabled (false); + brightness->setEnabled (false); + black->setEnabled (false); + hlcompr->setEnabled (false); + shcompr->setEnabled (false); + contrast->setEnabled (false); + shape->set_sensitive (false); +} + +int aexpcomputed (void* data) { + + gdk_threads_enter(); + ((ToneCurve*)data)->autoExpComputed_ (); + gdk_threads_leave(); + return 0; +} + +void ToneCurve::autoExpChanged (double br, int bl) { + + nextBl = bl; + nextBr = br; + g_idle_add (aexpcomputed, this); + +// Glib::signal_idle().connect (sigc::mem_fun(*this, &ToneCurve::autoExpComputed_)); +} + +void ToneCurve::enableAll () { + + sclip->set_sensitive (true); + expcomp->setEnabled (true); + brightness->setEnabled (true); + black->setEnabled (true); + hlcompr->setEnabled (true); + shcompr->setEnabled (true); + contrast->setEnabled (true); + shape->set_sensitive (true); +} + +bool ToneCurve::autoExpComputed_ () { + + disableListener (); + enableAll (); + expcomp->setValue (nextBr); + black->setValue (nextBl); + enableListener (); + + return false; +} + +void ToneCurve::expandCurve (bool isExpanded) { + + curvexp->set_expanded (isExpanded); +} + +bool ToneCurve::isCurveExpanded () { + + return curvexp->get_expanded (); +} + + +void ToneCurve::setBatchMode (bool batchMode) { + + removeIfThere (abox, autolevels, false); + autolevels = Gtk::manage (new Gtk::CheckButton (M("TP_EXPOSURE_AUTOLEVELS"))); + autoconn = autolevels->signal_toggled().connect( sigc::mem_fun(*this, &ToneCurve::autolevels_toggled) ); + abox->pack_start (*autolevels); + + ToolPanel::setBatchMode (batchMode); + expcomp->showEditedCB (); + black->showEditedCB (); + hlcompr->showEditedCB (); + shcompr->showEditedCB (); + brightness->showEditedCB (); + contrast->showEditedCB (); + + shape->setBatchMode (batchMode); +} + +void ToneCurve::setAdjusterBehavior (bool expadd, bool bradd, bool blackadd, bool contradd) { + + if (!expAdd && expadd || expAdd && !expadd) + expcomp->setLimits (-5, 5, 0.01, 0); + if (!blackAdd && blackadd) + black->setLimits (0, 16384, 1, 0); + else if (blackAdd && !blackadd) + black->setLimits (0, 32768, 1, 0); + if (!brAdd && bradd || brAdd && !bradd) + brightness->setLimits (-100, 100, 1, 0); + if (!contrAdd && contradd || contrAdd && !contradd) + contrast->setLimits (-100, 100, 1, 0); + + expAdd = expadd; + blackAdd = blackadd; + brAdd = bradd; + contrAdd = contradd; +} + +void ToneCurve::updateCurveBackgroundHistogram (unsigned* hist) { + + shape->updateBackgroundHistogram (hist); +} diff --git a/rtgui/tonecurve.h b/rtgui/tonecurve.h new file mode 100644 index 000000000..4f4ad5256 --- /dev/null +++ b/rtgui/tonecurve.h @@ -0,0 +1,71 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _TONECURVE_H_ +#define _TONECURVE_H_ + +#include +#include +#include +#include +#include + +class ToneCurve : public Gtk::VBox, public AdjusterListener, public ToolPanel, public rtengine::AutoExpListener, public CurveListener { + + protected: + Gtk::HBox* abox; + Gtk::ToggleButton* autolevels; + Gtk::SpinButton* sclip; + Adjuster* expcomp; + Adjuster* brightness; + Adjuster* black; + Adjuster* hlcompr; + Adjuster* shcompr; + Adjuster* contrast; + bool expAdd, blackAdd, brAdd, contrAdd, clipDirty, lastAuto; + sigc::connection autoconn; + CurveEditor* shape; + Gtk::Expander* curvexp; + double nextBr; + int nextBl; + + public: + + ToneCurve (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void setAdjusterBehavior (bool expadd, bool bradd, bool blackadd, bool contradd); + + void adjusterChanged (Adjuster* a, double newval); + void autolevels_toggled (); + void clip_changed (); + bool clip_changed_ (); + void waitForAutoExp (); + void autoExpChanged (double br, int bl); + bool autoExpComputed_ (); + void enableAll (); + void curveChanged (); + void expandCurve (bool isExpanded); + bool isCurveExpanded (); + void updateCurveBackgroundHistogram (unsigned* hist); +}; + +#endif diff --git a/rtgui/toolbar.cc b/rtgui/toolbar.cc new file mode 100644 index 000000000..2c8ccc2c8 --- /dev/null +++ b/rtgui/toolbar.cc @@ -0,0 +1,195 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include "toolbar.h" +#include + +extern Glib::ustring argv0; + +ToolBar::ToolBar () : listener (NULL) { + + handTool = Gtk::manage (new Gtk::ToggleButton ()); + Gtk::Image* handimg = Gtk::manage (new Gtk::Image (argv0+"/images/openhand22.png")); + handTool->add (*handimg); + handimg->show (); + handTool->set_relief(Gtk::RELIEF_NONE); + handTool->show (); + + pack_start (*handTool); + + wbTool = Gtk::manage (new Gtk::ToggleButton ()); + Gtk::Image* wbimg = Gtk::manage (new Gtk::Image (argv0+"/images/wbpicker22.png")); + wbTool->add (*wbimg); + wbimg->show (); + wbTool->set_relief(Gtk::RELIEF_NONE); + wbTool->show (); + + pack_start (*wbTool); + + cropTool = Gtk::manage (new Gtk::ToggleButton ()); + Gtk::Image* cropimg = Gtk::manage (new Gtk::Image (argv0+"/images/crop22.png")); + cropTool->add (*cropimg); + cropimg->show (); + cropTool->set_relief(Gtk::RELIEF_NONE); + cropTool->show (); + + pack_start (*cropTool); + + straTool = Gtk::manage (new Gtk::ToggleButton ()); + Gtk::Image* straimg = Gtk::manage (new Gtk::Image (argv0+"/images/straighten22.png")); + straTool->add (*straimg); + straimg->show (); + straTool->set_relief(Gtk::RELIEF_NONE); + straTool->show (); + + pack_start (*straTool); + + + handTool->set_active (true); + current = TMHand; + + handConn = handTool->signal_toggled().connect( sigc::mem_fun(*this, &ToolBar::hand_pressed)); + wbConn = wbTool->signal_toggled().connect( sigc::mem_fun(*this, &ToolBar::wb_pressed)); + cropConn = cropTool->signal_toggled().connect( sigc::mem_fun(*this, &ToolBar::crop_pressed)); + straConn = straTool->signal_toggled().connect( sigc::mem_fun(*this, &ToolBar::stra_pressed)); + + handTool->set_tooltip_text (M("TOOLBAR_TOOLTIP_HAND")); + wbTool->set_tooltip_text (M("TOOLBAR_TOOLTIP_WB")); + cropTool->set_tooltip_text (M("TOOLBAR_TOOLTIP_CROP")); + straTool->set_tooltip_text (M("TOOLBAR_TOOLTIP_STRAIGHTEN")); +} + +// +// Selects the desired tool without notifying the listener +// +void ToolBar::setTool (ToolMode tool) { + + handConn.block (true); + cropConn.block (true); + wbConn.block (true); + straConn.block (true); + + handTool->set_active (false); + wbTool->set_active (false); + cropTool->set_active (false); + straTool->set_active (false); + + if (tool==TMHand) + handTool->set_active (true); + else if (tool==TMSpotWB) + wbTool->set_active (true); + else if (tool==TMCropSelect) + cropTool->set_active (true); + else if (tool==TMStraighten) + straTool->set_active (true); + + current = tool; + + handConn.block (false); + cropConn.block (false); + wbConn.block (false); + straConn.block (false); +} + +void ToolBar::hand_pressed () { + + handConn.block (true); + cropConn.block (true); + wbConn.block (true); + straConn.block (true); + if (current!=TMHand) { + wbTool->set_active (false); + cropTool->set_active (false); + straTool->set_active (false); + current = TMHand; + } + handTool->set_active (true); + handConn.block (false); + cropConn.block (false); + wbConn.block (false); + straConn.block (false); + + if (listener) + listener->toolSelected (TMHand); +} + +void ToolBar::wb_pressed () { + + handConn.block (true); + cropConn.block (true); + wbConn.block (true); + straConn.block (true); + if (current!=TMSpotWB) { + handTool->set_active (false); + cropTool->set_active (false); + straTool->set_active (false); + current = TMSpotWB; + } + wbTool->set_active (true); + handConn.block (false); + cropConn.block (false); + wbConn.block (false); + straConn.block (false); + + if (listener) + listener->toolSelected (TMSpotWB); +} + +void ToolBar::crop_pressed () { + + handConn.block (true); + cropConn.block (true); + wbConn.block (true); + straConn.block (true); + if (current!=TMCropSelect) { + handTool->set_active (false); + wbTool->set_active (false); + straTool->set_active (false); + current = TMCropSelect; + } + cropTool->set_active (true); + handConn.block (false); + cropConn.block (false); + wbConn.block (false); + straConn.block (false); + + if (listener) + listener->toolSelected (TMCropSelect); +} + +void ToolBar::stra_pressed () { + + handConn.block (true); + cropConn.block (true); + wbConn.block (true); + straConn.block (true); + if (current!=TMStraighten) { + handTool->set_active (false); + wbTool->set_active (false); + cropTool->set_active (false); + current = TMStraighten; + } + straTool->set_active (true); + handConn.block (false); + cropConn.block (false); + wbConn.block (false); + straConn.block (false); + + if (listener) + listener->toolSelected (TMStraighten); +} diff --git a/rtgui/toolbar.h b/rtgui/toolbar.h new file mode 100644 index 000000000..a98287222 --- /dev/null +++ b/rtgui/toolbar.h @@ -0,0 +1,60 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef __TOOLBAR_H__ +#define __TOOLBAR_H__ + +#include +#include + +class ToolBarListener { + + public: + virtual void toolSelected (ToolMode tool) {} + +}; + +class ToolBar : public Gtk::HBox { + + protected: + Gtk::ToggleButton* handTool; + Gtk::ToggleButton* wbTool; + Gtk::ToggleButton* cropTool; + Gtk::ToggleButton* straTool; + ToolBarListener* listener; + ToolMode current; + sigc::connection handConn; + sigc::connection wbConn; + sigc::connection cropConn; + sigc::connection straConn; + + public: + ToolBar (); + + void setTool (ToolMode tool); + ToolMode getTool () { return current; } + + void setToolBarListener (ToolBarListener* tpl) { listener = tpl; } + + void hand_pressed (); + void wb_pressed (); + void crop_pressed (); + void stra_pressed (); +}; + +#endif diff --git a/rtgui/toolenum.h b/rtgui/toolenum.h new file mode 100644 index 000000000..082084851 --- /dev/null +++ b/rtgui/toolenum.h @@ -0,0 +1,24 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _TOOLENUM_ +#define _TOOLENUM_ + +enum ToolMode {TMHand=0, TMSpotWB=1, TMCropSelect=2, TMStraighten=3}; + +#endif diff --git a/rtgui/toolpanel.h b/rtgui/toolpanel.h new file mode 100644 index 000000000..f4fadb8b2 --- /dev/null +++ b/rtgui/toolpanel.h @@ -0,0 +1,58 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef __TOOLPANEL__ +#define __TOOLPANEL__ + +#include +#include +#include +#include +#include + +class ToolPanelListener { + + public: + + virtual void panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr) {} +}; + +class ToolPanel { + + protected: + ToolPanelListener* listener; + ToolPanelListener* tmp; + bool batchMode; + + public: + + ToolPanel () : listener(NULL), tmp(NULL), batchMode(false) {} + + void setListener (ToolPanelListener* tpl) { listener = tpl; } + virtual void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL) {} + virtual void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL) {} + virtual void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL) {} + + void disableListener () { if (tmp==NULL) tmp = listener; listener = NULL; } + void enableListener () { if (tmp!=NULL) listener = tmp; tmp = NULL; } + + virtual void setBatchMode (bool batchMode) { this->batchMode = batchMode; } + +}; + +#endif diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc new file mode 100644 index 000000000..642a2df6c --- /dev/null +++ b/rtgui/toolpanelcoord.cc @@ -0,0 +1,358 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include +#include + +using namespace rtengine::procparams; + +ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) { + + exposurePanel = Gtk::manage (new Gtk::VBox ()); + detailsPanel = Gtk::manage (new Gtk::VBox ()); + colorPanel = Gtk::manage (new Gtk::VBox ()); + transformPanel = Gtk::manage (new Gtk::VBox ()); + + coarse = Gtk::manage (new CoarsePanel ()); + curve = Gtk::manage (new ToneCurve ()); + shadowshighlights = Gtk::manage (new ShadowsHighlights ()); + lumadenoise = Gtk::manage (new LumaDenoise ()); + colordenoise = Gtk::manage (new ColorDenoise ()); + sharpening = Gtk::manage (new Sharpening ()); + lcurve = Gtk::manage (new LCurve ()); + colorboost = Gtk::manage (new ColorBoost ()); + colorshift = Gtk::manage (new ColorShift ()); + distortion = Gtk::manage (new Distortion ()); + rotate = Gtk::manage (new Rotate ()); + whitebalance = Gtk::manage (new WhiteBalance ()); + vignetting = Gtk::manage (new Vignetting ()); + cacorrection = Gtk::manage (new CACorrection ()); + hlrecovery = Gtk::manage (new HLRecovery ()); + chmixer = Gtk::manage (new ChMixer ()); + resize = Gtk::manage (new Resize ()); + crop = Gtk::manage (new Crop ()); + icm = Gtk::manage (new ICMPanel ()); + exifpanel = Gtk::manage (new ExifPanel ()); + iptcpanel = Gtk::manage (new IPTCPanel ()); + + addPanel (colorPanel, whitebalance, M("TP_WBALANCE_LABEL")); toolPanels.push_back (whitebalance); + addPanel (exposurePanel, curve, M("TP_EXPOSURE_LABEL")); toolPanels.push_back (curve); + addPanel (exposurePanel, hlrecovery, M("TP_HLREC_LABEL")); toolPanels.push_back (hlrecovery); + addPanel (colorPanel, chmixer, M("TP_CHMIXER_LABEL")); toolPanels.push_back (chmixer); + addPanel (exposurePanel, shadowshighlights, M("TP_SHADOWSHLIGHTS_LABEL")); toolPanels.push_back (shadowshighlights); + addPanel (detailsPanel, sharpening, M("TP_SHARPENING_LABEL")); toolPanels.push_back (sharpening); + addPanel (colorPanel, colorboost, M("TP_COLORBOOST_LABEL")); toolPanels.push_back (colorboost); + addPanel (colorPanel, colorshift, M("TP_COLORSHIFT_LABEL")); toolPanels.push_back (colorshift); + addPanel (exposurePanel, lcurve, M("TP_LUMACURVE_LABEL")); toolPanels.push_back (lcurve); + addPanel (detailsPanel, lumadenoise, M("TP_LUMADENOISE_LABEL")); toolPanels.push_back (lumadenoise); + addPanel (detailsPanel, colordenoise, M("TP_COLORDENOISE_LABEL")); toolPanels.push_back (colordenoise); + addPanel (transformPanel, crop, M("TP_CROP_LABEL")); toolPanels.push_back (crop); + addPanel (transformPanel, rotate, M("TP_ROTATE_LABEL")); toolPanels.push_back (rotate); + addPanel (transformPanel, distortion, M("TP_DISTORTION_LABEL")); toolPanels.push_back (distortion); + addPanel (transformPanel, cacorrection, M("TP_CACORRECTION_LABEL")); toolPanels.push_back (cacorrection); + addPanel (transformPanel, vignetting, M("TP_VIGNETTING_LABEL")); toolPanels.push_back (vignetting); + addPanel (transformPanel, resize, M("TP_RESIZE_LABEL")); toolPanels.push_back (resize); + addPanel (colorPanel, icm, M("TP_ICM_LABEL")); toolPanels.push_back (icm); + + toolPanels.push_back (coarse); + toolPanels.push_back (exifpanel); + toolPanels.push_back (iptcpanel); + + metadataPanel = Gtk::manage (new Gtk::Notebook ()); + toolPanelNotebook = new Gtk::Notebook (); + + metadataPanel->append_page (*exifpanel, M("MAIN_TAB_EXIF")); + metadataPanel->append_page (*iptcpanel, M("MAIN_TAB_IPTC")); + + Gtk::ScrolledWindow* exposurePanelSW = Gtk::manage (new Gtk::ScrolledWindow ()); + Gtk::ScrolledWindow* detailsPanelSW = Gtk::manage (new Gtk::ScrolledWindow ()); + Gtk::ScrolledWindow* colorPanelSW = Gtk::manage (new Gtk::ScrolledWindow ()); + Gtk::ScrolledWindow* transformPanelSW = Gtk::manage (new Gtk::ScrolledWindow ()); + exposurePanelSW->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + detailsPanelSW->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + colorPanelSW->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + transformPanelSW->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + + exposurePanelSW->add (*exposurePanel); + detailsPanelSW->add (*detailsPanel); + colorPanelSW->add (*colorPanel); + transformPanelSW->add (*transformPanel); + + toolPanelNotebook->append_page (*exposurePanelSW, M("MAIN_TAB_EXPOSURE")); + toolPanelNotebook->append_page (*detailsPanelSW, M("MAIN_TAB_DETAIL")); + toolPanelNotebook->append_page (*colorPanelSW, M("MAIN_TAB_COLOR")); + toolPanelNotebook->append_page (*transformPanelSW, M("MAIN_TAB_TRANSFORM")); + toolPanelNotebook->append_page (*metadataPanel, M("MAIN_TAB_METADATA")); + toolPanelNotebook->set_current_page (0); + + toolPanelNotebook->set_scrollable (); + toolPanelNotebook->show_all (); + + for (int i=0; isetListener (this); + + whitebalance->setWBProvider (this); + whitebalance->setSpotWBListener (this); + rotate->setRotateListener (this); + crop->setCropPanelListener (this); + icm->setICMPanelListener (this); + + toolBar = new ToolBar (); +} + +void ToolPanelCoordinator::addPanel (Gtk::Box* where, Gtk::Container* panel, Glib::ustring label) { + + Gtk::HSeparator *hsep = Gtk::manage (new Gtk::HSeparator()); + where->pack_start(*hsep, Gtk::PACK_SHRINK, 0); + hsep->show(); + +// Gtk::Expander* exp = new Gtk::Expander (); +// exp->set_label_widget (*(new ILabel (Glib::ustring("") + label + ""))); + Gtk::Expander* exp = Gtk::manage (new Gtk::Expander (Glib::ustring("") + label + "")); + exp->set_border_width (4); + exp->set_use_markup (true); + expList.push_back (exp); + + Gtk::Frame* pframe = Gtk::manage (new Gtk::Frame ()); + + pframe->set_name ("ToolPanel"); + + pframe->add (*panel); + panel->show (); + + exp->add (*pframe); + pframe->set_shadow_type (Gtk::SHADOW_ETCHED_IN); + pframe->show (); + exp->show (); + + where->pack_start(*exp, false, false); +} + +ToolPanelCoordinator::~ToolPanelCoordinator () { + + closeImage (); + + delete toolPanelNotebook; + delete toolBar; +} + +void ToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr) { + + if (!ipc) return; + + ProcParams* params = ipc->getParamsForUpdate (event); + for (int i=0; iwrite (params); + + // some transformations make the crop change for convinience + if (event==rtengine::EvResizeScale) { + crop->resizeScaleChanged (params->resize.scale); + crop->write (params); + } + else if (event==rtengine::EvCTHFlip) { + crop->hFlipCrop (); + crop->write (params); + } + else if (event==rtengine::EvCTVFlip) { + crop->vFlipCrop (); + crop->write (params); + } + else if (event==rtengine::EvCTRotate) { + crop->rotateCrop (params->coarse.rotate); + crop->write (params); + } + + ipc->paramsUpdateReady (); + + hasChanged = true; + + for (int i=0; iprocParamsChanged (params, event, descr); +} + +void ToolPanelCoordinator::profileChange (const ProcParams *nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited) { + + if (!ipc) return; + ProcParams* params = ipc->getParamsForUpdate (event); + *params = *nparams; + for (int i=0; iread (nparams); + + ipc->paramsUpdateReady (); + + hasChanged = event != rtengine::EvProfileChangeNotification; + + for (int i=0; iprocParamsChanged (params, event, descr); +} + +void ToolPanelCoordinator::setDefaults (ProcParams* defparams) { + + if (defparams) + for (int i=0; isetDefaults (defparams); +} + +CropGUIListener* ToolPanelCoordinator::getCropGUIListener () { + + return crop; +} + +void ToolPanelCoordinator::initImage (rtengine::StagedImageProcessor* ipc_, bool raw) { + + ipc = ipc_; + curve->disableListener (); + curve->enableAll (); + curve->enableListener (); + + + exifpanel->setImageData (ipc->getInitialImage()->getMetaData()); + iptcpanel->setImageData (ipc->getInitialImage()->getMetaData()); + + if (ipc) { + ipc->setAutoExpListener (curve); + ipc->setSizeListener (crop); + ipc->setSizeListener (resize); + } + + icm->setRaw (raw); + hlrecovery->setRaw (raw); + hasChanged = true; +} + + +void ToolPanelCoordinator::closeImage () { + + if (ipc) { + ipc->stopProcessing (); + ipc = NULL; + } +} + +void ToolPanelCoordinator::readOptions () { + + crop->readOptions (); + for (int i=0; iset_expanded (options.tpOpen[i]); + + if (options.crvOpen.size()>1) + curve->expandCurve (options.crvOpen[0]); +} + +void ToolPanelCoordinator::writeOptions () { + + crop->writeOptions (); + options.tpOpen.clear (); + for (int i=0; iget_expanded ()); + + options.crvOpen.clear (); + options.crvOpen.push_back (curve->isCurveExpanded()); +} + + +void ToolPanelCoordinator::cropSelectionReady () { + + toolBar->setTool (TMHand); + + if (!ipc) + return; +} + +void ToolPanelCoordinator::rotateSelectionReady (double rotate_deg, Thumbnail* thm) { + + toolBar->setTool (TMHand); + + if (!ipc) + return; + + if (rotate_deg!=0.0) + rotate->straighten (rotate_deg); +} + +void ToolPanelCoordinator::spotWBselected (int x, int y, Thumbnail* thm) { + + if (!ipc) + return; + +// toolBar->setTool (TOOL_HAND); + if (x>0 && y>0) { + double temp; + double green; + ipc->getSpotWB (x, y, whitebalance->getSize (), temp, green); + whitebalance->setWB (temp, green); + } +} + +void ToolPanelCoordinator::autoCropRequested () { + + if (!ipc) + return; + + int x1, y1, x2, y2, w, h; + ipc->getAutoCrop (crop->getRatio(), x1, y1, w, h); + x2 = x1 + w - 1; + y2 = y1 + h - 1; + crop->cropInit (x1, y1, w, h); + crop->cropResized (x1, y1, x2, y2); + crop->cropManipReady (); +} + +void ToolPanelCoordinator::straightenRequested () { + + if (!ipc) + return; + + toolBar->setTool (TMStraighten); +} + +void ToolPanelCoordinator::spotWBRequested (int size) { + + if (!ipc) + return; + + toolBar->setTool (TMSpotWB); +} + +void ToolPanelCoordinator::cropSelectRequested () { + + if (!ipc) + return; + + toolBar->setTool (TMCropSelect); +} + +void ToolPanelCoordinator::saveInputICCReference (Glib::ustring fname) { + + if (ipc) + ipc->saveInputICCReference (fname); +} + +int ToolPanelCoordinator::getSpotWBRectSize () { + + return whitebalance->getSize (); +} + +void ToolPanelCoordinator::updateCurveBackgroundHistogram (unsigned* histrgb, unsigned* histl) { + + curve->updateCurveBackgroundHistogram (histrgb); + lcurve->updateCurveBackgroundHistogram (histl); +} diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h new file mode 100644 index 000000000..eb19edd59 --- /dev/null +++ b/rtgui/toolpanelcoord.h @@ -0,0 +1,162 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef __TOOLPANELCCORD__ +#define __TOOLPANELCCORD__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class ImageEditorCoordinator; + +class ToolPanelCoordinator : public ToolPanelListener, + public ProfileChangeListener, + public WBProvider, + public RotateListener, + public SpotWBListener, + public CropPanelListener, + public ICMPanelListener, + public ImageAreaToolListener { + + protected: + + WhiteBalance* whitebalance; + Vignetting* vignetting; + Rotate* rotate; + Distortion* distortion; + CACorrection* cacorrection; + ColorShift* colorshift; + HLRecovery* hlrecovery; + ChMixer* chmixer; + ColorBoost* colorboost; + Resize* resize; + ICMPanel* icm; + Crop* crop; + ToneCurve* curve; + ShadowsHighlights* shadowshighlights; + LumaDenoise* lumadenoise; + ColorDenoise* colordenoise; + Sharpening* sharpening; + LCurve* lcurve; + + std::vector paramcListeners; + + rtengine::StagedImageProcessor* ipc; + + std::vector toolPanels; + Gtk::VBox* exposurePanel; + Gtk::VBox* detailsPanel; + Gtk::VBox* colorPanel; + Gtk::VBox* transformPanel; + Gtk::Notebook* metadataPanel; + ExifPanel* exifpanel; + IPTCPanel* iptcpanel; + ToolBar* toolBar; + + std::vector expList; + + bool hasChanged; + + void addPanel (Gtk::Box* where, Gtk::Container* panel, Glib::ustring label); + + public: + + CoarsePanel* coarse; + Gtk::Notebook* toolPanelNotebook; + + ToolPanelCoordinator (); + ~ToolPanelCoordinator (); + + bool getChangedState () { return hasChanged; } + void updateCurveBackgroundHistogram (unsigned* histrgb, unsigned* histl); + + // multiple listeners can be added that are notified on changes (typical: profile panel and the history) + void addPParamsChangeListener (PParamsChangeListener* pp) { paramcListeners.push_back (pp); } + + // toolpanellistener interface + void panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr); + + // profilechangelistener interface + void profileChange (const rtengine::procparams::ProcParams* nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited=NULL); + void setDefaults (rtengine::procparams::ProcParams* defparams); + + // to support the GUI: + CropGUIListener* getCropGUIListener (); // through the CropGUIListener the editor area can notify the "crop" ToolPanel when the crop selection changes + + // init the toolpanelcoordinator with an image & close it + void initImage (rtengine::StagedImageProcessor* ipc_, bool israw); + void closeImage (); + + // read/write the "expanded" state of the expanders & read/write the crop panel settings (ratio, guide type, etc.) + void readOptions (); + void writeOptions (); + + // wbprovider interface + void getAutoWB (double& temp, double& green) { if (ipc) ipc->getAutoWB (temp, green); } + void getCamWB (double& temp, double& green) { if (ipc) ipc->getCamWB (temp, green); } + + // rotatelistener interface + void straightenRequested (); + void autoCropRequested (); + + // spotwblistener interface + void spotWBRequested (int size); + + // croppanellistener interface + void cropSelectRequested (); + + // icmpanellistener interface + void saveInputICCReference (Glib::ustring fname); + + // imageareatoollistener interface + void spotWBselected (int x, int y, Thumbnail* thm=NULL); + void cropSelectionReady (); + void rotateSelectionReady (double rotate_deg, Thumbnail* thm=NULL); + ToolBar* getToolBar () { return toolBar; } + int getSpotWBRectSize (); + CropGUIListener* startCropEditing (Thumbnail* thm=NULL) { return crop; } +}; + +#endif diff --git a/rtgui/utils.cc b/rtgui/utils.cc new file mode 100644 index 000000000..06d67aa2f --- /dev/null +++ b/rtgui/utils.cc @@ -0,0 +1,39 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +void removeIfThere (Gtk::Container* cont, Gtk::Widget* w) { + + Glib::ListHandle list = cont->get_children (); + Glib::ListHandle::iterator i = list.begin (); + for (; i!=list.end() && *i!=w; i++); + if (i!=list.end()) { + w->reference (); + cont->remove (*w); + } +} + +void thumbInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh) { + + if (options.thumbInterp==0) + rtengine::nearestInterp (src, sw, sh, dst, dw, dh); + else if (options.thumbInterp==1) + rtengine::bilinearInterp (src, sw, sh, dst, dw, dh); +} diff --git a/rtgui/utils.h b/rtgui/utils.h new file mode 100644 index 000000000..dfcc299f0 --- /dev/null +++ b/rtgui/utils.h @@ -0,0 +1,27 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef __UTILS_ +#define __UTILS_ + +#include + +void removeIfThere (Gtk::Container* cont, Gtk::Widget* w); +void thumbInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh); + +#endif diff --git a/rtgui/vignetting.cc b/rtgui/vignetting.cc new file mode 100644 index 000000000..1d35bc9e5 --- /dev/null +++ b/rtgui/vignetting.cc @@ -0,0 +1,90 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +Vignetting::Vignetting () : vigAdd(false) { + + amount = Gtk::manage (new Adjuster (M("TP_VIGNETTING_AMOUNT"), -100, 100, 1, 0)); + amount->setAdjusterListener (this); + + radius = Gtk::manage (new Adjuster (M("TP_VIGNETTING_RADIUS"), 0, 100, 1, 50)); + radius->setAdjusterListener (this); + + pack_start (*amount); + pack_start (*radius); + + show_all(); +} + +void Vignetting::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) + amount->setEditedState (pedited->vignetting.amount ? Edited : UnEdited); + + amount->setValue (pp->vignetting.amount); + radius->setValue (pp->vignetting.radius); + + enableListener (); +} + +void Vignetting::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->vignetting.amount = (int)amount->getValue (); + pp->vignetting.radius = (int)radius->getValue (); + + if (pedited) + pedited->vignetting.amount = amount->getEditedState (); +} + +void Vignetting::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + amount->setDefault (defParams->vignetting.amount); + radius->setDefault (defParams->vignetting.radius); + + if (pedited) + amount->setDefaultEditedState (pedited->vignetting.amount ? Edited : UnEdited); + else + amount->setDefaultEditedState (Irrelevant); +} + +void Vignetting::adjusterChanged (Adjuster* a, double newval) { + + if (listener) + listener->panelChanged (EvVignetting, Glib::ustring::compose ("%1=%3\n%2=%4", M("TP_VIGNETTING_AMOUNT"), M("TP_VIGNETTING_RADIUS"), (int)amount->getValue(), (int)radius->getValue())); +} + +void Vignetting::setAdjusterBehavior (bool bvadd) { + + if (!vigAdd && bvadd || vigAdd && !bvadd) + amount->setLimits (-100, 100, 1, 0); + + vigAdd = bvadd; +} + +void Vignetting::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + amount->showEditedCB (); +} diff --git a/rtgui/vignetting.h b/rtgui/vignetting.h new file mode 100644 index 000000000..ff65e9584 --- /dev/null +++ b/rtgui/vignetting.h @@ -0,0 +1,46 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _VIGNETTING_H_ +#define _VIGNETTING_H_ + +#include +#include +#include + +class Vignetting : public Gtk::VBox, public AdjusterListener, public ToolPanel { + + protected: + Adjuster* amount; + Adjuster* radius; + bool vigAdd; + + public: + + Vignetting (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void setAdjusterBehavior (bool bvadd); +}; + +#endif diff --git a/rtgui/wbprovider.h b/rtgui/wbprovider.h new file mode 100644 index 000000000..f5f70ba9d --- /dev/null +++ b/rtgui/wbprovider.h @@ -0,0 +1,31 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _WBPROVIDER_ +#define _WBPROVIDER_ + + +class WBProvider { + + public: + virtual void getAutoWB (double& temp, double& green) {} + virtual void getCamWB (double& temp, double& green) {} + virtual void spotWBRequested (int size) {} +}; + +#endif diff --git a/rtgui/whitebalance.cc b/rtgui/whitebalance.cc new file mode 100644 index 000000000..833c5a433 --- /dev/null +++ b/rtgui/whitebalance.cc @@ -0,0 +1,297 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include + +#define MINTEMP 1200 +#define MAXTEMP 12000 +#define MINGREEN 0.02 +#define MAXGREEN 5.0 + +extern Glib::ustring argv0; + +using namespace rtengine; +using namespace rtengine::procparams; + +WhiteBalance::WhiteBalance () : ToolPanel(), wbp(NULL), wblistener(NULL), tempAdd(false), greenAdd (false) { + + Gtk::HBox* hbox = Gtk::manage (new Gtk::HBox ()); + hbox->show (); + Gtk::Label* lab = Gtk::manage (new Gtk::Label (M("TP_WBALANCE_METHOD"))); + lab->show (); + method = Gtk::manage (new Gtk::ComboBoxText ()); + method->show (); + method->append_text (M("TP_WBALANCE_CAMERA")); + method->append_text (M("TP_WBALANCE_AUTO")); + method->append_text (M("TP_WBALANCE_CUSTOM")); + method->set_active (0); + hbox->pack_start (*lab, Gtk::PACK_SHRINK, 4); + hbox->pack_start (*method); + pack_start (*hbox, Gtk::PACK_SHRINK, 4); + opt = 0; + + Gtk::HBox* spotbox = Gtk::manage (new Gtk::HBox ()); + spotbox->show (); + + spotbutton = Gtk::manage (new Gtk::Button (M("TP_WBALANCE_SPOTWB"))); + Gtk::Image* spotimg = Gtk::manage (new Gtk::Image (argv0+"/images/wbpicker16.png")); + spotimg->show (); + spotbutton->set_image (*spotimg); + spotbutton->show (); + + spotbox->pack_start (*spotbutton); + + Gtk::Label* slab = Gtk::manage (new Gtk::Label (M("TP_WBALANCE_SIZE"))); + slab->show (); + + spotsize = Gtk::manage (new Gtk::ComboBoxText ()); + spotsize->show (); + spotsize->append_text ("2"); + spotsize->append_text ("4"); + spotsize->append_text ("8"); + spotsize->append_text ("16"); + spotsize->append_text ("32"); + spotsize->set_active (2); + + spotbox->pack_end (*spotsize, Gtk::PACK_SHRINK, 4); + spotbox->pack_end (*slab, Gtk::PACK_SHRINK, 4); + + pack_start (*spotbox, Gtk::PACK_SHRINK, 4); + + temp = Gtk::manage (new Adjuster (M("TP_WBALANCE_TEMPERATURE"), MINTEMP, MAXTEMP, 1, 4750)); + green = Gtk::manage (new Adjuster (M("TP_WBALANCE_GREEN"), MINGREEN, MAXGREEN, 0.001, 1.2)); + temp->show (); + green->show (); + + pack_start (*temp); + pack_start (*green); + + temp->setAdjusterListener (this); + green->setAdjusterListener (this); + + spotbutton->signal_pressed().connect( sigc::mem_fun(*this, &WhiteBalance::spotPressed) ); + methconn = method->signal_changed().connect( sigc::mem_fun(*this, &WhiteBalance::optChanged) ); + spotsize->signal_changed().connect( sigc::mem_fun(*this, &WhiteBalance::spotSizeChanged) ); +} + +void WhiteBalance::adjusterChanged (Adjuster* a, double newval) { + + if (method->get_active_row_number()!=2) { + disableListener (); + method->set_active (2); + enableListener (); + } + + if (listener) { + if (a==temp) + listener->panelChanged (EvWBTemp, Glib::ustring::format ((int)a->getValue())); + else if (a==green) + listener->panelChanged (EvWBGreen, Glib::ustring::format (std::setw(4), std::fixed, std::setprecision(3), a->getValue())); + } +} + +void WhiteBalance::optChanged () { + + if (opt!=method->get_active_row_number()) { + opt = method->get_active_row_number(); + Glib::ustring meth = M("TP_WBALANCE_CUSTOM"); + if (opt==0 && wbp) { + double ctemp; double cgreen; + wbp->getCamWB (ctemp, cgreen); + temp->setValue (tempAdd ? 0.0 : (int)ctemp); + green->setValue (greenAdd ? 0.0 : cgreen); + meth = M("TP_WBALANCE_CAMERA"); + if (batchMode) { + temp->setEditedState (UnEdited); + green->setEditedState (UnEdited); + } + } + else if (opt==1 && wbp) { + double ctemp; double cgreen; + wbp->getAutoWB (ctemp, cgreen); + temp->setValue (tempAdd ? 0.0 : (int)ctemp); + green->setValue (greenAdd ? 0.0 : cgreen); + meth = M("TP_WBALANCE_AUTO"); + if (batchMode) { + temp->setEditedState (UnEdited); + green->setEditedState (UnEdited); + } + } + else if (opt==3) { + meth = M("GENERAL_UNCHANGED"); + temp->setEditedState (UnEdited); + green->setEditedState (UnEdited); + } + if (listener) + listener->panelChanged (EvWBMethod, meth); + } +} + +void WhiteBalance::spotPressed () { + + if (wblistener) + wblistener->spotWBRequested (getSize()); +} + +void WhiteBalance::spotSizeChanged () { + + if (wblistener) + wblistener->spotWBRequested (getSize()); +} + +void WhiteBalance::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + methconn.block (true); + + if (pedited) { + temp->setEditedState (UnEdited); + green->setEditedState (UnEdited); + } + + if (pedited && !pedited->wb.method) { + method->set_active (3); + opt = 3; + } + else { + if (pp->wb.method == "Camera") { + method->set_active (0); + if (wbp) { + double ctemp; double cgreen; + wbp->getCamWB (ctemp, cgreen); + temp->setValue (tempAdd ? 0.0 : (int)ctemp); + green->setValue (greenAdd ? 0.0 : cgreen); + } + opt = 0; + } + else if (pp->wb.method == "Auto") { + method->set_active (1); + if (wbp) { + double ctemp; double cgreen; + wbp->getAutoWB (ctemp, cgreen); + temp->setValue (tempAdd ? 0.0 : (int)ctemp); + green->setValue (greenAdd ? 0.0 : cgreen); + } + opt = 1; + } + else if (pp->wb.method == "Custom") { + method->set_active (2); + temp->setValue (pp->wb.temperature); + green->setValue (pp->wb.green); + opt = 2; + if (pedited) { + temp->setEditedState (pedited->wb.temperature ? Edited : UnEdited); + green->setEditedState (pedited->wb.green ? Edited : UnEdited); + } + } + } + methconn.block (false); + enableListener (); +} + +void WhiteBalance::write (ProcParams* pp, ParamsEdited* pedited) { + + if (pedited) { + pedited->wb.temperature = temp->getEditedState (); + pedited->wb.green = green->getEditedState (); + pedited->wb.method = method->get_active_row_number()!=3; + } + + if (method->get_active_row_number()==0) + pp->wb.method = "Camera"; + else if (method->get_active_row_number()==1) + pp->wb.method = "Auto"; + else if (method->get_active_row_number()>=2) + pp->wb.method = "Custom"; + + pp->wb.temperature = (int)temp->getValue (); + pp->wb.green = green->getValue (); + +} + +void WhiteBalance::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + if (wbp && defParams->wb.method == "Camera") { + double ctemp; double cgreen; + wbp->getCamWB (ctemp, cgreen); + temp->setDefault (tempAdd ? 0 : (int)ctemp); + green->setDefault (greenAdd ? 0 : cgreen); + } + else if (wbp && defParams->wb.method == "Auto") { + double ctemp; double cgreen; + wbp->getAutoWB (ctemp, cgreen); + temp->setDefault (tempAdd ? 0 : (int)ctemp); + green->setDefault (greenAdd ? 0 : cgreen); + } + else if (defParams->wb.method == "Custom") { + temp->setDefault (defParams->wb.temperature); + green->setDefault (defParams->wb.green); + } + if (pedited) { + temp->setDefaultEditedState (pedited->wb.temperature ? Edited : UnEdited); + green->setDefaultEditedState (pedited->wb.green ? Edited : UnEdited); + } + else { + temp->setDefaultEditedState (Irrelevant); + green->setDefaultEditedState (Irrelevant); + } +} + +void WhiteBalance::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + temp->showEditedCB (); + green->showEditedCB (); + method->append_text (M("GENERAL_UNCHANGED")); +} + +int WhiteBalance::getSize () { + + return atoi(spotsize->get_active_text().c_str()); +} + +void WhiteBalance::setWB (int vtemp, double vgreen) { + + disableListener (); + temp->setValue (vtemp); + green->setValue (vgreen); + method->set_active (2); + temp->setEditedState (Edited); + green->setEditedState (Edited); + enableListener (); + + if (listener) + listener->panelChanged (EvWBTemp, Glib::ustring::compose("%1, %2", (int)temp->getValue(), Glib::ustring::format (std::setw(4), std::fixed, std::setprecision(3), green->getValue()))); +} + void WhiteBalance::setAdjusterBehavior (bool btempadd, bool bgreenadd) { + + if (!tempAdd && btempadd) + temp->setLimits (-4000, +4000, 1, 0); + else if (tempAdd && !btempadd) + temp->setLimits (MINTEMP, MAXTEMP, 1, 4750); + + if (!greenAdd && bgreenadd) + green->setLimits (-1.0, +1.0, 0.001, 0); + else if (greenAdd && bgreenadd) + green->setLimits (MINGREEN, MAXGREEN, 0.001, 1.2); + + tempAdd = btempadd; + greenAdd = bgreenadd; +} + diff --git a/rtgui/whitebalance.h b/rtgui/whitebalance.h new file mode 100644 index 000000000..89e6b97d8 --- /dev/null +++ b/rtgui/whitebalance.h @@ -0,0 +1,71 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _WB_H_ +#define _WB_H_ + +#include +#include +#include +#include + +class SpotWBListener { + + public: + virtual void spotWBRequested (int size) {} +}; + +class WhiteBalance : public Gtk::VBox, public AdjusterListener, public ToolPanel { + + protected: + Gtk::ComboBoxText* method; + Gtk::ComboBoxText* spotsize; + Adjuster* temp; + Adjuster* green; + Gtk::Button* spotbutton; + int opt; + double nextTemp; + double nextGreen; + WBProvider *wbp; + SpotWBListener* wblistener; + sigc::connection methconn; + bool tempAdd, greenAdd; + + public: + + WhiteBalance (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + + void optChanged (); + void spotPressed (); + void spotSizeChanged (); + void adjusterChanged (Adjuster* a, double newval); + int getSize (); + void setWBProvider (WBProvider* p) { wbp = p; } + void setSpotWBListener (SpotWBListener* l) { wblistener = l; } + void setWB (int temp, double green); + + void setAdjusterBehavior (bool btempadd, bool bgreenadd); +}; + +#endif diff --git a/rtgui/windirmonitor.cc b/rtgui/windirmonitor.cc new file mode 100644 index 000000000..b5284a02a --- /dev/null +++ b/rtgui/windirmonitor.cc @@ -0,0 +1,80 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include + +static void CALLBACK current_directory_monitor_callback (DWORD error, DWORD nBytes, LPOVERLAPPED lpOverlapped) { + +// printf ("hivas: %d %d %d\n", error, nBytes, lpOverlapped); + + WinDirMonitor::MonitorData* monData = (WinDirMonitor::MonitorData*)lpOverlapped; + if (!nBytes) { + delete monData; + return; + } + + if (monData->listener) + monData->listener->winDirChanged (); + + ReadDirectoryChangesW (monData->hDirectory, + monData->file_notify_buffer, + monData->buffer_allocated_bytes, + FALSE, + FILE_NOTIFY_CHANGE_FILE_NAME | + FILE_NOTIFY_CHANGE_DIR_NAME | + FILE_NOTIFY_CHANGE_ATTRIBUTES | + FILE_NOTIFY_CHANGE_SIZE, + &monData->buffer_filled_bytes, + &monData->overlapped, + current_directory_monitor_callback); +} + +WinDirMonitor::WinDirMonitor (Glib::ustring dirName, WinDirChangeListener* listener) : monData(NULL) { + + wchar_t* wdirname = (wchar_t*)g_utf8_to_utf16 (dirName.raw().c_str(), -1, NULL, NULL, NULL); + HANDLE hDirectory = CreateFileW (wdirname, FILE_LIST_DIRECTORY,FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL); + g_free (wdirname); + + if (hDirectory != INVALID_HANDLE_VALUE) { + + monData = new MonitorData (); + monData->listener = listener; + monData->buffer_allocated_bytes = 32768; + monData->file_notify_buffer = new char [monData->buffer_allocated_bytes]; + monData->hDirectory = hDirectory; + +// printf ("mondata=%d\n", monData); + ReadDirectoryChangesW (monData->hDirectory, + monData->file_notify_buffer, + monData->buffer_allocated_bytes, + FALSE, + FILE_NOTIFY_CHANGE_FILE_NAME | + FILE_NOTIFY_CHANGE_DIR_NAME | + FILE_NOTIFY_CHANGE_ATTRIBUTES | + FILE_NOTIFY_CHANGE_SIZE, + &monData->buffer_filled_bytes, + &monData->overlapped, + current_directory_monitor_callback); + } +} + +WinDirMonitor::~WinDirMonitor () { + + if (monData && monData->hDirectory != INVALID_HANDLE_VALUE) + CloseHandle (monData->hDirectory); +} diff --git a/rtgui/windirmonitor.h b/rtgui/windirmonitor.h new file mode 100644 index 000000000..10f4b39f2 --- /dev/null +++ b/rtgui/windirmonitor.h @@ -0,0 +1,53 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _WINDIRMONITOR_ +#define _WINDIRMONITOR_ + +#include +#include + +class WinDirChangeListener { + + public: + virtual void winDirChanged () {} +}; + +class WinDirMonitor : public Glib::Object { + + public: + struct MonitorData { + OVERLAPPED overlapped; + DWORD buffer_allocated_bytes; + char *file_notify_buffer; + DWORD buffer_filled_bytes; + HANDLE hDirectory; + WinDirChangeListener* listener; + int bigyo; + }; + + private: + MonitorData* monData; + + public: + WinDirMonitor (Glib::ustring dirName, WinDirChangeListener* listener); + ~WinDirMonitor (); +}; + +#endif + diff --git a/rtgui/zoompanel.cc b/rtgui/zoompanel.cc new file mode 100644 index 000000000..ac0876c07 --- /dev/null +++ b/rtgui/zoompanel.cc @@ -0,0 +1,121 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#include +#include +#include + +ZoomPanel::ZoomPanel (ImageArea* iarea) : iarea(iarea) { + + set_border_width (0); + + Gtk::Label* label = Gtk::manage (new Gtk::Label (Glib::ustring("") + "Zoom" + ": ")); + label->set_use_markup (true); + + pack_start (*label, Gtk::PACK_SHRINK, 4); + + Gtk::Image* imageOut = Gtk::manage (new Gtk::Image (Gtk::StockID ("gtk-zoom-out"), Gtk::ICON_SIZE_SMALL_TOOLBAR)); + imageOut->set_padding(0,0); + Gtk::Image* imageIn = Gtk::manage (new Gtk::Image (Gtk::StockID ("gtk-zoom-in"), Gtk::ICON_SIZE_SMALL_TOOLBAR)); + imageIn->set_padding(0,0); + Gtk::Image* image11 =Gtk::manage ( new Gtk::Image (Gtk::StockID ("gtk-zoom-100"), Gtk::ICON_SIZE_SMALL_TOOLBAR)); + image11->set_padding(0,0); + Gtk::Image* imageFit = Gtk::manage (new Gtk::Image (Gtk::StockID ("gtk-zoom-fit"), Gtk::ICON_SIZE_SMALL_TOOLBAR)); + imageFit->set_padding(0,0); + + zoomOut = Gtk::manage (new Gtk::Button()); + zoomOut->add (*imageOut); + zoomOut->set_relief(Gtk::RELIEF_NONE); + zoomIn = Gtk::manage (new Gtk::Button()); + zoomIn->add (*imageIn); + zoomIn->set_relief(Gtk::RELIEF_NONE); + zoomFit = Gtk::manage (new Gtk::Button()); + zoomFit->add (*imageFit); + zoomFit->set_relief(Gtk::RELIEF_NONE); + zoom11 = Gtk::manage (new Gtk::Button()); + zoom11->add (*image11); + zoom11->set_relief(Gtk::RELIEF_NONE); + + pack_start (*zoomOut, Gtk::PACK_SHRINK, 0); + pack_start (*zoomIn, Gtk::PACK_SHRINK, 0); + pack_start (*zoomFit, Gtk::PACK_SHRINK, 0); + pack_start (*zoom11, Gtk::PACK_SHRINK, 0); + + zoomLabel = Gtk::manage (new Gtk::Label ()); + pack_start (*zoomLabel, Gtk::PACK_SHRINK, 4); + + Gtk::Image* imageCrop = Gtk::manage (new Gtk::Image (Gtk::StockID ("gtk-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR)); + imageCrop->set_padding(0,0); + newCrop = Gtk::manage (new Gtk::Button()); + newCrop->add (*imageCrop); + newCrop->set_relief(Gtk::RELIEF_NONE); + pack_start (*newCrop, Gtk::PACK_SHRINK, 4); + + show_all_children (); + + zoomIn->signal_clicked().connect ( sigc::mem_fun(*this, &ZoomPanel::zoomInClicked) ); + zoomOut->signal_clicked().connect( sigc::mem_fun(*this, &ZoomPanel::zoomOutClicked) ); + zoomFit->signal_clicked().connect( sigc::mem_fun(*this, &ZoomPanel::zoomFitClicked) ); + zoom11->signal_clicked().connect ( sigc::mem_fun(*this, &ZoomPanel::zoom11Clicked) ); + newCrop->signal_clicked().connect ( sigc::mem_fun(*this, &ZoomPanel::newCropClicked) ); + + zoomIn->set_tooltip_text (M("ZOOMPANEL_ZOOMIN")); + zoomOut->set_tooltip_text (M("ZOOMPANEL_ZOOMOUT")); + zoom11->set_tooltip_text (M("ZOOMPANEL_ZOOM100")); + zoomFit->set_tooltip_text (M("ZOOMPANEL_ZOOMFITSCREEN")); + newCrop->set_tooltip_text (M("ZOOMPANEL_NEWCROPWINDOW")); + + zoomLabel->set_text (M("ZOOMPANEL_100")); +} + +void ZoomPanel::zoomInClicked () { + + if (iarea->mainCropWindow) + iarea->mainCropWindow->zoomIn (); +} + +void ZoomPanel::zoomOutClicked () { + + if (iarea->mainCropWindow) + iarea->mainCropWindow->zoomOut (); +} + +void ZoomPanel::zoomFitClicked () { + + if (iarea->mainCropWindow) + iarea->mainCropWindow->zoomFit (); +} + +void ZoomPanel::zoom11Clicked () { + + if (iarea->mainCropWindow) + iarea->mainCropWindow->zoom11 (); +} + +void ZoomPanel::refreshZoomLabel () { + + if (iarea->mainCropWindow) { + int z = (int)(iarea->mainCropWindow->getZoom () * 100); + zoomLabel->set_text (Glib::ustring::compose("%1%%", z)); + } +} + +void ZoomPanel::newCropClicked () { + + iarea->addCropWindow (); +} diff --git a/rtgui/zoompanel.h b/rtgui/zoompanel.h new file mode 100644 index 000000000..2733c0a71 --- /dev/null +++ b/rtgui/zoompanel.h @@ -0,0 +1,50 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . + */ +#ifndef _ZOOMPANEL_ +#define _ZOOMPANEL_ + +#include + +class ImageArea; +class ZoomPanel : public Gtk::HBox { + + protected: + + Gtk::Button* zoomOut; + Gtk::Button* zoomIn; + Gtk::Button* zoomFit; + Gtk::Button* zoom11; + Gtk::Button* newCrop; + Gtk::Label* zoomLabel; + ImageArea* iarea; + + public: + + ZoomPanel (ImageArea* iarea); + + void zoomInClicked (); + void zoomOutClicked (); + void zoomFitClicked (); + void zoom11Clicked (); + void newCropClicked (); + void refreshZoomLabel (); +}; + +#endif + diff --git a/rtinstaller.nsi b/rtinstaller.nsi new file mode 100644 index 000000000..8a7227ed9 --- /dev/null +++ b/rtinstaller.nsi @@ -0,0 +1,135 @@ +;NSIS Modern User Interface +;Start Menu Folder Selection Example Script +;Written by Joost Verburg + +;-------------------------------- +;Include Modern UI + + !include "MUI2.nsh" + +;-------------------------------- +;General + SetCompressor /SOLID lzma + + ;Name and file + Name "Raw Therapee 3.0 alpha 1" + OutFile "rawtherapee30a1.exe" + + ;Default installation folder + InstallDir "$PROGRAMFILES\Raw Therapee 3.0 A1" + + ;Get installation folder from registry if available + InstallDirRegKey HKCU "Software\Raw Therapee 3.0 A1" "" + + ;Request application privileges for Windows Vista + RequestExecutionLevel admin + +;-------------------------------- +;Variables + + Var StartMenuFolder + +;-------------------------------- +;Interface Settings + + !define MUI_ABORTWARNING + +;-------------------------------- +;Pages + +# !insertmacro MUI_PAGE_LICENSE "${NSISDIR}\Docs\Modern UI\License.txt" + !insertmacro MUI_PAGE_COMPONENTS + !insertmacro MUI_PAGE_DIRECTORY + + ;Start Menu Folder Page Configuration + !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU" + !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\Raw Therapee 3.0 A1" + !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder" + !define MUI_STARTMENUPAGE_DEFAULTFOLDER "Raw Therapee" + + !insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder + + !insertmacro MUI_PAGE_INSTFILES + + !insertmacro MUI_UNPAGE_CONFIRM + !insertmacro MUI_UNPAGE_INSTFILES + +;-------------------------------- +;Languages + + !insertmacro MUI_LANGUAGE "English" + +;-------------------------------- +;Installer Sections + +;First possible component +Section "Binaries" Component1 + SectionIn 1 RO + SetOutPath "$INSTDIR" + + ;ADD YOUR OWN FILES HERE... + AddSize 34553 + File /r /x rtinstaller.nsi *.* + + ;Store installation folder + WriteRegStr HKCU "Software\Raw Therapee" "" $INSTDIR + + ;Create uninstaller + WriteUninstaller "$INSTDIR\Uninstall.exe" + + !insertmacro MUI_STARTMENU_WRITE_BEGIN Application + ;Create shortcuts + CreateDirectory "$SMPROGRAMS\$StartMenuFolder" + CreateShortCut "$SMPROGRAMS\$StartMenuFolder\Raw Therapee.lnk" "$INSTDIR\rt.exe" + CreateShortCut "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk" "$INSTDIR\Uninstall.exe" + !insertmacro MUI_STARTMENU_WRITE_END +SectionEnd + +Section "Desktop Shortcut" Component2 + ;Create Shortcut + CreateShortCut "$DESKTOP\Raw Therapee.lnk" "$INSTDIR\rt.exe" +SectionEnd + +Section "Quicklaunch Shortcut" Component3 + ;Create Shortcut + CreateShortCut "$QUICKLAUNCH\Raw Therapee.lnk" "$INSTDIR\rt.exe" +SectionEnd +;-------------------------------- +;Descriptions + + ;Language strings + LangString DESC_Component1 ${LANG_ENGLISH} "Raw Therapee Binaries" + LangString DESC_Component2 ${LANG_ENGLISH} "Create Raw Therapee shortcut on desktop" + LangString DESC_Component3 ${LANG_ENGLISH} "Create Raw Therapee shortcut on quicklaunch bar" + + ;Assign language strings to sections + !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN + !insertmacro MUI_DESCRIPTION_TEXT ${Component1} $(DESC_Component1) + !insertmacro MUI_DESCRIPTION_TEXT ${Component2} $(DESC_Component2) + !insertmacro MUI_DESCRIPTION_TEXT ${Component3} $(DESC_Component3) + !insertmacro MUI_FUNCTION_DESCRIPTION_END + +;-------------------------------- +;Uninstaller Section + +Section "Uninstall" + + ;ADD YOUR OWN FILES HERE... + + Delete "$INSTDIR\Uninstall.exe" + + RMDir "$INSTDIR" + + !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder + + Delete "$SMPROGRAMS\$StartMenuFolder\Raw Therapee.lnk" + Delete "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk" + Delete "$DESKTOP\Raw Therapee.lnk" + Delete "$QUICKLAUNCH\Raw Therapee.lnk" + RMDir /r "$INSTDIR" + RMDir "$SMPROGRAMS\$StartMenuFolder" + + DeleteRegKey HKCU "Software\Raw Therapee 3.0 A1" + + +SectionEnd \ No newline at end of file diff --git a/rtstart b/rtstart new file mode 100755 index 000000000..2bc895444 --- /dev/null +++ b/rtstart @@ -0,0 +1,4 @@ +#!/bin/bash + +export LD_LIBRARY_PATH=`dirname "$0"` +`dirname "$0"`/rt \ No newline at end of file diff --git a/tools/createicon.exe b/tools/createicon.exe new file mode 100644 index 000000000..0c192be2d Binary files /dev/null and b/tools/createicon.exe differ diff --git a/tools/edited.png b/tools/edited.png new file mode 100644 index 000000000..bbc0dae98 Binary files /dev/null and b/tools/edited.png differ diff --git a/tools/editedb.png b/tools/editedb.png new file mode 100644 index 000000000..d9aa74739 Binary files /dev/null and b/tools/editedb.png differ diff --git a/tools/editedw.png b/tools/editedw.png new file mode 100644 index 000000000..9bfdfa5ca Binary files /dev/null and b/tools/editedw.png differ diff --git a/tools/head.png b/tools/head.png new file mode 100644 index 000000000..29b5b934a Binary files /dev/null and b/tools/head.png differ diff --git a/tools/headb.png b/tools/headb.png new file mode 100644 index 000000000..9d3fc2d75 Binary files /dev/null and b/tools/headb.png differ diff --git a/tools/headw.png b/tools/headw.png new file mode 100644 index 000000000..bbbc01b2d Binary files /dev/null and b/tools/headw.png differ diff --git a/tools/horizontal.svg b/tools/horizontal.svg new file mode 100644 index 000000000..850b9f33e --- /dev/null +++ b/tools/horizontal.svg @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/tools/osx/Icons.icns b/tools/osx/Icons.icns new file mode 100644 index 000000000..d06b7199e Binary files /dev/null and b/tools/osx/Icons.icns differ diff --git a/tools/osx/Info.plist b/tools/osx/Info.plist new file mode 100644 index 000000000..4020ef513 --- /dev/null +++ b/tools/osx/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + start + CFBundleIconFile + Icons.icns + CFBundleIdentifier + com.rawtherapee.rawtherapee + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + RawTherapee + CFBundlePackageType + APPL + CFBundleShortVersionString + 3.0a + CFBundleSignature + APPL + CFBundleVersion + 3.0 Alpha + NSAppleScriptEnabled + NO + + diff --git a/tools/osx/make-app-bundle b/tools/osx/make-app-bundle new file mode 100755 index 000000000..388f1082f --- /dev/null +++ b/tools/osx/make-app-bundle @@ -0,0 +1,100 @@ +#!/bin/bash +# Function checkLink: +# args: $1 - file +# +# Will loop through all dynamic links for $file, and update each to be relative. +function checkLink { + #echo "checkLink called with $1 $2" + local FILE=$1 + + otool -L $FILE | grep -v "${APP}" | grep -v '/usr/lib' | grep -v '/System/' | grep -v "@executable_path" | cut -f 1 -d ' ' | while read X + do + local NAME=${LIB}/`basename "$X"` + if [ ! -f "${NAME}" ] + then + cp $X "${NAME}" + + #Recursively update the linkage of libraries + checkLink "${NAME}" + fi + done +} + +APP=RawTherapee.app +CONTENTS=${APP}/Contents +RESOURCES=${CONTENTS}/Resources +MACOS=${CONTENTS}/MacOS +BIN=${MACOS}/bin +ETC=${MACOS}/etc +LIB=${MACOS}/lib +SHARE=${MACOS}/share +RELEASE=release +DMG=${RELEASE}/RawTherapee.dmg +EXECUTABLE=rt + +#Find where MacPorts is installed. We take a known binary (cmake), which is in /bin, and +# go up a level to get the main install folder. +MACPORTS_PREFIX=`which cmake` +MACPORTS_PREFIX=`dirname $MACPORTS_PREFIX` +MACPORTS_PREFIX=`dirname $MACPORTS_PREFIX` + +if [ ! -d ${RELEASE} ]; then + echo "Please run this from the root of the project; i.e. './tools/osx/make-app-bundle'." + exit +fi + +if [ -d "${APP}" ]; then + echo "Removing old application..." + rm -rf "${APP}" +fi +if [ -f ${DMG} ]; then + echo "Removing old disk image..." + rm "${DMG}" +fi + +echo "Making application directory structure..." +mkdir -p "${RESOURCES}" +mkdir -p "${ETC}" +mkdir -p "${LIB}" +mkdir -p "${SHARE}/mime" + +#Copy over non-explicitly linked libraries +echo "Copying libraries from ${MACPORTS_PREFIX}..." +cp -R ${MACPORTS_PREFIX}/lib/pango ${LIB} +cp -R ${MACPORTS_PREFIX}/lib/gtk-2.0 ${LIB} + +#Copy over mimes (if a mime is copied, and nobody hears, is it really copied?) +echo "Copying shared files from ${MACPORTS_PREFIX}..." +cp -R ${MACPORTS_PREFIX}/share/mime/* ${SHARE}/mime + +#Copy over etc files, and modify as needed +echo "Copying configuration files from ${MACPORTS_PREFIX} and modifying for standalone app bundle..." +cp -R $MACPORTS_PREFIX/etc/gtk-2.0 ${ETC} +cp -R $MACPORTS_PREFIX/etc/pango ${ETC} +ESCAPED_MACPORTS_PREFIX=`echo ${MACPORTS_PREFIX} | sed -e 's/\\//\\\\\\//g'` +sed -i .bak -e "s/${ESCAPED_MACPORTS_PREFIX}/@executable_path/g" ${ETC}/gtk-2.0/gdk-pixbuf.loaders ${ETC}/pango/pango.modules +echo -e "[Pango]\nModuleFiles = /tmp/${EXECUTABLE}_pango.modules" > ${ETC}/pango/pangorc + + +#Copy over the release files +echo "Copying release files..." +cp -R release/* ${MACOS} + +#Copy application-specific stuff like icons and startup script +echo "Creating required application bundle files..." +cp ./tools/osx/Info.plist ${CONTENTS} +cp tools/osx/Icons.icns ${RESOURCES} +cp tools/osx/start ${MACOS} + +#Copy and relink the explicitly defined libraries +echo "Recursively copying libraries referenced by executable..." +checkLink "${MACOS}/${EXECUTABLE}" + + +#Make a .dmg for distribution and delete the .app +echo "Creating distribution .dmg..." +hdiutil create -srcdir ${APP} ${DMG} +echo "Cleaning up..." +rm -rf ${APP} + +echo "All done!" diff --git a/tools/osx/start b/tools/osx/start new file mode 100755 index 000000000..fe0024178 --- /dev/null +++ b/tools/osx/start @@ -0,0 +1,20 @@ +#!/bin/bash + +CWD=`dirname "$0"` +echo $CWD + +export DYLD_LIBRARY_PATH="${CWD}/lib:$DYLD_LIBRARY_PATH" +export GTK_DATA_PREFIX="${CWD}" +export GTK_DATA_DIRS="${CWD}" +export GTK_EXE_PREFIX="${CWD}" +export GTK_PATH="${CWD}" + +export GTK2_RC_FILES="${CWD}/etc/gtk-2.0/gtkrc" +export GTK_IM_MODULE_FILE="${CWD}/gtk-2.0/gtk.immodules" +export GDK_PIXBUF_MODULE_FILE="${CWD}/etc/gtk-2.0/gdk-pixbuf.loaders" +export PANGO_RC_FILE="${CWD}/etc/pango/pangorc" + +cp "${CWD}/etc/pango/pango.modules" /tmp/rt_pango.modules + +"${CWD}/rt" + diff --git a/tools/processing.png b/tools/processing.png new file mode 100644 index 000000000..33e8c4ed7 Binary files /dev/null and b/tools/processing.png differ diff --git a/tools/processingb.png b/tools/processingb.png new file mode 100644 index 000000000..d34293483 Binary files /dev/null and b/tools/processingb.png differ diff --git a/tools/processingw.png b/tools/processingw.png new file mode 100644 index 000000000..15954e3e9 Binary files /dev/null and b/tools/processingw.png differ diff --git a/tools/saved.png b/tools/saved.png new file mode 100644 index 000000000..556a93fb5 Binary files /dev/null and b/tools/saved.png differ diff --git a/tools/savedb.png b/tools/savedb.png new file mode 100644 index 000000000..1d5e809c0 Binary files /dev/null and b/tools/savedb.png differ diff --git a/tools/savedw.png b/tools/savedw.png new file mode 100644 index 000000000..1ec8c5d73 Binary files /dev/null and b/tools/savedw.png differ diff --git a/tools/tail.png b/tools/tail.png new file mode 100644 index 000000000..a40e93750 Binary files /dev/null and b/tools/tail.png differ diff --git a/tools/tailb.png b/tools/tailb.png new file mode 100644 index 000000000..e22ba7f14 Binary files /dev/null and b/tools/tailb.png differ diff --git a/tools/tailw.png b/tools/tailw.png new file mode 100644 index 000000000..cfadaf6b5 Binary files /dev/null and b/tools/tailw.png differ diff --git a/tools/trash.png b/tools/trash.png new file mode 100644 index 000000000..c185c78e4 Binary files /dev/null and b/tools/trash.png differ diff --git a/tools/trashb.png b/tools/trashb.png new file mode 100644 index 000000000..eb680934e Binary files /dev/null and b/tools/trashb.png differ diff --git a/tools/trashw.png b/tools/trashw.png new file mode 100644 index 000000000..c6393bd36 Binary files /dev/null and b/tools/trashw.png differ diff --git a/tools/undelete.png b/tools/undelete.png new file mode 100644 index 000000000..17f7c62f0 Binary files /dev/null and b/tools/undelete.png differ diff --git a/tools/undeleteb.png b/tools/undeleteb.png new file mode 100644 index 000000000..3119ed6f6 Binary files /dev/null and b/tools/undeleteb.png differ diff --git a/tools/undeletew.png b/tools/undeletew.png new file mode 100644 index 000000000..2bf13763d Binary files /dev/null and b/tools/undeletew.png differ diff --git a/tools/vertical.svg b/tools/vertical.svg new file mode 100644 index 000000000..c8bdaf573 --- /dev/null +++ b/tools/vertical.svg @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/winclude/cderror.h b/winclude/cderror.h new file mode 100755 index 000000000..70435e161 --- /dev/null +++ b/winclude/cderror.h @@ -0,0 +1,132 @@ +/* + * cderror.h + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the error and message codes for the cjpeg/djpeg + * applications. These strings are not needed as part of the JPEG library + * proper. + * Edit this file to add new codes, or to translate the message strings to + * some other language. + */ + +/* + * To define the enum list of message codes, include this file without + * defining macro JMESSAGE. To create a message string table, include it + * again with a suitable JMESSAGE definition (see jerror.c for an example). + */ +#ifndef JMESSAGE +#ifndef CDERROR_H +#define CDERROR_H +/* First time through, define the enum list */ +#define JMAKE_ENUM_LIST +#else +/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */ +#define JMESSAGE(code,string) +#endif /* CDERROR_H */ +#endif /* JMESSAGE */ + +#ifdef JMAKE_ENUM_LIST + +typedef enum { + +#define JMESSAGE(code,string) code , + +#endif /* JMAKE_ENUM_LIST */ + +JMESSAGE(JMSG_FIRSTADDONCODE=1000, NULL) /* Must be first entry! */ + +#ifdef BMP_SUPPORTED +JMESSAGE(JERR_BMP_BADCMAP, "Unsupported BMP colormap format") +JMESSAGE(JERR_BMP_BADDEPTH, "Only 8- and 24-bit BMP files are supported") +JMESSAGE(JERR_BMP_BADHEADER, "Invalid BMP file: bad header length") +JMESSAGE(JERR_BMP_BADPLANES, "Invalid BMP file: biPlanes not equal to 1") +JMESSAGE(JERR_BMP_COLORSPACE, "BMP output must be grayscale or RGB") +JMESSAGE(JERR_BMP_COMPRESSED, "Sorry, compressed BMPs not yet supported") +JMESSAGE(JERR_BMP_NOT, "Not a BMP file - does not start with BM") +JMESSAGE(JTRC_BMP, "%ux%u 24-bit BMP image") +JMESSAGE(JTRC_BMP_MAPPED, "%ux%u 8-bit colormapped BMP image") +JMESSAGE(JTRC_BMP_OS2, "%ux%u 24-bit OS2 BMP image") +JMESSAGE(JTRC_BMP_OS2_MAPPED, "%ux%u 8-bit colormapped OS2 BMP image") +#endif /* BMP_SUPPORTED */ + +#ifdef GIF_SUPPORTED +JMESSAGE(JERR_GIF_BUG, "GIF output got confused") +JMESSAGE(JERR_GIF_CODESIZE, "Bogus GIF codesize %d") +JMESSAGE(JERR_GIF_COLORSPACE, "GIF output must be grayscale or RGB") +JMESSAGE(JERR_GIF_IMAGENOTFOUND, "Too few images in GIF file") +JMESSAGE(JERR_GIF_NOT, "Not a GIF file") +JMESSAGE(JTRC_GIF, "%ux%ux%d GIF image") +JMESSAGE(JTRC_GIF_BADVERSION, + "Warning: unexpected GIF version number '%c%c%c'") +JMESSAGE(JTRC_GIF_EXTENSION, "Ignoring GIF extension block of type 0x%02x") +JMESSAGE(JTRC_GIF_NONSQUARE, "Caution: nonsquare pixels in input") +JMESSAGE(JWRN_GIF_BADDATA, "Corrupt data in GIF file") +JMESSAGE(JWRN_GIF_CHAR, "Bogus char 0x%02x in GIF file, ignoring") +JMESSAGE(JWRN_GIF_ENDCODE, "Premature end of GIF image") +JMESSAGE(JWRN_GIF_NOMOREDATA, "Ran out of GIF bits") +#endif /* GIF_SUPPORTED */ + +#ifdef PPM_SUPPORTED +JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB") +JMESSAGE(JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file") +JMESSAGE(JERR_PPM_NOT, "Not a PPM/PGM file") +JMESSAGE(JTRC_PGM, "%ux%u PGM image") +JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image") +JMESSAGE(JTRC_PPM, "%ux%u PPM image") +JMESSAGE(JTRC_PPM_TEXT, "%ux%u text PPM image") +#endif /* PPM_SUPPORTED */ + +#ifdef RLE_SUPPORTED +JMESSAGE(JERR_RLE_BADERROR, "Bogus error code from RLE library") +JMESSAGE(JERR_RLE_COLORSPACE, "RLE output must be grayscale or RGB") +JMESSAGE(JERR_RLE_DIMENSIONS, "Image dimensions (%ux%u) too large for RLE") +JMESSAGE(JERR_RLE_EMPTY, "Empty RLE file") +JMESSAGE(JERR_RLE_EOF, "Premature EOF in RLE header") +JMESSAGE(JERR_RLE_MEM, "Insufficient memory for RLE header") +JMESSAGE(JERR_RLE_NOT, "Not an RLE file") +JMESSAGE(JERR_RLE_TOOMANYCHANNELS, "Cannot handle %d output channels for RLE") +JMESSAGE(JERR_RLE_UNSUPPORTED, "Cannot handle this RLE setup") +JMESSAGE(JTRC_RLE, "%ux%u full-color RLE file") +JMESSAGE(JTRC_RLE_FULLMAP, "%ux%u full-color RLE file with map of length %d") +JMESSAGE(JTRC_RLE_GRAY, "%ux%u grayscale RLE file") +JMESSAGE(JTRC_RLE_MAPGRAY, "%ux%u grayscale RLE file with map of length %d") +JMESSAGE(JTRC_RLE_MAPPED, "%ux%u colormapped RLE file with map of length %d") +#endif /* RLE_SUPPORTED */ + +#ifdef TARGA_SUPPORTED +JMESSAGE(JERR_TGA_BADCMAP, "Unsupported Targa colormap format") +JMESSAGE(JERR_TGA_BADPARMS, "Invalid or unsupported Targa file") +JMESSAGE(JERR_TGA_COLORSPACE, "Targa output must be grayscale or RGB") +JMESSAGE(JTRC_TGA, "%ux%u RGB Targa image") +JMESSAGE(JTRC_TGA_GRAY, "%ux%u grayscale Targa image") +JMESSAGE(JTRC_TGA_MAPPED, "%ux%u colormapped Targa image") +#else +JMESSAGE(JERR_TGA_NOTCOMP, "Targa support was not compiled") +#endif /* TARGA_SUPPORTED */ + +JMESSAGE(JERR_BAD_CMAP_FILE, + "Color map file is invalid or of unsupported format") +JMESSAGE(JERR_TOO_MANY_COLORS, + "Output file format cannot handle %d colormap entries") +JMESSAGE(JERR_UNGETC_FAILED, "ungetc failed") +#ifdef TARGA_SUPPORTED +JMESSAGE(JERR_UNKNOWN_FORMAT, + "Unrecognized input file format --- perhaps you need -targa") +#else +JMESSAGE(JERR_UNKNOWN_FORMAT, "Unrecognized input file format") +#endif +JMESSAGE(JERR_UNSUPPORTED_FORMAT, "Unsupported output file format") + +#ifdef JMAKE_ENUM_LIST + + JMSG_LASTADDONCODE +} ADDON_MESSAGE_CODE; + +#undef JMAKE_ENUM_LIST +#endif /* JMAKE_ENUM_LIST */ + +/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */ +#undef JMESSAGE diff --git a/winclude/cdjpeg.h b/winclude/cdjpeg.h new file mode 100755 index 000000000..de83cfb1a --- /dev/null +++ b/winclude/cdjpeg.h @@ -0,0 +1,184 @@ +/* + * cdjpeg.h + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains common declarations for the sample applications + * cjpeg and djpeg. It is NOT used by the core JPEG library. + */ + +#define JPEG_CJPEG_DJPEG /* define proper options in jconfig.h */ +#define JPEG_INTERNAL_OPTIONS /* cjpeg.c,djpeg.c need to see xxx_SUPPORTED */ +#include "jinclude.h" +#include "jpeglib.h" +#include "jerror.h" /* get library error codes too */ +#include "cderror.h" /* get application-specific error codes */ + + +/* + * Object interface for cjpeg's source file decoding modules + */ + +typedef struct cjpeg_source_struct * cjpeg_source_ptr; + +struct cjpeg_source_struct { + JMETHOD(void, start_input, (j_compress_ptr cinfo, + cjpeg_source_ptr sinfo)); + JMETHOD(JDIMENSION, get_pixel_rows, (j_compress_ptr cinfo, + cjpeg_source_ptr sinfo)); + JMETHOD(void, finish_input, (j_compress_ptr cinfo, + cjpeg_source_ptr sinfo)); + + FILE *input_file; + + JSAMPARRAY buffer; + JDIMENSION buffer_height; +}; + + +/* + * Object interface for djpeg's output file encoding modules + */ + +typedef struct djpeg_dest_struct * djpeg_dest_ptr; + +struct djpeg_dest_struct { + /* start_output is called after jpeg_start_decompress finishes. + * The color map will be ready at this time, if one is needed. + */ + JMETHOD(void, start_output, (j_decompress_ptr cinfo, + djpeg_dest_ptr dinfo)); + /* Emit the specified number of pixel rows from the buffer. */ + JMETHOD(void, put_pixel_rows, (j_decompress_ptr cinfo, + djpeg_dest_ptr dinfo, + JDIMENSION rows_supplied)); + /* Finish up at the end of the image. */ + JMETHOD(void, finish_output, (j_decompress_ptr cinfo, + djpeg_dest_ptr dinfo)); + + /* Target file spec; filled in by djpeg.c after object is created. */ + FILE * output_file; + + /* Output pixel-row buffer. Created by module init or start_output. + * Width is cinfo->output_width * cinfo->output_components; + * height is buffer_height. + */ + JSAMPARRAY buffer; + JDIMENSION buffer_height; +}; + + +/* + * cjpeg/djpeg may need to perform extra passes to convert to or from + * the source/destination file format. The JPEG library does not know + * about these passes, but we'd like them to be counted by the progress + * monitor. We use an expanded progress monitor object to hold the + * additional pass count. + */ + +struct cdjpeg_progress_mgr { + struct jpeg_progress_mgr pub; /* fields known to JPEG library */ + int completed_extra_passes; /* extra passes completed */ + int total_extra_passes; /* total extra */ + /* last printed percentage stored here to avoid multiple printouts */ + int percent_done; +}; + +typedef struct cdjpeg_progress_mgr * cd_progress_ptr; + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jinit_read_bmp jIRdBMP +#define jinit_write_bmp jIWrBMP +#define jinit_read_gif jIRdGIF +#define jinit_write_gif jIWrGIF +#define jinit_read_ppm jIRdPPM +#define jinit_write_ppm jIWrPPM +#define jinit_read_rle jIRdRLE +#define jinit_write_rle jIWrRLE +#define jinit_read_targa jIRdTarga +#define jinit_write_targa jIWrTarga +#define read_quant_tables RdQTables +#define read_scan_script RdScnScript +#define set_quant_slots SetQSlots +#define set_sample_factors SetSFacts +#define read_color_map RdCMap +#define enable_signal_catcher EnSigCatcher +#define start_progress_monitor StProgMon +#define end_progress_monitor EnProgMon +#define read_stdin RdStdin +#define write_stdout WrStdout +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + +/* Module selection routines for I/O modules. */ + +EXTERN(cjpeg_source_ptr) jinit_read_bmp JPP((j_compress_ptr cinfo)); +EXTERN(djpeg_dest_ptr) jinit_write_bmp JPP((j_decompress_ptr cinfo, + jboolean is_os2)); +EXTERN(cjpeg_source_ptr) jinit_read_gif JPP((j_compress_ptr cinfo)); +EXTERN(djpeg_dest_ptr) jinit_write_gif JPP((j_decompress_ptr cinfo)); +EXTERN(cjpeg_source_ptr) jinit_read_ppm JPP((j_compress_ptr cinfo)); +EXTERN(djpeg_dest_ptr) jinit_write_ppm JPP((j_decompress_ptr cinfo)); +EXTERN(cjpeg_source_ptr) jinit_read_rle JPP((j_compress_ptr cinfo)); +EXTERN(djpeg_dest_ptr) jinit_write_rle JPP((j_decompress_ptr cinfo)); +EXTERN(cjpeg_source_ptr) jinit_read_targa JPP((j_compress_ptr cinfo)); +EXTERN(djpeg_dest_ptr) jinit_write_targa JPP((j_decompress_ptr cinfo)); + +/* cjpeg support routines (in rdswitch.c) */ + +EXTERN(jboolean) read_quant_tables JPP((j_compress_ptr cinfo, char * filename, + int scale_factor, jboolean force_baseline)); +EXTERN(jboolean) read_scan_script JPP((j_compress_ptr cinfo, char * filename)); +EXTERN(jboolean) set_quant_slots JPP((j_compress_ptr cinfo, char *arg)); +EXTERN(jboolean) set_sample_factors JPP((j_compress_ptr cinfo, char *arg)); + +/* djpeg support routines (in rdcolmap.c) */ + +EXTERN(void) read_color_map JPP((j_decompress_ptr cinfo, FILE * infile)); + +/* common support routines (in cdjpeg.c) */ + +EXTERN(void) enable_signal_catcher JPP((j_common_ptr cinfo)); +EXTERN(void) start_progress_monitor JPP((j_common_ptr cinfo, + cd_progress_ptr progress)); +EXTERN(void) end_progress_monitor JPP((j_common_ptr cinfo)); +EXTERN(jboolean) keymatch JPP((char * arg, const char * keyword, int minchars)); +EXTERN(FILE *) read_stdin JPP((void)); +EXTERN(FILE *) write_stdout JPP((void)); + +/* miscellaneous useful macros */ + +#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ +#define READ_BINARY "r" +#define WRITE_BINARY "w" +#else +#ifdef VMS /* VMS is very nonstandard */ +#define READ_BINARY "rb", "ctx=stm" +#define WRITE_BINARY "wb", "ctx=stm" +#else /* standard ANSI-compliant case */ +#define READ_BINARY "rb" +#define WRITE_BINARY "wb" +#endif +#endif + +#ifndef EXIT_FAILURE /* define exit() codes if not provided */ +#define EXIT_FAILURE 1 +#endif +#ifndef EXIT_SUCCESS +#ifdef VMS +#define EXIT_SUCCESS 1 /* VMS is very nonstandard */ +#else +#define EXIT_SUCCESS 0 +#endif +#endif +#ifndef EXIT_WARNING +#ifdef VMS +#define EXIT_WARNING 1 /* VMS is very nonstandard */ +#else +#define EXIT_WARNING 2 +#endif +#endif diff --git a/winclude/common.h b/winclude/common.h new file mode 100755 index 000000000..bd5545904 --- /dev/null +++ b/winclude/common.h @@ -0,0 +1,49 @@ +#ifndef _COMMON_ +#define _COMMON_ + +#define ISRED(image,row,col) \ + ((image->filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==0) +#define ISGREEN(image,row,col) \ + ((image->filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==1) +#define ISBLUE(image,row,col) \ + ((image->filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==2) + + +#define CMAXVAL 65535 + +#include + +struct RawImage { + + int width; + int height; + + unsigned filters; + + double red_multiplier; + double green_multiplier; + double blue_multiplier; + + double camwb_red; + double camwb_green; + double camwb_blue; + + int blackpoint; + int rgb_max; + int rotate_deg; + int fuji_width; + + struct tm* time; + float iso_speed, aperture, focal_len, shutter; + char *make, *model; + + int exifbase, exiflocation, exiforder; + + unsigned short** data; // holds pixel values, data[i][j] corresponds to the ith row and jth column + + float coeff[3][4]; + float icoeff[3][4]; + +}; + +#endif diff --git a/winclude/deflate.h b/winclude/deflate.h new file mode 100755 index 000000000..c5958df63 --- /dev/null +++ b/winclude/deflate.h @@ -0,0 +1,318 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2002 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef _DEFLATE_H +#define _DEFLATE_H + +#include "zutil.h" + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + int pending; /* nb of bytes in the pending buffer */ + int noheader; /* suppress zlib header and adler32 */ + Byte data_type; /* UNKNOWN, BINARY or ASCII */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + + /* in trees.c */ +void _tr_init OF((deflate_state *s)); +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +void _tr_align OF((deflate_state *s)); +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch _length_code[]; + extern uch _dist_code[]; +#else + extern const uch _length_code[]; + extern const uch _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif diff --git a/winclude/icc34.h b/winclude/icc34.h new file mode 100755 index 000000000..deca76d02 --- /dev/null +++ b/winclude/icc34.h @@ -0,0 +1,1027 @@ +/* Header file guard bands */ +#ifndef ICC_H +#define ICC_H + +#define PACKAGE_NAME 1 + + +/***************************************************************** + Copyright (c) 1994-1996 SunSoft, Inc. + + Rights Reserved + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without restrict- +ion, including without limitation the rights to use, copy, modify, +merge, publish distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON- +INFRINGEMENT. IN NO EVENT SHALL SUNSOFT, INC. OR ITS PARENT +COMPANY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of SunSoft, Inc. +shall not be used in advertising or otherwise to promote the +sale, use or other dealings in this Software without written +authorization from SunSoft Inc. +******************************************************************/ + +/* + * This version of the header file corresponds to the profile + * specification version 3.4. + * + * All header file entries are pre-fixed with "ic" to help + * avoid name space collisions. Signatures are pre-fixed with + * icSig. + * + * The structures defined in this header file were created to + * represent a description of an ICC profile on disk. Rather + * than use pointers a technique is used where a single byte array + * was placed at the end of each structure. This allows us in "C" + * to extend the structure by allocating more data than is needed + * to account for variable length structures. + * + * This also ensures that data following is allocated + * contiguously and makes it easier to write and read data from + * the file. + * + * For example to allocate space for a 256 count length UCR + * and BG array, and fill the allocated data. Note strlen + 1 + * to remember NULL terminator. + * + icUcrBgCurve *ucrCurve, *bgCurve; + int ucr_nbytes, bg_nbytes, string_bytes; + icUcrBg *ucrBgWrite; + char ucr_string[100], *ucr_char; + + strcpy(ucr_string, "Example ucrBG curves"); + ucr_nbytes = sizeof(icUInt32Number) + + (UCR_CURVE_SIZE * sizeof(icUInt16Number)); + bg_nbytes = sizeof(icUInt32Number) + + (BG_CURVE_SIZE * sizeof(icUInt16Number)); + string_bytes = strlen(ucr_string) + 1; + + ucrBgWrite = (icUcrBg *)malloc( + (ucr_nbytes + bg_nbytes + string_bytes)); + + ucrCurve = (icUcrBgCurve *)ucrBgWrite->data; + ucrCurve->count = UCR_CURVE_SIZE; + for (i=0; icount; i++) + ucrCurve->curve[i] = (icUInt16Number)i; + + bgCurve = (icUcrBgCurve *)((char *)ucrCurve + ucr_nbytes); + bgCurve->count = BG_CURVE_SIZE; + for (i=0; icount; i++) + bgCurve->curve[i] = 255 - (icUInt16Number)i; + + ucr_char = (char *)((char *)bgCurve + bg_nbytes); + memcpy(ucr_char, ucr_string, string_bytes); + * + */ + +/* + * Many of the structures contain variable length arrays. This + * is represented by the use of the convention. + * + * type data[icAny]; + */ + +/*------------------------------------------------------------------------*/ +/* + * Defines used in the specification + */ +#define icMagicNumber 0x61637370L /* 'acsp' */ +#define icVersionNumber 0x02100000L /* 2.1.0, BCD */ + +/* Screening Encodings */ +#define icPrtrDefaultScreensFalse 0x00000000L /* Bit pos 0 */ +#define icPrtrDefaultScreensTrue 0x00000001L /* Bit pos 0 */ +#define icLinesPerInch 0x00000002L /* Bit pos 1 */ +#define icLinesPerCm 0x00000000L /* Bit pos 1 */ + +/* + * Device attributes, currently defined values correspond + * to the low 4 bytes of the 8 byte attribute quantity, see + * the header for their location. + */ +#define icReflective 0x00000000L /* Bit pos 0 */ +#define icTransparency 0x00000001L /* Bit pos 0 */ +#define icGlossy 0x00000000L /* Bit pos 1 */ +#define icMatte 0x00000002L /* Bit pos 1 */ + +/* + * Profile header flags, the low 16 bits are reserved for consortium + * use. + */ +#define icEmbeddedProfileFalse 0x00000000L /* Bit pos 0 */ +#define icEmbeddedProfileTrue 0x00000001L /* Bit pos 0 */ +#define icUseAnywhere 0x00000000L /* Bit pos 1 */ +#define icUseWithEmbeddedDataOnly 0x00000002L /* Bit pos 1 */ + +/* Ascii or Binary data */ +#define icAsciiData 0x00000000L +#define icBinaryData 0x00000001L + +/* + * Define used to indicate that this is a variable length array + */ +#define icAny 1 + + +/*------------------------------------------------------------------------*/ +/* + * Use this area to translate platform definitions of long + * etc into icXXX form. The rest of the header uses the icXXX + * typedefs. Signatures are 4 byte quantities. + * + */ + + +#ifdef PACKAGE_NAME +/* + June 9, 2003, Adapted for use with configure by Bob Friesenhahn + Added the stupid check for autoconf by Marti Maria. + PACKAGE_NAME is defined if autoconf is being used +*/ + +typedef unsigned char icUInt8Number; +typedef unsigned short icUInt16Number; +typedef unsigned int icUInt32Number; +typedef unsigned int icUInt64Number[2]; + +typedef char icInt8Number; +typedef short icInt16Number; +typedef int icInt32Number; +typedef int icInt64Number[2]; + +#else + +/* + *Apr-17-2002: Modified by Marti Maria in order to provide wider portability. + */ + +#if defined (__digital__) && defined (__unix__) + +/* Tru64 */ + +#include + +typedef uint8_t icUInt8Number; +typedef uint16_t icUInt16Number; +typedef uint32_t icUInt32Number; +typedef uint32_t icUInt64Number[2]; + +typedef int8_t icInt8Number; +typedef int16_t icInt16Number; +typedef int32_t icInt32Number; +typedef int32_t icInt64Number[2]; + +#else +#ifdef __sgi +#include "sgidefs.h" + + +/* + * Number definitions + */ + +/* Unsigned integer numbers */ +typedef unsigned char icUInt8Number; +typedef unsigned short icUInt16Number; +typedef __uint32_t icUInt32Number; +typedef __uint32_t icUInt64Number[2]; + +/* Signed numbers */ +typedef char icInt8Number; +typedef short icInt16Number; +typedef __int32_t icInt32Number; +typedef __int32_t icInt64Number[2]; + + +#else +#if defined(__GNUC__) || defined(__unix__) || defined(__unix) + +#include + +#if defined(__sun) || defined(__hpux) || defined (__MINGW) || defined(__MINGW32__) + +typedef uint8_t icUInt8Number; +typedef uint16_t icUInt16Number; +typedef uint32_t icUInt32Number; +typedef uint32_t icUInt64Number[2]; + +#else + +/* Unsigned integer numbers */ +typedef u_int8_t icUInt8Number; +typedef u_int16_t icUInt16Number; +typedef u_int32_t icUInt32Number; +typedef u_int32_t icUInt64Number[2]; + +#endif + + +/* Signed numbers */ +typedef int8_t icInt8Number; +typedef int16_t icInt16Number; +typedef int32_t icInt32Number; +typedef int32_t icInt64Number[2]; + + +#else /* default definitions */ + +/* + * Number definitions + */ + +/* Unsigned integer numbers */ +typedef unsigned char icUInt8Number; +typedef unsigned short icUInt16Number; +typedef unsigned long icUInt32Number; +typedef unsigned long icUInt64Number[2]; + +/* Signed numbers */ +typedef char icInt8Number; +typedef short icInt16Number; +typedef long icInt32Number; +typedef long icInt64Number[2]; + + +#endif /* default defs */ +#endif +#endif +#endif + +/* Base types */ + +typedef icInt32Number icSignature; +typedef icInt32Number icS15Fixed16Number; +typedef icUInt32Number icU16Fixed16Number; + + +/*------------------------------------------------------------------------*/ +/* public tags and sizes */ +typedef enum { + icSigAToB0Tag = 0x41324230L, /* 'A2B0' */ + icSigAToB1Tag = 0x41324231L, /* 'A2B1' */ + icSigAToB2Tag = 0x41324232L, /* 'A2B2' */ + icSigBlueColorantTag = 0x6258595AL, /* 'bXYZ' */ + icSigBlueTRCTag = 0x62545243L, /* 'bTRC' */ + icSigBToA0Tag = 0x42324130L, /* 'B2A0' */ + icSigBToA1Tag = 0x42324131L, /* 'B2A1' */ + icSigBToA2Tag = 0x42324132L, /* 'B2A2' */ + icSigCalibrationDateTimeTag = 0x63616C74L, /* 'calt' */ + icSigCharTargetTag = 0x74617267L, /* 'targ' */ + icSigCopyrightTag = 0x63707274L, /* 'cprt' */ + icSigCrdInfoTag = 0x63726469L, /* 'crdi' */ + icSigDeviceMfgDescTag = 0x646D6E64L, /* 'dmnd' */ + icSigDeviceModelDescTag = 0x646D6464L, /* 'dmdd' */ + icSigGamutTag = 0x67616D74L, /* 'gamt ' */ + icSigGrayTRCTag = 0x6b545243L, /* 'kTRC' */ + icSigGreenColorantTag = 0x6758595AL, /* 'gXYZ' */ + icSigGreenTRCTag = 0x67545243L, /* 'gTRC' */ + icSigLuminanceTag = 0x6C756d69L, /* 'lumi' */ + icSigMeasurementTag = 0x6D656173L, /* 'meas' */ + icSigMediaBlackPointTag = 0x626B7074L, /* 'bkpt' */ + icSigMediaWhitePointTag = 0x77747074L, /* 'wtpt' */ + icSigNamedColorTag = 0x6E636f6CL, /* 'ncol' + * OBSOLETE, use ncl2 */ + icSigNamedColor2Tag = 0x6E636C32L, /* 'ncl2' */ + icSigPreview0Tag = 0x70726530L, /* 'pre0' */ + icSigPreview1Tag = 0x70726531L, /* 'pre1' */ + icSigPreview2Tag = 0x70726532L, /* 'pre2' */ + icSigProfileDescriptionTag = 0x64657363L, /* 'desc' */ + icSigProfileSequenceDescTag = 0x70736571L, /* 'pseq' */ + icSigPs2CRD0Tag = 0x70736430L, /* 'psd0' */ + icSigPs2CRD1Tag = 0x70736431L, /* 'psd1' */ + icSigPs2CRD2Tag = 0x70736432L, /* 'psd2' */ + icSigPs2CRD3Tag = 0x70736433L, /* 'psd3' */ + icSigPs2CSATag = 0x70733273L, /* 'ps2s' */ + icSigPs2RenderingIntentTag = 0x70733269L, /* 'ps2i' */ + icSigRedColorantTag = 0x7258595AL, /* 'rXYZ' */ + icSigRedTRCTag = 0x72545243L, /* 'rTRC' */ + icSigScreeningDescTag = 0x73637264L, /* 'scrd' */ + icSigScreeningTag = 0x7363726EL, /* 'scrn' */ + icSigTechnologyTag = 0x74656368L, /* 'tech' */ + icSigUcrBgTag = 0x62666420L, /* 'bfd ' */ + icSigViewingCondDescTag = 0x76756564L, /* 'vued' */ + icSigViewingConditionsTag = 0x76696577L, /* 'view' */ + icMaxEnumTag = 0xFFFFFFFFL +} icTagSignature; + +/* technology signature descriptions */ +typedef enum { + icSigDigitalCamera = 0x6463616DL, /* 'dcam' */ + icSigFilmScanner = 0x6673636EL, /* 'fscn' */ + icSigReflectiveScanner = 0x7273636EL, /* 'rscn' */ + icSigInkJetPrinter = 0x696A6574L, /* 'ijet' */ + icSigThermalWaxPrinter = 0x74776178L, /* 'twax' */ + icSigElectrophotographicPrinter = 0x6570686FL, /* 'epho' */ + icSigElectrostaticPrinter = 0x65737461L, /* 'esta' */ + icSigDyeSublimationPrinter = 0x64737562L, /* 'dsub' */ + icSigPhotographicPaperPrinter = 0x7270686FL, /* 'rpho' */ + icSigFilmWriter = 0x6670726EL, /* 'fprn' */ + icSigVideoMonitor = 0x7669646DL, /* 'vidm' */ + icSigVideoCamera = 0x76696463L, /* 'vidc' */ + icSigProjectionTelevision = 0x706A7476L, /* 'pjtv' */ + icSigCRTDisplay = 0x43525420L, /* 'CRT ' */ + icSigPMDisplay = 0x504D4420L, /* 'PMD ' */ + icSigAMDisplay = 0x414D4420L, /* 'AMD ' */ + icSigPhotoCD = 0x4B504344L, /* 'KPCD' */ + icSigPhotoImageSetter = 0x696D6773L, /* 'imgs' */ + icSigGravure = 0x67726176L, /* 'grav' */ + icSigOffsetLithography = 0x6F666673L, /* 'offs' */ + icSigSilkscreen = 0x73696C6BL, /* 'silk' */ + icSigFlexography = 0x666C6578L, /* 'flex' */ + icMaxEnumTechnology = 0xFFFFFFFFL +} icTechnologySignature; + +/* type signatures */ +typedef enum { + icSigCurveType = 0x63757276L, /* 'curv' */ + icSigDataType = 0x64617461L, /* 'data' */ + icSigDateTimeType = 0x6474696DL, /* 'dtim' */ + icSigLut16Type = 0x6d667432L, /* 'mft2' */ + icSigLut8Type = 0x6d667431L, /* 'mft1' */ + icSigMeasurementType = 0x6D656173L, /* 'meas' */ + icSigNamedColorType = 0x6E636f6CL, /* 'ncol' + * OBSOLETE, use ncl2 */ + icSigProfileSequenceDescType = 0x70736571L, /* 'pseq' */ + icSigS15Fixed16ArrayType = 0x73663332L, /* 'sf32' */ + icSigScreeningType = 0x7363726EL, /* 'scrn' */ + icSigSignatureType = 0x73696720L, /* 'sig ' */ + icSigTextType = 0x74657874L, /* 'text' */ + icSigTextDescriptionType = 0x64657363L, /* 'desc' */ + icSigU16Fixed16ArrayType = 0x75663332L, /* 'uf32' */ + icSigUcrBgType = 0x62666420L, /* 'bfd ' */ + icSigUInt16ArrayType = 0x75693136L, /* 'ui16' */ + icSigUInt32ArrayType = 0x75693332L, /* 'ui32' */ + icSigUInt64ArrayType = 0x75693634L, /* 'ui64' */ + icSigUInt8ArrayType = 0x75693038L, /* 'ui08' */ + icSigViewingConditionsType = 0x76696577L, /* 'view' */ + icSigXYZType = 0x58595A20L, /* 'XYZ ' */ + icSigXYZArrayType = 0x58595A20L, /* 'XYZ ' */ + icSigNamedColor2Type = 0x6E636C32L, /* 'ncl2' */ + icSigCrdInfoType = 0x63726469L, /* 'crdi' */ + icMaxEnumType = 0xFFFFFFFFL +} icTagTypeSignature; + +/* + * Color Space Signatures + * Note that only icSigXYZData and icSigLabData are valid + * Profile Connection Spaces (PCSs) + */ +typedef enum { + icSigXYZData = 0x58595A20L, /* 'XYZ ' */ + icSigLabData = 0x4C616220L, /* 'Lab ' */ + icSigLuvData = 0x4C757620L, /* 'Luv ' */ + icSigYCbCrData = 0x59436272L, /* 'YCbr' */ + icSigYxyData = 0x59787920L, /* 'Yxy ' */ + icSigRgbData = 0x52474220L, /* 'RGB ' */ + icSigGrayData = 0x47524159L, /* 'GRAY' */ + icSigHsvData = 0x48535620L, /* 'HSV ' */ + icSigHlsData = 0x484C5320L, /* 'HLS ' */ + icSigCmykData = 0x434D594BL, /* 'CMYK' */ + icSigCmyData = 0x434D5920L, /* 'CMY ' */ + icSig2colorData = 0x32434C52L, /* '2CLR' */ + icSig3colorData = 0x33434C52L, /* '3CLR' */ + icSig4colorData = 0x34434C52L, /* '4CLR' */ + icSig5colorData = 0x35434C52L, /* '5CLR' */ + icSig6colorData = 0x36434C52L, /* '6CLR' */ + icSig7colorData = 0x37434C52L, /* '7CLR' */ + icSig8colorData = 0x38434C52L, /* '8CLR' */ + icSig9colorData = 0x39434C52L, /* '9CLR' */ + icSig10colorData = 0x41434C52L, /* 'ACLR' */ + icSig11colorData = 0x42434C52L, /* 'BCLR' */ + icSig12colorData = 0x43434C52L, /* 'CCLR' */ + icSig13colorData = 0x44434C52L, /* 'DCLR' */ + icSig14colorData = 0x45434C52L, /* 'ECLR' */ + icSig15colorData = 0x46434C52L, /* 'FCLR' */ + icMaxEnumData = 0xFFFFFFFFL +} icColorSpaceSignature; + +/* profileClass enumerations */ +typedef enum { + icSigInputClass = 0x73636E72L, /* 'scnr' */ + icSigDisplayClass = 0x6D6E7472L, /* 'mntr' */ + icSigOutputClass = 0x70727472L, /* 'prtr' */ + icSigLinkClass = 0x6C696E6BL, /* 'link' */ + icSigAbstractClass = 0x61627374L, /* 'abst' */ + icSigColorSpaceClass = 0x73706163L, /* 'spac' */ + icSigNamedColorClass = 0x6e6d636cL, /* 'nmcl' */ + icMaxEnumClass = 0xFFFFFFFFL +} icProfileClassSignature; + +/* Platform Signatures */ +typedef enum { + icSigMacintosh = 0x4150504CL, /* 'APPL' */ + icSigMicrosoft = 0x4D534654L, /* 'MSFT' */ + icSigSolaris = 0x53554E57L, /* 'SUNW' */ + icSigSGI = 0x53474920L, /* 'SGI ' */ + icSigTaligent = 0x54474E54L, /* 'TGNT' */ + icMaxEnumPlatform = 0xFFFFFFFFL +} icPlatformSignature; + +/*------------------------------------------------------------------------*/ +/* + * Other enums + */ + +/* Measurement Flare, used in the measurmentType tag */ +typedef enum { + icFlare0 = 0x00000000L, /* 0% flare */ + icFlare100 = 0x00000001L, /* 100% flare */ + icMaxFlare = 0xFFFFFFFFL +} icMeasurementFlare; + +/* Measurement Geometry, used in the measurmentType tag */ +typedef enum { + icGeometryUnknown = 0x00000000L, /* Unknown */ + icGeometry045or450 = 0x00000001L, /* 0/45, 45/0 */ + icGeometry0dord0 = 0x00000002L, /* 0/d or d/0 */ + icMaxGeometry = 0xFFFFFFFFL +} icMeasurementGeometry; + +/* Rendering Intents, used in the profile header */ +typedef enum { + icPerceptual = 0, + icRelativeColorimetric = 1, + icSaturation = 2, + icAbsoluteColorimetric = 3, + icMaxEnumIntent = 0xFFFFFFFFL +} icRenderingIntent; + +/* Different Spot Shapes currently defined, used for screeningType */ +typedef enum { + icSpotShapeUnknown = 0, + icSpotShapePrinterDefault = 1, + icSpotShapeRound = 2, + icSpotShapeDiamond = 3, + icSpotShapeEllipse = 4, + icSpotShapeLine = 5, + icSpotShapeSquare = 6, + icSpotShapeCross = 7, + icMaxEnumSpot = 0xFFFFFFFFL +} icSpotShape; + +/* Standard Observer, used in the measurmentType tag */ +typedef enum { + icStdObsUnknown = 0x00000000L, /* Unknown */ + icStdObs1931TwoDegrees = 0x00000001L, /* 2 deg */ + icStdObs1964TenDegrees = 0x00000002L, /* 10 deg */ + icMaxStdObs = 0xFFFFFFFFL +} icStandardObserver; + +/* Pre-defined illuminants, used in measurement and viewing conditions type */ +typedef enum { + icIlluminantUnknown = 0x00000000L, + icIlluminantD50 = 0x00000001L, + icIlluminantD65 = 0x00000002L, + icIlluminantD93 = 0x00000003L, + icIlluminantF2 = 0x00000004L, + icIlluminantD55 = 0x00000005L, + icIlluminantA = 0x00000006L, + icIlluminantEquiPowerE = 0x00000007L, + icIlluminantF8 = 0x00000008L, + icMaxEnumIluminant = 0xFFFFFFFFL +} icIlluminant; + + +/*------------------------------------------------------------------------*/ +/* + * Arrays of numbers + */ + +/* Int8 Array */ +typedef struct { + icInt8Number data[icAny]; /* Variable array of values */ +} icInt8Array; + +/* UInt8 Array */ +typedef struct { + icUInt8Number data[icAny]; /* Variable array of values */ +} icUInt8Array; + +/* uInt16 Array */ +typedef struct { + icUInt16Number data[icAny]; /* Variable array of values */ +} icUInt16Array; + +/* Int16 Array */ +typedef struct { + icInt16Number data[icAny]; /* Variable array of values */ +} icInt16Array; + +/* uInt32 Array */ +typedef struct { + icUInt32Number data[icAny]; /* Variable array of values */ +} icUInt32Array; + +/* Int32 Array */ +typedef struct { + icInt32Number data[icAny]; /* Variable array of values */ +} icInt32Array; + +/* UInt64 Array */ +typedef struct { + icUInt64Number data[icAny]; /* Variable array of values */ +} icUInt64Array; + +/* Int64 Array */ +typedef struct { + icInt64Number data[icAny]; /* Variable array of values */ +} icInt64Array; + +/* u16Fixed16 Array */ +typedef struct { + icU16Fixed16Number data[icAny]; /* Variable array of values */ +} icU16Fixed16Array; + +/* s15Fixed16 Array */ +typedef struct { + icS15Fixed16Number data[icAny]; /* Variable array of values */ +} icS15Fixed16Array; + +/* The base date time number */ +typedef struct { + icUInt16Number year; + icUInt16Number month; + icUInt16Number day; + icUInt16Number hours; + icUInt16Number minutes; + icUInt16Number seconds; +} icDateTimeNumber; + +/* XYZ Number */ +typedef struct { + icS15Fixed16Number X; + icS15Fixed16Number Y; + icS15Fixed16Number Z; +} icXYZNumber; + +/* XYZ Array */ +typedef struct { + icXYZNumber data[icAny]; /* Variable array of XYZ numbers */ +} icXYZArray; + +/* Curve */ +typedef struct { + icUInt32Number count; /* Number of entries */ + icUInt16Number data[icAny]; /* The actual table data, real + * number is determined by count + * Interpretation depends on how + * data is used with a given tag + */ +} icCurve; + +/* Data */ +typedef struct { + icUInt32Number dataFlag; /* 0 = ascii, 1 = binary */ + icInt8Number data[icAny]; /* Data, size from tag */ +} icData; + +/* lut16 */ +typedef struct { + icUInt8Number inputChan; /* Number of input channels */ + icUInt8Number outputChan; /* Number of output channels */ + icUInt8Number clutPoints; /* Number of grid points */ + icInt8Number pad; /* Padding for byte alignment */ + icS15Fixed16Number e00; /* e00 in the 3 * 3 */ + icS15Fixed16Number e01; /* e01 in the 3 * 3 */ + icS15Fixed16Number e02; /* e02 in the 3 * 3 */ + icS15Fixed16Number e10; /* e10 in the 3 * 3 */ + icS15Fixed16Number e11; /* e11 in the 3 * 3 */ + icS15Fixed16Number e12; /* e12 in the 3 * 3 */ + icS15Fixed16Number e20; /* e20 in the 3 * 3 */ + icS15Fixed16Number e21; /* e21 in the 3 * 3 */ + icS15Fixed16Number e22; /* e22 in the 3 * 3 */ + icUInt16Number inputEnt; /* Num of in-table entries */ + icUInt16Number outputEnt; /* Num of out-table entries */ + icUInt16Number data[icAny]; /* Data follows see spec */ +/* + * Data that follows is of this form + * + * icUInt16Number inputTable[inputChan][icAny]; * The in-table + * icUInt16Number clutTable[icAny]; * The clut + * icUInt16Number outputTable[outputChan][icAny]; * The out-table + */ +} icLut16; + +/* lut8, input & output tables are always 256 bytes in length */ +typedef struct { + icUInt8Number inputChan; /* Num of input channels */ + icUInt8Number outputChan; /* Num of output channels */ + icUInt8Number clutPoints; /* Num of grid points */ + icInt8Number pad; + icS15Fixed16Number e00; /* e00 in the 3 * 3 */ + icS15Fixed16Number e01; /* e01 in the 3 * 3 */ + icS15Fixed16Number e02; /* e02 in the 3 * 3 */ + icS15Fixed16Number e10; /* e10 in the 3 * 3 */ + icS15Fixed16Number e11; /* e11 in the 3 * 3 */ + icS15Fixed16Number e12; /* e12 in the 3 * 3 */ + icS15Fixed16Number e20; /* e20 in the 3 * 3 */ + icS15Fixed16Number e21; /* e21 in the 3 * 3 */ + icS15Fixed16Number e22; /* e22 in the 3 * 3 */ + icUInt8Number data[icAny]; /* Data follows see spec */ +/* + * Data that follows is of this form + * + * icUInt8Number inputTable[inputChan][256]; * The in-table + * icUInt8Number clutTable[icAny]; * The clut + * icUInt8Number outputTable[outputChan][256]; * The out-table + */ +} icLut8; + +/* Measurement Data */ +typedef struct { + icStandardObserver stdObserver; /* Standard observer */ + icXYZNumber backing; /* XYZ for backing */ + icMeasurementGeometry geometry; /* Meas. geometry */ + icMeasurementFlare flare; /* Measurement flare */ + icIlluminant illuminant; /* Illuminant */ +} icMeasurement; + +/* Named color */ + +/* + * icNamedColor2 takes the place of icNamedColor + */ +typedef struct { + icUInt32Number vendorFlag; /* Bottom 16 bits for IC use */ + icUInt32Number count; /* Count of named colors */ + icUInt32Number nDeviceCoords; /* Num of device coordinates */ + icInt8Number prefix[32]; /* Prefix for each color name */ + icInt8Number suffix[32]; /* Suffix for each color name */ + icInt8Number data[icAny]; /* Named color data follows */ +/* + * Data that follows is of this form + * + * icInt8Number root1[32]; * Root name for 1st color + * icUInt16Number pcsCoords1[icAny]; * PCS coords of 1st color + * icUInt16Number deviceCoords1[icAny]; * Dev coords of 1st color + * icInt8Number root2[32]; * Root name for 2nd color + * icUInt16Number pcsCoords2[icAny]; * PCS coords of 2nd color + * icUInt16Number deviceCoords2[icAny]; * Dev coords of 2nd color + * : + * : + * Repeat for name and PCS and device color coordinates up to (count-1) + * + * NOTES: + * PCS and device space can be determined from the header. + * + * PCS coordinates are icUInt16 numbers and are described in Annex A of + * the ICC spec. Only 16 bit L*a*b* and XYZ are allowed. The number of + * coordinates is consistent with the headers PCS. + * + * Device coordinates are icUInt16 numbers where 0x0000 represents + * the minimum value and 0xFFFF represents the maximum value. + * If the nDeviceCoords value is 0 this field is not given. + */ +} icNamedColor2; + +/* Profile sequence structure */ +typedef struct { + icSignature deviceMfg; /* Dev Manufacturer */ + icSignature deviceModel; /* Dev Model */ + icUInt64Number attributes; /* Dev attributes */ + icTechnologySignature technology; /* Technology sig */ + icInt8Number data[icAny]; /* Desc text follows */ +/* + * Data that follows is of this form, this is an icInt8Number + * to avoid problems with a compiler generating bad code as + * these arrays are variable in length. + * + * icTextDescription deviceMfgDesc; * Manufacturer text + * icTextDescription modelDesc; * Model text + */ +} icDescStruct; + +/* Profile sequence description */ +typedef struct { + icUInt32Number count; /* Number of descriptions */ + icUInt8Number data[icAny]; /* Array of desc structs */ +} icProfileSequenceDesc; + +/* textDescription */ +typedef struct { + icUInt32Number count; /* Description length */ + icInt8Number data[icAny]; /* Descriptions follow */ +/* + * Data that follows is of this form + * + * icInt8Number desc[count] * NULL terminated ascii string + * icUInt32Number ucLangCode; * UniCode language code + * icUInt32Number ucCount; * UniCode description length + * icInt16Number ucDesc[ucCount];* The UniCode description + * icUInt16Number scCode; * ScriptCode code + * icUInt8Number scCount; * ScriptCode count + * icInt8Number scDesc[67]; * ScriptCode Description + */ +} icTextDescription; + +/* Screening Data */ +typedef struct { + icS15Fixed16Number frequency; /* Frequency */ + icS15Fixed16Number angle; /* Screen angle */ + icSpotShape spotShape; /* Spot Shape encodings below */ +} icScreeningData; + +typedef struct { + icUInt32Number screeningFlag; /* Screening flag */ + icUInt32Number channels; /* Number of channels */ + icScreeningData data[icAny]; /* Array of screening data */ +} icScreening; + +/* Text Data */ +typedef struct { + icInt8Number data[icAny]; /* Variable array of chars */ +} icText; + +/* Structure describing either a UCR or BG curve */ +typedef struct { + icUInt32Number count; /* Curve length */ + icUInt16Number curve[icAny]; /* The array of curve values */ +} icUcrBgCurve; + +/* Under color removal, black generation */ +typedef struct { + icInt8Number data[icAny]; /* The Ucr BG data */ +/* + * Data that follows is of this form, this is a icInt8Number + * to avoid problems with a compiler generating bad code as + * these arrays are variable in length. + * + * icUcrBgCurve ucr; * Ucr curve + * icUcrBgCurve bg; * Bg curve + * icInt8Number string; * UcrBg description + */ +} icUcrBg; + +/* viewingConditionsType */ +typedef struct { + icXYZNumber illuminant; /* In candelas per sq. meter */ + icXYZNumber surround; /* In candelas per sq. meter */ + icIlluminant stdIluminant; /* See icIlluminant defines */ +} icViewingCondition; + +/* CrdInfo type */ +typedef struct { + icUInt32Number count; /* Char count includes NULL */ + icInt8Number desc[icAny]; /* Null terminated string */ +} icCrdInfo; + +/*------------------------------------------------------------------------*/ +/* + * Tag Type definitions + */ + +/* + * Many of the structures contain variable length arrays. This + * is represented by the use of the convention. + * + * type data[icAny]; + */ + +/* The base part of each tag */ +typedef struct { + icTagTypeSignature sig; /* Signature */ + icInt8Number reserved[4]; /* Reserved, set to 0 */ +} icTagBase; + +/* curveType */ +typedef struct { + icTagBase base; /* Signature, "curv" */ + icCurve curve; /* The curve data */ +} icCurveType; + +/* dataType */ +typedef struct { + icTagBase base; /* Signature, "data" */ + icData data; /* The data structure */ +} icDataType; + +/* dateTimeType */ +typedef struct { + icTagBase base; /* Signature, "dtim" */ + icDateTimeNumber date; /* The date */ +} icDateTimeType; + +/* lut16Type */ +typedef struct { + icTagBase base; /* Signature, "mft2" */ + icLut16 lut; /* Lut16 data */ +} icLut16Type; + +/* lut8Type, input & output tables are always 256 bytes in length */ +typedef struct { + icTagBase base; /* Signature, "mft1" */ + icLut8 lut; /* Lut8 data */ +} icLut8Type; + +/* Measurement Type */ +typedef struct { + icTagBase base; /* Signature, "meas" */ + icMeasurement measurement; /* Measurement data */ +} icMeasurementType; + +/* Named color type */ +/* icNamedColor2Type, replaces icNamedColorType */ +typedef struct { + icTagBase base; /* Signature, "ncl2" */ + icNamedColor2 ncolor; /* Named color data */ +} icNamedColor2Type; + +/* Profile sequence description type */ +typedef struct { + icTagBase base; /* Signature, "pseq" */ + icProfileSequenceDesc desc; /* The seq description */ +} icProfileSequenceDescType; + +/* textDescriptionType */ +typedef struct { + icTagBase base; /* Signature, "desc" */ + icTextDescription desc; /* The description */ +} icTextDescriptionType; + +/* s15Fixed16Type */ +typedef struct { + icTagBase base; /* Signature, "sf32" */ + icS15Fixed16Array data; /* Array of values */ +} icS15Fixed16ArrayType; + +typedef struct { + icTagBase base; /* Signature, "scrn" */ + icScreening screen; /* Screening structure */ +} icScreeningType; + +/* sigType */ +typedef struct { + icTagBase base; /* Signature, "sig" */ + icSignature signature; /* The signature data */ +} icSignatureType; + +/* textType */ +typedef struct { + icTagBase base; /* Signature, "text" */ + icText data; /* Variable array of chars */ +} icTextType; + +/* u16Fixed16Type */ +typedef struct { + icTagBase base; /* Signature, "uf32" */ + icU16Fixed16Array data; /* Variable array of values */ +} icU16Fixed16ArrayType; + +/* Under color removal, black generation type */ +typedef struct { + icTagBase base; /* Signature, "bfd " */ + icUcrBg data; /* ucrBg structure */ +} icUcrBgType; + +/* uInt16Type */ +typedef struct { + icTagBase base; /* Signature, "ui16" */ + icUInt16Array data; /* Variable array of values */ +} icUInt16ArrayType; + +/* uInt32Type */ +typedef struct { + icTagBase base; /* Signature, "ui32" */ + icUInt32Array data; /* Variable array of values */ +} icUInt32ArrayType; + +/* uInt64Type */ +typedef struct { + icTagBase base; /* Signature, "ui64" */ + icUInt64Array data; /* Variable array of values */ +} icUInt64ArrayType; + +/* uInt8Type */ +typedef struct { + icTagBase base; /* Signature, "ui08" */ + icUInt8Array data; /* Variable array of values */ +} icUInt8ArrayType; + +/* viewingConditionsType */ +typedef struct { + icTagBase base; /* Signature, "view" */ + icViewingCondition view; /* Viewing conditions */ +} icViewingConditionType; + +/* XYZ Type */ +typedef struct { + icTagBase base; /* Signature, "XYZ" */ + icXYZArray data; /* Variable array of XYZ nums */ +} icXYZType; + +/* CRDInfoType where [0] is the CRD product name count and string and + * [1] -[5] are the rendering intents 0-4 counts and strings + */ +typedef struct { + icTagBase base; /* Signature, "crdi" */ + icCrdInfo info; /* 5 sets of counts & strings */ +}icCrdInfoType; + /* icCrdInfo productName; PS product count/string */ + /* icCrdInfo CRDName0; CRD name for intent 0 */ + /* icCrdInfo CRDName1; CRD name for intent 1 */ + /* icCrdInfo CRDName2; CRD name for intent 2 */ + /* icCrdInfo CRDName3; CRD name for intent 3 */ + +/*------------------------------------------------------------------------*/ + +/* + * Lists of tags, tags, profile header and profile structure + */ + +/* A tag */ +typedef struct { + icTagSignature sig; /* The tag signature */ + icUInt32Number offset; /* Start of tag relative to + * start of header, Spec + * Clause 5 */ + icUInt32Number size; /* Size in bytes */ +} icTag; + +/* A Structure that may be used independently for a list of tags */ +typedef struct { + icUInt32Number count; /* Num tags in the profile */ + icTag tags[icAny]; /* Variable array of tags */ +} icTagList; + +/* The Profile header */ +typedef struct { + icUInt32Number size; /* Prof size in bytes */ + icSignature cmmId; /* CMM for profile */ + icUInt32Number version; /* Format version */ + icProfileClassSignature deviceClass; /* Type of profile */ + icColorSpaceSignature colorSpace; /* Clr space of data */ + icColorSpaceSignature pcs; /* PCS, XYZ or Lab */ + icDateTimeNumber date; /* Creation Date */ + icSignature magic; /* icMagicNumber */ + icPlatformSignature platform; /* Primary Platform */ + icUInt32Number flags; /* Various bits */ + icSignature manufacturer; /* Dev manufacturer */ + icUInt32Number model; /* Dev model number */ + icUInt64Number attributes; /* Device attributes */ + icUInt32Number renderingIntent;/* Rendering intent */ + icXYZNumber illuminant; /* Profile illuminant */ + icSignature creator; /* Profile creator */ + icInt8Number reserved[44]; /* Reserved */ +} icHeader; + +/* + * A profile, + * we can't use icTagList here because its not at the end of the structure + */ +typedef struct { + icHeader header; /* The header */ + icUInt32Number count; /* Num tags in the profile */ + icInt8Number data[icAny]; /* The tagTable and tagData */ +/* + * Data that follows is of the form + * + * icTag tagTable[icAny]; * The tag table + * icInt8Number tagData[icAny]; * The tag data + */ +} icProfile; + +/*------------------------------------------------------------------------*/ +/* Obsolete entries */ + +/* icNamedColor was replaced with icNamedColor2 */ +typedef struct { + icUInt32Number vendorFlag; /* Bottom 16 bits for IC use */ + icUInt32Number count; /* Count of named colors */ + icInt8Number data[icAny]; /* Named color data follows */ +/* + * Data that follows is of this form + * + * icInt8Number prefix[icAny]; * Prefix + * icInt8Number suffix[icAny]; * Suffix + * icInt8Number root1[icAny]; * Root name + * icInt8Number coords1[icAny]; * Color coordinates + * icInt8Number root2[icAny]; * Root name + * icInt8Number coords2[icAny]; * Color coordinates + * : + * : + * Repeat for root name and color coordinates up to (count-1) + */ +} icNamedColor; + +/* icNamedColorType was replaced by icNamedColor2Type */ +typedef struct { + icTagBase base; /* Signature, "ncol" */ + icNamedColor ncolor; /* Named color data */ +} icNamedColorType; + +#endif /* ICC_H */ diff --git a/winclude/infblock.h b/winclude/infblock.h new file mode 100755 index 000000000..4cf0fa969 --- /dev/null +++ b/winclude/infblock.h @@ -0,0 +1,39 @@ +/* infblock.h -- header to use infblock.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_blocks_state; +typedef struct inflate_blocks_state FAR inflate_blocks_statef; + +extern inflate_blocks_statef * inflate_blocks_new OF(( + z_streamp z, + check_func c, /* check function */ + uInt w)); /* window size */ + +extern int inflate_blocks OF(( + inflate_blocks_statef *, + z_streamp , + int)); /* initial return code */ + +extern void inflate_blocks_reset OF(( + inflate_blocks_statef *, + z_streamp , + uLongf *)); /* check value on output */ + +extern int inflate_blocks_free OF(( + inflate_blocks_statef *, + z_streamp)); + +extern void inflate_set_dictionary OF(( + inflate_blocks_statef *s, + const Bytef *d, /* dictionary */ + uInt n)); /* dictionary length */ + +extern int inflate_blocks_sync_point OF(( + inflate_blocks_statef *s)); diff --git a/winclude/infcodes.h b/winclude/infcodes.h new file mode 100755 index 000000000..531d41927 --- /dev/null +++ b/winclude/infcodes.h @@ -0,0 +1,27 @@ +/* infcodes.h -- header to use infcodes.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_codes_state; +typedef struct inflate_codes_state FAR inflate_codes_statef; + +extern inflate_codes_statef *inflate_codes_new OF(( + uInt, uInt, + inflate_huft *, inflate_huft *, + z_streamp )); + +extern int inflate_codes OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +extern void inflate_codes_free OF(( + inflate_codes_statef *, + z_streamp )); + diff --git a/winclude/inffast.h b/winclude/inffast.h new file mode 100755 index 000000000..ac643b329 --- /dev/null +++ b/winclude/inffast.h @@ -0,0 +1,17 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +extern int inflate_fast OF(( + uInt, + uInt, + inflate_huft *, + inflate_huft *, + inflate_blocks_statef *, + z_streamp )); diff --git a/winclude/inffixed.h b/winclude/inffixed.h new file mode 100755 index 000000000..e997507c3 --- /dev/null +++ b/winclude/inffixed.h @@ -0,0 +1,151 @@ +/* inffixed.h -- table for decoding fixed codes + * Generated automatically by the maketree.c program + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +local uInt fixed_bl = 9; +local uInt fixed_bd = 5; +local inflate_huft fixed_tl[] = { + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} + }; +local inflate_huft fixed_td[] = { + {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, + {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, + {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, + {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, + {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, + {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, + {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, + {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} + }; diff --git a/winclude/inftrees.h b/winclude/inftrees.h new file mode 100755 index 000000000..affbb3b21 --- /dev/null +++ b/winclude/inftrees.h @@ -0,0 +1,58 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). */ + +typedef struct inflate_huft_s FAR inflate_huft; + +struct inflate_huft_s { + union { + struct { + Byte Exop; /* number of extra bits or operation */ + Byte Bits; /* number of bits in this code or subcode */ + } what; + uInt pad; /* pad structure to a power of 2 (4 bytes for */ + } word; /* 16-bit, 8 bytes for 32-bit int's) */ + uInt base; /* literal, length base, distance base, + or table offset */ +}; + +/* Maximum size of dynamic tree. The maximum found in a long but non- + exhaustive search was 1004 huft structures (850 for length/literals + and 154 for distances, the latter actually the result of an + exhaustive search). The actual maximum is not known, but the + value below is more than safe. */ +#define MANY 1440 + +extern int inflate_trees_bits OF(( + uIntf *, /* 19 code lengths */ + uIntf *, /* bits tree desired/actual depth */ + inflate_huft * FAR *, /* bits tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ + +extern int inflate_trees_dynamic OF(( + uInt, /* number of literal/length codes */ + uInt, /* number of distance codes */ + uIntf *, /* that many (total) code lengths */ + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *, /* distance tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ + +extern int inflate_trees_fixed OF(( + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *, /* distance tree result */ + z_streamp)); /* for memory allocation */ diff --git a/winclude/infutil.h b/winclude/infutil.h new file mode 100755 index 000000000..0c0ace366 --- /dev/null +++ b/winclude/infutil.h @@ -0,0 +1,98 @@ +/* infutil.h -- types and macros common to blocks and codes + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _INFUTIL_H +#define _INFUTIL_H + +typedef enum { + TYPE, /* get type bits (3, including end bit) */ + LENS, /* get lengths for stored */ + STORED, /* processing stored block */ + TABLE, /* get table lengths */ + BTREE, /* get bit lengths tree for a dynamic block */ + DTREE, /* get length, distance trees for a dynamic block */ + CODES, /* processing fixed or dynamic block */ + DRY, /* output remaining window bytes */ + DONE, /* finished last block, done */ + BAD} /* got a data error--stuck here */ +inflate_block_mode; + +/* inflate blocks semi-private state */ +struct inflate_blocks_state { + + /* mode */ + inflate_block_mode mode; /* current inflate_block mode */ + + /* mode dependent information */ + union { + uInt left; /* if STORED, bytes left to copy */ + struct { + uInt table; /* table lengths (14 bits) */ + uInt index; /* index into blens (or border) */ + uIntf *blens; /* bit lengths of codes */ + uInt bb; /* bit length tree depth */ + inflate_huft *tb; /* bit length decoding tree */ + } trees; /* if DTREE, decoding info for trees */ + struct { + inflate_codes_statef + *codes; + } decode; /* if CODES, current state */ + } sub; /* submode */ + uInt last; /* true if this block is the last block */ + + /* mode independent information */ + uInt bitk; /* bits in bit buffer */ + uLong bitb; /* bit buffer */ + inflate_huft *hufts; /* single malloc for tree space */ + Bytef *window; /* sliding window */ + Bytef *end; /* one byte after sliding window */ + Bytef *read; /* window read pointer */ + Bytef *write; /* window write pointer */ + check_func checkfn; /* check function */ + uLong check; /* check on output */ + +}; + + +/* defines for inflate input/output */ +/* update pointers and return */ +#define UPDBITS {s->bitb=b;s->bitk=k;} +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} +#define UPDOUT {s->write=q;} +#define UPDATE {UPDBITS UPDIN UPDOUT} +#define LEAVE {UPDATE return inflate_flush(s,z,r);} +/* get bytes and bits */ +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} +#define NEXTBYTE (n--,*p++) +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} +/* output bytes */ +#define WAVAIL (uInt)(qread?s->read-q-1:s->end-q) +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} +#define OUTBYTE(a) {*q++=(Byte)(a);m--;} +/* load local pointers */ +#define LOAD {LOADIN LOADOUT} + +/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ +extern uInt inflate_mask[17]; + +/* copy as much as possible from the sliding window to the output area */ +extern int inflate_flush OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +struct internal_state {int dummy;}; /* for buggy compilers */ + +#endif diff --git a/winclude/jchuff.h b/winclude/jchuff.h new file mode 100755 index 000000000..a914f45d7 --- /dev/null +++ b/winclude/jchuff.h @@ -0,0 +1,47 @@ +/* + * jchuff.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains declarations for Huffman entropy encoding routines + * that are shared between the sequential encoder (jchuff.c) and the + * progressive encoder (jcphuff.c). No other modules need to see these. + */ + +/* The legal range of a DCT coefficient is + * -1024 .. +1023 for 8-bit data; + * -16384 .. +16383 for 12-bit data. + * Hence the magnitude should always fit in 10 or 14 bits respectively. + */ + +#if BITS_IN_JSAMPLE == 8 +#define MAX_COEF_BITS 10 +#else +#define MAX_COEF_BITS 14 +#endif + +/* Derived data constructed for each Huffman table */ + +typedef struct { + unsigned int ehufco[256]; /* code for each symbol */ + char ehufsi[256]; /* length of code for each symbol */ + /* If no code has been allocated for a symbol S, ehufsi[S] contains 0 */ +} c_derived_tbl; + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_make_c_derived_tbl jMkCDerived +#define jpeg_gen_optimal_table jGenOptTbl +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + +/* Expand a Huffman table definition into the derived format */ +EXTERN(void) jpeg_make_c_derived_tbl + JPP((j_compress_ptr cinfo, jboolean isDC, int tblno, + c_derived_tbl ** pdtbl)); + +/* Generate an optimal table definition given the specified counts */ +EXTERN(void) jpeg_gen_optimal_table + JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])); diff --git a/winclude/jconfig.h b/winclude/jconfig.h new file mode 100755 index 000000000..9594ec56b --- /dev/null +++ b/winclude/jconfig.h @@ -0,0 +1,45 @@ +/* jconfig.h. Generated automatically by configure. */ +/* jconfig.cfg --- source file edited by configure script */ +/* see jconfig.doc for explanations */ + +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +#undef void +#undef const +#undef CHAR_IS_UNSIGNED +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#undef NEED_FAR_POINTERS +#undef NEED_SHORT_EXTERNAL_NAMES +/* Define this if you get warnings about undefined structures. */ +#undef INCOMPLETE_TYPES_BROKEN + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED +#define INLINE __inline__ +/* These are for configuring the JPEG memory manager. */ +#undef DEFAULT_MAX_MEM +#undef NO_MKTEMP + +#endif /* JPEG_INTERNALS */ + +#ifdef JPEG_CJPEG_DJPEG + +#define BMP_SUPPORTED /* BMP image file format */ +#define GIF_SUPPORTED /* GIF image file format */ +#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ +#undef RLE_SUPPORTED /* Utah RLE image file format */ +#define TARGA_SUPPORTED /* Targa image file format */ + +#undef TWO_FILE_COMMANDLINE +#undef NEED_SIGNAL_CATCHER +#undef DONT_USE_B_MODE + +/* Define this if you want percent-done progress reports from cjpeg/djpeg. */ +#undef PROGRESS_REPORT + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/winclude/jdatasrc.c b/winclude/jdatasrc.c new file mode 100755 index 000000000..bfbd9e802 --- /dev/null +++ b/winclude/jdatasrc.c @@ -0,0 +1,408 @@ +/* + * jdatasrc.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains decompression data source routines for the case of + * reading JPEG data from a file (or any stdio stream). While these routines + * are sufficient for most applications, some will want to use a different + * source manager. + * IMPORTANT: we assume that fread() will correctly transcribe an array of + * JOCTETs from 8-bit-wide elements on external storage. If char is wider + * than 8 bits on your machine, you may need to do some tweaking. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +//#include "jinclude.h" +#include +#include +#include + +#define JFREAD(file,buf,sizeofbuf) \ + ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) +#define JFWRITE(file,buf,sizeofbuf) \ + ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) + + + + +/* Expanded data source object for stdio input */ + +typedef struct { + struct jpeg_source_mgr pub; /* public fields */ + + FILE * infile; /* source stream */ + JOCTET * buffer; /* start of buffer */ + jboolean start_of_file; /* have we gotten any data yet? */ +} my_source_mgr; + +typedef my_source_mgr * my_src_ptr; + +#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ + + +/* + * Initialize source --- called by jpeg_read_header + * before any data is actually read. + */ + +METHODDEF(void) +my_init_source (j_decompress_ptr cinfo) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + /* We reset the empty-input-file flag for each image, + * but we don't clear the input buffer. + * This is correct behavior for reading a series of images from one source. + */ + src->start_of_file = TRUE; +} + + +/* + * Fill the input buffer --- called whenever buffer is emptied. + * + * In typical applications, this should read fresh data into the buffer + * (ignoring the current state of next_input_byte & bytes_in_buffer), + * reset the pointer & count to the start of the buffer, and return TRUE + * indicating that the buffer has been reloaded. It is not necessary to + * fill the buffer entirely, only to obtain at least one more byte. + * + * There is no such thing as an EOF return. If the end of the file has been + * reached, the routine has a choice of ERREXIT() or inserting fake data into + * the buffer. In most cases, generating a warning message and inserting a + * fake EOI marker is the best course of action --- this will allow the + * decompressor to output however much of the image is there. However, + * the resulting error message is misleading if the real problem is an empty + * input file, so we handle that case specially. + * + * In applications that need to be able to suspend compression due to input + * not being available yet, a FALSE return indicates that no more data can be + * obtained right now, but more may be forthcoming later. In this situation, + * the decompressor will return to its caller (with an indication of the + * number of scanlines it has read, if any). The application should resume + * decompression after it has loaded more data into the input buffer. Note + * that there are substantial restrictions on the use of suspension --- see + * the documentation. + * + * When suspending, the decompressor will back up to a convenient restart point + * (typically the start of the current MCU). next_input_byte & bytes_in_buffer + * indicate where the restart point will be if the current call returns FALSE. + * Data beyond this point must be rescanned after resumption, so move it to + * the front of the buffer rather than discarding it. + */ + +METHODDEF(jboolean) +my_fill_input_buffer (j_decompress_ptr cinfo) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + size_t nbytes; + + nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE); + + if (nbytes <= 0) { + if (src->start_of_file) /* Treat empty input file as fatal error */ + ERREXIT(cinfo, JERR_INPUT_EMPTY); + WARNMS(cinfo, JWRN_JPEG_EOF); + /* Insert a fake EOI marker */ + src->buffer[0] = (JOCTET) 0xFF; + src->buffer[1] = (JOCTET) JPEG_EOI; + nbytes = 2; + } + + if (src->start_of_file) + src->buffer[0] = (JOCTET) 0xFF; + + src->pub.next_input_byte = src->buffer; + src->pub.bytes_in_buffer = nbytes; + src->start_of_file = FALSE; + + return TRUE; +} + + +/* + * Skip data --- used to skip over a potentially large amount of + * uninteresting data (such as an APPn marker). + * + * Writers of suspendable-input applications must note that skip_input_data + * is not granted the right to give a suspension return. If the skip extends + * beyond the data currently in the buffer, the buffer can be marked empty so + * that the next read will cause a fill_input_buffer call that can suspend. + * Arranging for additional bytes to be discarded before reloading the input + * buffer is the application writer's problem. + */ + +METHODDEF(void) +my_skip_input_data (j_decompress_ptr cinfo, long num_bytes) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + /* Just a dumb implementation for now. Could use fseek() except + * it doesn't work on pipes. Not clear that being smart is worth + * any trouble anyway --- large skips are infrequent. + */ + if (num_bytes > 0) { + while (num_bytes > (long) src->pub.bytes_in_buffer) { + num_bytes -= (long) src->pub.bytes_in_buffer; + (void) my_fill_input_buffer(cinfo); + /* note we assume that fill_input_buffer will never return FALSE, + * so suspension need not be handled. + */ + } + src->pub.next_input_byte += (size_t) num_bytes; + src->pub.bytes_in_buffer -= (size_t) num_bytes; + } +} + + +/* + * An additional method that can be provided by data source modules is the + * resync_to_restart method for error recovery in the presence of RST markers. + * For the moment, this source module just uses the default resync method + * provided by the JPEG library. That method assumes that no backtracking + * is possible. + */ + + +/* + * Terminate source --- called by jpeg_finish_decompress + * after all data has been read. Often a no-op. + * + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + * application must deal with any cleanup that should happen even + * for error exit. + */ + +METHODDEF(void) +my_term_source (j_decompress_ptr cinfo) +{ + /* no work necessary here */ +} + + +/* + * Prepare for input from a stdio stream. + * The caller must have already opened the stream, and is responsible + * for closing it after finishing decompression. + */ + +GLOBAL(void) +my_jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile) +{ + my_src_ptr src; + + /* The source object and input buffer are made permanent so that a series + * of JPEG images can be read from the same file by calling jpeg_stdio_src + * only before the first one. (If we discarded the buffer at the end of + * one image, we'd likely lose the start of the next one.) + * This makes it unsafe to use this manager and a different source + * manager serially with the same JPEG object. Caveat programmer. + */ + if (cinfo->src == NULL) { /* first time for this JPEG object? */ + cinfo->src = (struct jpeg_source_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + sizeof(my_source_mgr)); + src = (my_src_ptr) cinfo->src; + src->buffer = (JOCTET *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + INPUT_BUF_SIZE * sizeof(JOCTET)); + } + + src = (my_src_ptr) cinfo->src; + src->pub.init_source = my_init_source; + src->pub.fill_input_buffer = my_fill_input_buffer; + src->pub.skip_input_data = my_skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ + src->pub.term_source = my_term_source; + src->infile = infile; + src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ + src->pub.next_input_byte = NULL; /* until buffer loaded */ +} + +jmp_buf jpeg_jmp_buf; + +METHODDEF(void) +my_error_exit (j_common_ptr cinfo) +{ + /* Always display the message */ + (*cinfo->err->output_message) (cinfo); + + /* Let the memory manager delete any temp files before we die */ + jpeg_destroy(cinfo); + + longjmp (jpeg_jmp_buf, 1); +} + + +//const char * const jpeg_std_message_table[] = { +//#include "jerror.h" +// NULL +//}; +extern const char * const jpeg_std_message_table[]; + + +/* + * Actual output of an error or trace message. + * Applications may override this method to send JPEG messages somewhere + * other than stderr. + * + * On Windows, printing to stderr is generally completely useless, + * so we provide optional code to produce an error-dialog popup. + * Most Windows applications will still prefer to override this routine, + * but if they don't, it'll do something at least marginally useful. + * + * NOTE: to use the library in an environment that doesn't support the + * C stdio library, you may have to delete the call to fprintf() entirely, + * not just not use this routine. + */ + +METHODDEF(void) +output_message (j_common_ptr cinfo) +{ + char buffer[JMSG_LENGTH_MAX]; + + /* Create the message */ + (*cinfo->err->format_message) (cinfo, buffer); + +#ifdef USE_WINDOWS_MESSAGEBOX + /* Display it in a message dialog box */ + MessageBox(GetActiveWindow(), buffer, "JPEG Library Error", + MB_OK | MB_ICONERROR); +#else + /* Send it to stderr, adding a newline */ + fprintf(stderr, "%s\n", buffer); +#endif +} + + +/* + * Decide whether to emit a trace or warning message. + * msg_level is one of: + * -1: recoverable corrupt-data warning, may want to abort. + * 0: important advisory messages (always display to user). + * 1: first level of tracing detail. + * 2,3,...: successively more detailed tracing messages. + * An application might override this method if it wanted to abort on warnings + * or change the policy about which messages to display. + */ + +METHODDEF(void) +emit_message (j_common_ptr cinfo, int msg_level) +{ + struct jpeg_error_mgr * err = cinfo->err; + + if (msg_level < 0) { + /* It's a warning message. Since corrupt files may generate many warnings, + * the policy implemented here is to show only the first warning, + * unless trace_level >= 3. + */ + if (err->num_warnings == 0 || err->trace_level >= 3) + (*err->output_message) (cinfo); + /* Always count warnings in num_warnings. */ + err->num_warnings++; + } else { + /* It's a trace message. Show it if trace_level >= msg_level. */ + if (err->trace_level >= msg_level) + (*err->output_message) (cinfo); + } +} + + +/* + * Format a message string for the most recent JPEG error or message. + * The message is stored into buffer, which should be at least JMSG_LENGTH_MAX + * characters. Note that no '\n' character is added to the string. + * Few applications should need to override this method. + */ + +METHODDEF(void) +format_message (j_common_ptr cinfo, char * buffer) +{ + struct jpeg_error_mgr * err = cinfo->err; + int msg_code = err->msg_code; + const char * msgtext = NULL; + const char * msgptr; + char ch; + jboolean isstring; + + /* Look up message string in proper table */ + if (msg_code > 0 && msg_code <= err->last_jpeg_message) { + msgtext = err->jpeg_message_table[msg_code]; + } else if (err->addon_message_table != NULL && + msg_code >= err->first_addon_message && + msg_code <= err->last_addon_message) { + msgtext = err->addon_message_table[msg_code - err->first_addon_message]; + } + + /* Defend against bogus message number */ + if (msgtext == NULL) { + err->msg_parm.i[0] = msg_code; + msgtext = err->jpeg_message_table[0]; + } + + /* Check for string parameter, as indicated by %s in the message text */ + isstring = FALSE; + msgptr = msgtext; + while ((ch = *msgptr++) != '\0') { + if (ch == '%') { + if (*msgptr == 's') isstring = TRUE; + break; + } + } + + /* Format the message into the passed buffer */ + if (isstring) + sprintf(buffer, msgtext, err->msg_parm.s); + else + sprintf(buffer, msgtext, + err->msg_parm.i[0], err->msg_parm.i[1], + err->msg_parm.i[2], err->msg_parm.i[3], + err->msg_parm.i[4], err->msg_parm.i[5], + err->msg_parm.i[6], err->msg_parm.i[7]); +} + + +/* + * Reset error state variables at start of a new image. + * This is called during compression startup to reset trace/error + * processing to default state, without losing any application-specific + * method pointers. An application might possibly want to override + * this method if it has additional error processing state. + */ + +METHODDEF(void) +reset_error_mgr (j_common_ptr cinfo) +{ + cinfo->err->num_warnings = 0; + /* trace_level is not reset since it is an application-supplied parameter */ + cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */ +} + + +GLOBAL(struct jpeg_error_mgr *) +my_jpeg_std_error (struct jpeg_error_mgr * err) +{ + + err->error_exit = my_error_exit; + err->emit_message = emit_message; + err->output_message = output_message; + err->format_message = format_message; + err->reset_error_mgr = reset_error_mgr; + + err->trace_level = 0; /* default = no tracing */ + err->num_warnings = 0; /* no warnings emitted yet */ + err->msg_code = 0; /* may be useful as a flag for "no error" */ + + /* Initialize message table pointers */ + err->jpeg_message_table = jpeg_std_message_table; + err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1; + + err->addon_message_table = NULL; + err->first_addon_message = 0; /* for safety */ + err->last_addon_message = 0; + + return err; +} diff --git a/winclude/jdct.h b/winclude/jdct.h new file mode 100755 index 000000000..04192a266 --- /dev/null +++ b/winclude/jdct.h @@ -0,0 +1,176 @@ +/* + * jdct.h + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This include file contains common declarations for the forward and + * inverse DCT modules. These declarations are private to the DCT managers + * (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms. + * The individual DCT algorithms are kept in separate files to ease + * machine-dependent tuning (e.g., assembly coding). + */ + + +/* + * A forward DCT routine is given a pointer to a work area of type DCTELEM[]; + * the DCT is to be performed in-place in that buffer. Type DCTELEM is int + * for 8-bit samples, INT32 for 12-bit samples. (NOTE: Floating-point DCT + * implementations use an array of type FAST_FLOAT, instead.) + * The DCT inputs are expected to be signed (range +-CENTERJSAMPLE). + * The DCT outputs are returned scaled up by a factor of 8; they therefore + * have a range of +-8K for 8-bit data, +-128K for 12-bit data. This + * convention improves accuracy in integer implementations and saves some + * work in floating-point ones. + * Quantization of the output coefficients is done by jcdctmgr.c. + */ + +#if BITS_IN_JSAMPLE == 8 +typedef int DCTELEM; /* 16 or 32 bits is fine */ +#else +typedef INT32 DCTELEM; /* must have 32 bits */ +#endif + +typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data)); +typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data)); + + +/* + * An inverse DCT routine is given a pointer to the input JBLOCK and a pointer + * to an output sample array. The routine must dequantize the input data as + * well as perform the IDCT; for dequantization, it uses the multiplier table + * pointed to by compptr->dct_table. The output data is to be placed into the + * sample array starting at a specified column. (Any row offset needed will + * be applied to the array pointer before it is passed to the IDCT code.) + * Note that the number of samples emitted by the IDCT routine is + * DCT_scaled_size * DCT_scaled_size. + */ + +/* typedef inverse_DCT_method_ptr is declared in jpegint.h */ + +/* + * Each IDCT routine has its own ideas about the best dct_table element type. + */ + +typedef MULTIPLIER ISLOW_MULT_TYPE; /* short or int, whichever is faster */ +#if BITS_IN_JSAMPLE == 8 +typedef MULTIPLIER IFAST_MULT_TYPE; /* 16 bits is OK, use short if faster */ +#define IFAST_SCALE_BITS 2 /* fractional bits in scale factors */ +#else +typedef INT32 IFAST_MULT_TYPE; /* need 32 bits for scaled quantizers */ +#define IFAST_SCALE_BITS 13 /* fractional bits in scale factors */ +#endif +typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */ + + +/* + * Each IDCT routine is responsible for range-limiting its results and + * converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + * be quite far out of range if the input data is corrupt, so a bulletproof + * range-limiting step is required. We use a mask-and-table-lookup method + * to do the combined operations quickly. See the comments with + * prepare_range_limit_table (in jdmaster.c) for more info. + */ + +#define IDCT_range_limit(cinfo) ((cinfo)->sample_range_limit + CENTERJSAMPLE) + +#define RANGE_MASK (MAXJSAMPLE * 4 + 3) /* 2 bits wider than legal samples */ + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_fdct_islow jFDislow +#define jpeg_fdct_ifast jFDifast +#define jpeg_fdct_float jFDfloat +#define jpeg_idct_islow jRDislow +#define jpeg_idct_ifast jRDifast +#define jpeg_idct_float jRDfloat +#define jpeg_idct_4x4 jRD4x4 +#define jpeg_idct_2x2 jRD2x2 +#define jpeg_idct_1x1 jRD1x1 +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + +/* Extern declarations for the forward and inverse DCT routines. */ + +EXTERN(void) jpeg_fdct_islow JPP((DCTELEM * data)); +EXTERN(void) jpeg_fdct_ifast JPP((DCTELEM * data)); +EXTERN(void) jpeg_fdct_float JPP((FAST_FLOAT * data)); + +EXTERN(void) jpeg_idct_islow + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN(void) jpeg_idct_ifast + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN(void) jpeg_idct_float + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN(void) jpeg_idct_4x4 + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN(void) jpeg_idct_2x2 + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); +EXTERN(void) jpeg_idct_1x1 + JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); + + +/* + * Macros for handling fixed-point arithmetic; these are used by many + * but not all of the DCT/IDCT modules. + * + * All values are expected to be of type INT32. + * Fractional constants are scaled left by CONST_BITS bits. + * CONST_BITS is defined within each module using these macros, + * and may differ from one module to the next. + */ + +#define ONE ((INT32) 1) +#define CONST_SCALE (ONE << CONST_BITS) + +/* Convert a positive real constant to an integer scaled by CONST_SCALE. + * Caution: some C compilers fail to reduce "FIX(constant)" at compile time, + * thus causing a lot of useless floating-point operations at run time. + */ + +#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5)) + +/* Descale and correctly round an INT32 value that's scaled by N bits. + * We assume RIGHT_SHIFT rounds towards minus infinity, so adding + * the fudge factor is correct for either sign of X. + */ + +#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n) + +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + * This macro is used only when the two inputs will actually be no more than + * 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a + * full 32x32 multiply. This provides a useful speedup on many machines. + * Unfortunately there is no way to specify a 16x16->32 multiply portably + * in C, but some C compilers will do the right thing if you provide the + * correct combination of casts. + */ + +#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ +#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT16) (const))) +#endif +#ifdef SHORTxLCONST_32 /* known to work with Microsoft C 6.0 */ +#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT32) (const))) +#endif + +#ifndef MULTIPLY16C16 /* default definition */ +#define MULTIPLY16C16(var,const) ((var) * (const)) +#endif + +/* Same except both inputs are variables. */ + +#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ +#define MULTIPLY16V16(var1,var2) (((INT16) (var1)) * ((INT16) (var2))) +#endif + +#ifndef MULTIPLY16V16 /* default definition */ +#define MULTIPLY16V16(var1,var2) ((var1) * (var2)) +#endif diff --git a/winclude/jdhuff.h b/winclude/jdhuff.h new file mode 100755 index 000000000..82199ca40 --- /dev/null +++ b/winclude/jdhuff.h @@ -0,0 +1,201 @@ +/* + * jdhuff.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains declarations for Huffman entropy decoding routines + * that are shared between the sequential decoder (jdhuff.c) and the + * progressive decoder (jdphuff.c). No other modules need to see these. + */ + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_make_d_derived_tbl jMkDDerived +#define jpeg_fill_bit_buffer jFilBitBuf +#define jpeg_huff_decode jHufDecode +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Derived data constructed for each Huffman table */ + +#define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */ + +typedef struct { + /* Basic tables: (element [0] of each array is unused) */ + INT32 maxcode[18]; /* largest code of length k (-1 if none) */ + /* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */ + INT32 valoffset[17]; /* huffval[] offset for codes of length k */ + /* valoffset[k] = huffval[] index of 1st symbol of code length k, less + * the smallest code of length k; so given a code of length k, the + * corresponding symbol is huffval[code + valoffset[k]] + */ + + /* Link to public Huffman table (needed only in jpeg_huff_decode) */ + JHUFF_TBL *pub; + + /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of + * the input data stream. If the next Huffman code is no more + * than HUFF_LOOKAHEAD bits long, we can obtain its length and + * the corresponding symbol directly from these tables. + */ + int look_nbits[1< 32 bits on your machine, and shifting/masking longs is + * reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE + * appropriately should be a win. Unfortunately we can't define the size + * with something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8) + * because not all machines measure sizeof in 8-bit bytes. + */ + +typedef struct { /* Bitreading state saved across MCUs */ + bit_buf_type get_buffer; /* current bit-extraction buffer */ + int bits_left; /* # of unused bits in it */ +} bitread_perm_state; + +typedef struct { /* Bitreading working state within an MCU */ + /* Current data source location */ + /* We need a copy, rather than munging the original, in case of suspension */ + const JOCTET * next_input_byte; /* => next byte to read from source */ + size_t bytes_in_buffer; /* # of bytes remaining in source buffer */ + /* Bit input buffer --- note these values are kept in register variables, + * not in this struct, inside the inner loops. + */ + bit_buf_type get_buffer; /* current bit-extraction buffer */ + int bits_left; /* # of unused bits in it */ + /* Pointer needed by jpeg_fill_bit_buffer. */ + j_decompress_ptr cinfo; /* back link to decompress master record */ +} bitread_working_state; + +/* Macros to declare and load/save bitread local variables. */ +#define BITREAD_STATE_VARS \ + register bit_buf_type get_buffer; \ + register int bits_left; \ + bitread_working_state br_state + +#define BITREAD_LOAD_STATE(cinfop,permstate) \ + br_state.cinfo = cinfop; \ + br_state.next_input_byte = cinfop->src->next_input_byte; \ + br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \ + get_buffer = permstate.get_buffer; \ + bits_left = permstate.bits_left; + +#define BITREAD_SAVE_STATE(cinfop,permstate) \ + cinfop->src->next_input_byte = br_state.next_input_byte; \ + cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \ + permstate.get_buffer = get_buffer; \ + permstate.bits_left = bits_left + +/* + * These macros provide the in-line portion of bit fetching. + * Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer + * before using GET_BITS, PEEK_BITS, or DROP_BITS. + * The variables get_buffer and bits_left are assumed to be locals, + * but the state struct might not be (jpeg_huff_decode needs this). + * CHECK_BIT_BUFFER(state,n,action); + * Ensure there are N bits in get_buffer; if suspend, take action. + * val = GET_BITS(n); + * Fetch next N bits. + * val = PEEK_BITS(n); + * Fetch next N bits without removing them from the buffer. + * DROP_BITS(n); + * Discard next N bits. + * The value N should be a simple variable, not an expression, because it + * is evaluated multiple times. + */ + +#define CHECK_BIT_BUFFER(state,nbits,action) \ + { if (bits_left < (nbits)) { \ + if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits)) \ + { action; } \ + get_buffer = (state).get_buffer; bits_left = (state).bits_left; } } + +#define GET_BITS(nbits) \ + (((int) (get_buffer >> (bits_left -= (nbits)))) & ((1<<(nbits))-1)) + +#define PEEK_BITS(nbits) \ + (((int) (get_buffer >> (bits_left - (nbits)))) & ((1<<(nbits))-1)) + +#define DROP_BITS(nbits) \ + (bits_left -= (nbits)) + +/* Load up the bit buffer to a depth of at least nbits */ +EXTERN(jboolean) jpeg_fill_bit_buffer + JPP((bitread_working_state * state, register bit_buf_type get_buffer, + register int bits_left, int nbits)); + + +/* + * Code for extracting next Huffman-coded symbol from input bit stream. + * Again, this is time-critical and we make the main paths be macros. + * + * We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits + * without looping. Usually, more than 95% of the Huffman codes will be 8 + * or fewer bits long. The few overlength codes are handled with a loop, + * which need not be inline code. + * + * Notes about the HUFF_DECODE macro: + * 1. Near the end of the data segment, we may fail to get enough bits + * for a lookahead. In that case, we do it the hard way. + * 2. If the lookahead table contains no entry, the next code must be + * more than HUFF_LOOKAHEAD bits long. + * 3. jpeg_huff_decode returns -1 if forced to suspend. + */ + +#define HUFF_DECODE(result,state,htbl,failaction,slowlabel) \ +{ register int nb, look; \ + if (bits_left < HUFF_LOOKAHEAD) { \ + if (! jpeg_fill_bit_buffer(&state,get_buffer,bits_left, 0)) {failaction;} \ + get_buffer = state.get_buffer; bits_left = state.bits_left; \ + if (bits_left < HUFF_LOOKAHEAD) { \ + nb = 1; goto slowlabel; \ + } \ + } \ + look = PEEK_BITS(HUFF_LOOKAHEAD); \ + if ((nb = htbl->look_nbits[look]) != 0) { \ + DROP_BITS(nb); \ + result = htbl->look_sym[look]; \ + } else { \ + nb = HUFF_LOOKAHEAD+1; \ +slowlabel: \ + if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \ + { failaction; } \ + get_buffer = state.get_buffer; bits_left = state.bits_left; \ + } \ +} + +/* Out-of-line case for Huffman code fetching */ +EXTERN(int) jpeg_huff_decode + JPP((bitread_working_state * state, register bit_buf_type get_buffer, + register int bits_left, d_derived_tbl * htbl, int min_bits)); diff --git a/winclude/jerror.h b/winclude/jerror.h new file mode 100755 index 000000000..fc2fffeac --- /dev/null +++ b/winclude/jerror.h @@ -0,0 +1,291 @@ +/* + * jerror.h + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the error and message codes for the JPEG library. + * Edit this file to add new codes, or to translate the message strings to + * some other language. + * A set of error-reporting macros are defined too. Some applications using + * the JPEG library may wish to include this file to get the error codes + * and/or the macros. + */ + +/* + * To define the enum list of message codes, include this file without + * defining macro JMESSAGE. To create a message string table, include it + * again with a suitable JMESSAGE definition (see jerror.c for an example). + */ +#ifndef JMESSAGE +#ifndef JERROR_H +/* First time through, define the enum list */ +#define JMAKE_ENUM_LIST +#else +/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */ +#define JMESSAGE(code,string) +#endif /* JERROR_H */ +#endif /* JMESSAGE */ + +#ifdef JMAKE_ENUM_LIST + +typedef enum { + +#define JMESSAGE(code,string) code , + +#endif /* JMAKE_ENUM_LIST */ + +JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */ + +/* For maintenance convenience, list is alphabetical by message code name */ +JMESSAGE(JERR_ARITH_NOTIMPL, + "Sorry, there are legal restrictions on arithmetic coding") +JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix") +JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix") +JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode") +JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS") +JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range") +JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported") +JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition") +JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace") +JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace") +JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length") +JMESSAGE(JERR_BAD_LIB_VERSION, + "Wrong JPEG library version: library is %d, caller expects %d") +JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan") +JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d") +JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d") +JMESSAGE(JERR_BAD_PROGRESSION, + "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d") +JMESSAGE(JERR_BAD_PROG_SCRIPT, + "Invalid progressive parameters at scan script entry %d") +JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors") +JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d") +JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d") +JMESSAGE(JERR_BAD_STRUCT_SIZE, + "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u") +JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access") +JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small") +JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here") +JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet") +JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d") +JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request") +JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d") +JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x") +JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d") +JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d") +JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)") +JMESSAGE(JERR_EMS_READ, "Read from EMS failed") +JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed") +JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan") +JMESSAGE(JERR_FILE_READ, "Input file read error") +JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?") +JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet") +JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow") +JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry") +JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels") +JMESSAGE(JERR_INPUT_EMPTY, "Empty input file") +JMESSAGE(JERR_INPUT_EOF, "Premature end of input file") +JMESSAGE(JERR_MISMATCHED_QUANT_TABLE, + "Cannot transcode due to multiple use of quantization table %d") +JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data") +JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change") +JMESSAGE(JERR_NOTIMPL, "Not implemented yet") +JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time") +JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported") +JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined") +JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image") +JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined") +JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x") +JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)") +JMESSAGE(JERR_QUANT_COMPONENTS, + "Cannot quantize more than %d color components") +JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors") +JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors") +JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers") +JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker") +JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x") +JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers") +JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF") +JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s") +JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file") +JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file") +JMESSAGE(JERR_TFILE_WRITE, + "Write failed on temporary file --- out of disk space?") +JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines") +JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x") +JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up") +JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation") +JMESSAGE(JERR_XMS_READ, "Read from XMS failed") +JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed") +JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT) +JMESSAGE(JMSG_VERSION, JVERSION) +JMESSAGE(JTRC_16BIT_TABLES, + "Caution: quantization tables are too coarse for baseline JPEG") +JMESSAGE(JTRC_ADOBE, + "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d") +JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u") +JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u") +JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x") +JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x") +JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d") +JMESSAGE(JTRC_DRI, "Define Restart Interval %u") +JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u") +JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u") +JMESSAGE(JTRC_EOI, "End Of Image") +JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d") +JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d") +JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE, + "Warning: thumbnail image size does not match data length %u") +JMESSAGE(JTRC_JFIF_EXTENSION, + "JFIF extension marker: type 0x%02x, length %u") +JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image") +JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u") +JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x") +JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u") +JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors") +JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors") +JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization") +JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d") +JMESSAGE(JTRC_RST, "RST%d") +JMESSAGE(JTRC_SMOOTH_NOTIMPL, + "Smoothing not supported with nonstandard sampling ratios") +JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d") +JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d") +JMESSAGE(JTRC_SOI, "Start of Image") +JMESSAGE(JTRC_SOS, "Start Of Scan: %d components") +JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d") +JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d") +JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s") +JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s") +JMESSAGE(JTRC_THUMB_JPEG, + "JFIF extension marker: JPEG-compressed thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_PALETTE, + "JFIF extension marker: palette thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_RGB, + "JFIF extension marker: RGB thumbnail image, length %u") +JMESSAGE(JTRC_UNKNOWN_IDS, + "Unrecognized component IDs %d %d %d, assuming YCbCr") +JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u") +JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u") +JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d") +JMESSAGE(JWRN_BOGUS_PROGRESSION, + "Inconsistent progression sequence for component %d coefficient %d") +JMESSAGE(JWRN_EXTRANEOUS_DATA, + "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x") +JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment") +JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code") +JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d") +JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file") +JMESSAGE(JWRN_MUST_RESYNC, + "Corrupt JPEG data: found marker 0x%02x instead of RST%d") +JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG") +JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") + +#ifdef JMAKE_ENUM_LIST + + JMSG_LASTMSGCODE +} J_MESSAGE_CODE; + +#undef JMAKE_ENUM_LIST +#endif /* JMAKE_ENUM_LIST */ + +/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */ +#undef JMESSAGE + + +#ifndef JERROR_H +#define JERROR_H + +/* Macros to simplify using the error and trace message stuff */ +/* The first parameter is either type of cinfo pointer */ + +/* Fatal errors (print message and exit) */ +#define ERREXIT(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT3(cinfo,code,p1,p2,p3) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (cinfo)->err->msg_parm.i[3] = (p4), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXITS(cinfo,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) + +#define MAKESTMT(stuff) do { stuff } while (0) + +/* Nonfatal errors (we can keep going, but the data is probably corrupt) */ +#define WARNMS(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) + +/* Informational/debugging messages */ +#define TRACEMS(cinfo,lvl,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS1(cinfo,lvl,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS2(cinfo,lvl,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMSS(cinfo,lvl,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) + +#endif /* JERROR_H */ diff --git a/winclude/jinclude.h b/winclude/jinclude.h new file mode 100755 index 000000000..0a4f15146 --- /dev/null +++ b/winclude/jinclude.h @@ -0,0 +1,91 @@ +/* + * jinclude.h + * + * Copyright (C) 1991-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file exists to provide a single place to fix any problems with + * including the wrong system include files. (Common problems are taken + * care of by the standard jconfig symbols, but on really weird systems + * you may have to edit this file.) + * + * NOTE: this file is NOT intended to be included by applications using the + * JPEG library. Most applications need only include jpeglib.h. + */ + + +/* Include auto-config file to find out which system include files we need. */ + +#include "jconfig.h" /* auto configuration options */ +#define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */ + +/* + * We need the NULL macro and size_t typedef. + * On an ANSI-conforming system it is sufficient to include . + * Otherwise, we get them from or ; we may have to + * pull in as well. + * Note that the core JPEG library does not require ; + * only the default error handler and data source/destination modules do. + * But we must pull it in because of the references to FILE in jpeglib.h. + * You can remove those references if you want to compile without . + */ + +#ifdef HAVE_STDDEF_H +#include +#endif + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef NEED_SYS_TYPES_H +#include +#endif + +#include + +/* + * We need memory copying and zeroing functions, plus strncpy(). + * ANSI and System V implementations declare these in . + * BSD doesn't have the mem() functions, but it does have bcopy()/bzero(). + * Some systems may declare memset and memcpy in . + * + * NOTE: we assume the size parameters to these functions are of type size_t. + * Change the casts in these macros if not! + */ + +#ifdef NEED_BSD_STRINGS + +#include +#define MEMZERO(target,size) bzero((void *)(target), (size_t)(size)) +#define MEMCOPY(dest,src,size) bcopy((const void *)(src), (void *)(dest), (size_t)(size)) + +#else /* not BSD, assume ANSI/SysV string lib */ + +#include +#define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size)) +#define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size)) + +#endif + +/* + * In ANSI C, and indeed any rational implementation, size_t is also the + * type returned by sizeof(). However, it seems there are some irrational + * implementations out there, in which sizeof() returns an int even though + * size_t is defined as long or unsigned long. To ensure consistent results + * we always use this SIZEOF() macro in place of using sizeof() directly. + */ + +#define SIZEOF(object) ((size_t) sizeof(object)) + +/* + * The modules that use fread() and fwrite() always invoke them through + * these macros. On some systems you may need to twiddle the argument casts. + * CAUTION: argument order is different from underlying functions! + */ + +#define JFREAD(file,buf,sizeofbuf) \ + ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) +#define JFWRITE(file,buf,sizeofbuf) \ + ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) diff --git a/winclude/jmemsys.h b/winclude/jmemsys.h new file mode 100755 index 000000000..6c3c6d348 --- /dev/null +++ b/winclude/jmemsys.h @@ -0,0 +1,198 @@ +/* + * jmemsys.h + * + * Copyright (C) 1992-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This include file defines the interface between the system-independent + * and system-dependent portions of the JPEG memory manager. No other + * modules need include it. (The system-independent portion is jmemmgr.c; + * there are several different versions of the system-dependent portion.) + * + * This file works as-is for the system-dependent memory managers supplied + * in the IJG distribution. You may need to modify it if you write a + * custom memory manager. If system-dependent changes are needed in + * this file, the best method is to #ifdef them based on a configuration + * symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR + * and USE_MAC_MEMMGR. + */ + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_get_small jGetSmall +#define jpeg_free_small jFreeSmall +#define jpeg_get_large jGetLarge +#define jpeg_free_large jFreeLarge +#define jpeg_mem_available jMemAvail +#define jpeg_open_backing_store jOpenBackStore +#define jpeg_mem_init jMemInit +#define jpeg_mem_term jMemTerm +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* + * These two functions are used to allocate and release small chunks of + * memory. (Typically the total amount requested through jpeg_get_small is + * no more than 20K or so; this will be requested in chunks of a few K each.) + * Behavior should be the same as for the standard library functions malloc + * and free; in particular, jpeg_get_small must return NULL on failure. + * On most systems, these ARE malloc and free. jpeg_free_small is passed the + * size of the object being freed, just in case it's needed. + * On an 80x86 machine using small-data memory model, these manage near heap. + */ + +EXTERN(void *) jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject)); +EXTERN(void) jpeg_free_small JPP((j_common_ptr cinfo, void * object, + size_t sizeofobject)); + +/* + * These two functions are used to allocate and release large chunks of + * memory (up to the total free space designated by jpeg_mem_available). + * The interface is the same as above, except that on an 80x86 machine, + * far pointers are used. On most other machines these are identical to + * the jpeg_get/free_small routines; but we keep them separate anyway, + * in case a different allocation strategy is desirable for large chunks. + */ + +EXTERN(void FAR *) jpeg_get_large JPP((j_common_ptr cinfo, + size_t sizeofobject)); +EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object, + size_t sizeofobject)); + +/* + * The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may + * be requested in a single call to jpeg_get_large (and jpeg_get_small for that + * matter, but that case should never come into play). This macro is needed + * to model the 64Kb-segment-size limit of far addressing on 80x86 machines. + * On those machines, we expect that jconfig.h will provide a proper value. + * On machines with 32-bit flat address spaces, any large constant may be used. + * + * NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type + * size_t and will be a multiple of sizeof(align_type). + */ + +#ifndef MAX_ALLOC_CHUNK /* may be overridden in jconfig.h */ +#define MAX_ALLOC_CHUNK 1000000000L +#endif + +/* + * This routine computes the total space still available for allocation by + * jpeg_get_large. If more space than this is needed, backing store will be + * used. NOTE: any memory already allocated must not be counted. + * + * There is a minimum space requirement, corresponding to the minimum + * feasible buffer sizes; jmemmgr.c will request that much space even if + * jpeg_mem_available returns zero. The maximum space needed, enough to hold + * all working storage in memory, is also passed in case it is useful. + * Finally, the total space already allocated is passed. If no better + * method is available, cinfo->mem->max_memory_to_use - already_allocated + * is often a suitable calculation. + * + * It is OK for jpeg_mem_available to underestimate the space available + * (that'll just lead to more backing-store access than is really necessary). + * However, an overestimate will lead to failure. Hence it's wise to subtract + * a slop factor from the true available space. 5% should be enough. + * + * On machines with lots of virtual memory, any large constant may be returned. + * Conversely, zero may be returned to always use the minimum amount of memory. + */ + +EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo, + long min_bytes_needed, + long max_bytes_needed, + long already_allocated)); + + +/* + * This structure holds whatever state is needed to access a single + * backing-store object. The read/write/close method pointers are called + * by jmemmgr.c to manipulate the backing-store object; all other fields + * are private to the system-dependent backing store routines. + */ + +#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */ + + +#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */ + +typedef unsigned short XMSH; /* type of extended-memory handles */ +typedef unsigned short EMSH; /* type of expanded-memory handles */ + +typedef union { + short file_handle; /* DOS file handle if it's a temp file */ + XMSH xms_handle; /* handle if it's a chunk of XMS */ + EMSH ems_handle; /* handle if it's a chunk of EMS */ +} handle_union; + +#endif /* USE_MSDOS_MEMMGR */ + +#ifdef USE_MAC_MEMMGR /* Mac-specific junk */ +#include +#endif /* USE_MAC_MEMMGR */ + + +typedef struct backing_store_struct * backing_store_ptr; + +typedef struct backing_store_struct { + /* Methods for reading/writing/closing this backing-store object */ + JMETHOD(void, read_backing_store, (j_common_ptr cinfo, + backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count)); + JMETHOD(void, write_backing_store, (j_common_ptr cinfo, + backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count)); + JMETHOD(void, close_backing_store, (j_common_ptr cinfo, + backing_store_ptr info)); + + /* Private fields for system-dependent backing-store management */ +#ifdef USE_MSDOS_MEMMGR + /* For the MS-DOS manager (jmemdos.c), we need: */ + handle_union handle; /* reference to backing-store storage object */ + char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ +#else +#ifdef USE_MAC_MEMMGR + /* For the Mac manager (jmemmac.c), we need: */ + short temp_file; /* file reference number to temp file */ + FSSpec tempSpec; /* the FSSpec for the temp file */ + char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ +#else + /* For a typical implementation with temp files, we need: */ + FILE * temp_file; /* stdio reference to temp file */ + char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */ +#endif +#endif +} backing_store_info; + + +/* + * Initial opening of a backing-store object. This must fill in the + * read/write/close pointers in the object. The read/write routines + * may take an error exit if the specified maximum file size is exceeded. + * (If jpeg_mem_available always returns a large value, this routine can + * just take an error exit.) + */ + +EXTERN(void) jpeg_open_backing_store JPP((j_common_ptr cinfo, + backing_store_ptr info, + long total_bytes_needed)); + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. jpeg_mem_init will be called before anything is + * allocated (and, therefore, nothing in cinfo is of use except the error + * manager pointer). It should return a suitable default value for + * max_memory_to_use; this may subsequently be overridden by the surrounding + * application. (Note that max_memory_to_use is only important if + * jpeg_mem_available chooses to consult it ... no one else will.) + * jpeg_mem_term may assume that all requested memory has been freed and that + * all opened backing-store objects have been closed. + */ + +EXTERN(long) jpeg_mem_init JPP((j_common_ptr cinfo)); +EXTERN(void) jpeg_mem_term JPP((j_common_ptr cinfo)); diff --git a/winclude/jmorecfg.h b/winclude/jmorecfg.h new file mode 100755 index 000000000..c00e644a3 --- /dev/null +++ b/winclude/jmorecfg.h @@ -0,0 +1,363 @@ +/* + * jmorecfg.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains additional configuration options that customize the + * JPEG software for special applications or support machine-dependent + * optimizations. Most users will not need to touch this file. + */ + + +/* + * Define BITS_IN_JSAMPLE as either + * 8 for 8-bit sample values (the usual setting) + * 12 for 12-bit sample values + * Only 8 and 12 are legal data precisions for lossy JPEG according to the + * JPEG standard, and the IJG code does not support anything else! + * We do not support run-time selection of data precision, sorry. + */ + +#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */ + + +/* + * Maximum number of components (color channels) allowed in JPEG image. + * To meet the letter of the JPEG spec, set this to 255. However, darn + * few applications need more than 4 channels (maybe 5 for CMYK + alpha + * mask). We recommend 10 as a reasonable compromise; use 4 if you are + * really short on memory. (Each allowed component costs a hundred or so + * bytes of storage, whether actually used in an image or not.) + */ + +#define MAX_COMPONENTS 10 /* maximum number of image components */ + + +/* + * Basic data types. + * You may need to change these if you have a machine with unusual data + * type sizes; for example, "char" not 8 bits, "short" not 16 bits, + * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits, + * but it had better be at least 16. + */ + +/* Representation of a single sample (pixel element value). + * We frequently allocate large arrays of these, so it's important to keep + * them small. But if you have memory to burn and access to char or short + * arrays is very slow on your hardware, you might want to change these. + */ + +#if BITS_IN_JSAMPLE == 8 +/* JSAMPLE should be the smallest type that will hold the values 0..255. + * You can use a signed char by having GETJSAMPLE mask it with 0xFF. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JSAMPLE; +#ifdef CHAR_IS_UNSIGNED +#define GETJSAMPLE(value) ((int) (value)) +#else +#define GETJSAMPLE(value) ((int) (value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + +#define MAXJSAMPLE 255 +#define CENTERJSAMPLE 128 + +#endif /* BITS_IN_JSAMPLE == 8 */ + + +#if BITS_IN_JSAMPLE == 12 +/* JSAMPLE should be the smallest type that will hold the values 0..4095. + * On nearly all machines "short" will do nicely. + */ + +typedef short JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#define MAXJSAMPLE 4095 +#define CENTERJSAMPLE 2048 + +#endif /* BITS_IN_JSAMPLE == 12 */ + + +/* Representation of a DCT frequency coefficient. + * This should be a signed value of at least 16 bits; "short" is usually OK. + * Again, we allocate large arrays of these, but you can change to int + * if you have memory to burn and "short" is really slow. + */ + +typedef short JCOEF; + + +/* Compressed datastreams are represented as arrays of JOCTET. + * These must be EXACTLY 8 bits wide, at least once they are written to + * external storage. Note that when using the stdio data source/destination + * managers, this is also the data type passed to fread/fwrite. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JOCTET; +#define GETJOCTET(value) (value) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JOCTET; +#ifdef CHAR_IS_UNSIGNED +#define GETJOCTET(value) (value) +#else +#define GETJOCTET(value) ((value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + + +/* These typedefs are used for various table entries and so forth. + * They must be at least as wide as specified; but making them too big + * won't cost a huge amount of memory, so we don't provide special + * extraction code like we did for JSAMPLE. (In other words, these + * typedefs live at a different point on the speed/space tradeoff curve.) + */ + +/* UINT8 must hold at least the values 0..255. */ + +#ifdef HAVE_UNSIGNED_CHAR +typedef unsigned char UINT8; +#else /* not HAVE_UNSIGNED_CHAR */ +#ifdef CHAR_IS_UNSIGNED +typedef char UINT8; +#else /* not CHAR_IS_UNSIGNED */ +typedef short UINT8; +#endif /* CHAR_IS_UNSIGNED */ +#endif /* HAVE_UNSIGNED_CHAR */ + +/* UINT16 must hold at least the values 0..65535. */ + +#ifdef HAVE_UNSIGNED_SHORT +typedef unsigned short UINT16; +#else /* not HAVE_UNSIGNED_SHORT */ +typedef unsigned int UINT16; +#endif /* HAVE_UNSIGNED_SHORT */ + +/* INT16 must hold at least the values -32768..32767. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */ +typedef short INT16; +#endif + +/* INT32 must hold at least signed 32-bit values. */ + +//#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */ +//typedef long INT32; +//#endif + +/* Datatype used for image dimensions. The JPEG standard only supports + * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore + * "unsigned int" is sufficient on all machines. However, if you need to + * handle larger images and you don't mind deviating from the spec, you + * can change this datatype. + */ + +typedef unsigned int JDIMENSION; + +#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */ + + +/* These macros are used in all function definitions and extern declarations. + * You could modify them if you need to change function linkage conventions; + * in particular, you'll need to do that to make the library a Windows DLL. + * Another application is to make all functions global for use with debuggers + * or code profilers that require it. + */ + +/* a function called through method pointers: */ +#define METHODDEF(type) static type +/* a function used only in its module: */ +#define LOCAL(type) static type +/* a function referenced thru EXTERNs: */ +#define GLOBAL(type) type +/* a reference to a GLOBAL function: */ +#define EXTERN(type) extern type + + +/* This macro is used to declare a "method", that is, a function pointer. + * We want to supply prototype parameters if the compiler can cope. + * Note that the arglist parameter must be parenthesized! + * Again, you can customize this if you need special linkage keywords. + */ + +#ifdef HAVE_PROTOTYPES +#define JMETHOD(type,methodname,arglist) type (*methodname) arglist +#else +#define JMETHOD(type,methodname,arglist) type (*methodname) () +#endif + + +/* Here is the pseudo-keyword for declaring pointers that must be "far" + * on 80x86 machines. Most of the specialized coding for 80x86 is handled + * by just saying "FAR *" where such a pointer is needed. In a few places + * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol. + */ + +#ifdef NEED_FAR_POINTERS +#define FAR far +#else +#define FAR +#endif + + +/* + * On a few systems, type jboolean and/or its values FALSE, TRUE may appear + * in standard header files. Or you may have conflicts with application- + * specific header files that you want to include together with these files. + * Defining HAVE_jboolean before including jpeglib.h should make it work. + */ + +#ifndef HAVE_jboolean +typedef int jboolean; +#endif +#ifndef FALSE /* in case these macros already exist */ +#define FALSE 0 /* values of jboolean */ +#endif +#ifndef TRUE +#define TRUE 1 +#endif + + +/* + * The remaining options affect code selection within the JPEG library, + * but they don't need to be visible to most applications using the library. + * To minimize application namespace pollution, the symbols won't be + * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined. + */ + +#ifdef JPEG_INTERNALS +#define JPEG_INTERNAL_OPTIONS +#endif + +#ifdef JPEG_INTERNAL_OPTIONS + + +/* + * These defines indicate whether to include various optional functions. + * Undefining some of these symbols will produce a smaller but less capable + * library. Note that you can leave certain source files out of the + * compilation/linking process if you've #undef'd the corresponding symbols. + * (You may HAVE to do that if your compiler doesn't like null source files.) + */ + +/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */ + +/* Capability options common to encoder and decoder: */ + +#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */ +#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */ +#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */ + +/* Encoder capability options: */ + +#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ +/* Note: if you selected 12-bit data precision, it is dangerous to turn off + * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit + * precision, so jchuff.c normally uses entropy optimization to compute + * usable tables for higher precision. If you don't want to do optimization, + * you'll have to supply different default Huffman tables. + * The exact same statements apply for progressive JPEG: the default tables + * don't work for progressive mode. (This may get fixed, however.) + */ +#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */ + +/* Decoder capability options: */ + +#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ +#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ +#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */ +#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ +#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */ +#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */ +#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */ + +/* more capability options later, no doubt */ + + +/* + * Ordering of RGB data in scanlines passed to or from the application. + * If your application wants to deal with data in the order B,G,R, just + * change these macros. You can also deal with formats such as R,G,B,X + * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing + * the offsets will also change the order in which colormap data is organized. + * RESTRICTIONS: + * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. + * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not + * useful if you are using JPEG color spaces other than YCbCr or grayscale. + * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE + * is not 3 (they don't understand about dummy color components!). So you + * can't use color quantization if you change that value. + */ + +#define RGB_RED 0 /* Offset of Red in an RGB scanline element */ +#define RGB_GREEN 1 /* Offset of Green */ +#define RGB_BLUE 2 /* Offset of Blue */ +#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */ + + +/* Definitions for speed-related optimizations. */ + + +/* If your compiler supports inline functions, define INLINE + * as the inline keyword; otherwise define it as empty. + */ + +#ifndef INLINE +#ifdef __GNUC__ /* for instance, GNU C knows about inline */ +#define INLINE __inline__ +#endif +#ifndef INLINE +#define INLINE /* default is to define it as empty */ +#endif +#endif + + +/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying + * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER + * as short on such a machine. MULTIPLIER must be at least 16 bits wide. + */ + +#ifndef MULTIPLIER +#define MULTIPLIER int /* type for fastest integer multiply */ +#endif + + +/* FAST_FLOAT should be either float or double, whichever is done faster + * by your compiler. (Note that this type is only used in the floating point + * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.) + * Typically, float is faster in ANSI C compilers, while double is faster in + * pre-ANSI compilers (because they insist on converting to double anyway). + * The code below therefore chooses float if we have ANSI-style prototypes. + */ + +#ifndef FAST_FLOAT +#ifdef HAVE_PROTOTYPES +#define FAST_FLOAT float +#else +#define FAST_FLOAT double +#endif +#endif + +#endif /* JPEG_INTERNAL_OPTIONS */ diff --git a/winclude/jpegint.h b/winclude/jpegint.h new file mode 100755 index 000000000..4f37410e2 --- /dev/null +++ b/winclude/jpegint.h @@ -0,0 +1,392 @@ +/* + * jpegint.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides common declarations for the various JPEG modules. + * These declarations are considered internal to the JPEG library; most + * applications using the library shouldn't need to include this file. + */ + + +/* Declarations for both compression & decompression */ + +typedef enum { /* Operating modes for buffer controllers */ + JBUF_PASS_THRU, /* Plain stripwise operation */ + /* Remaining modes require a full-image buffer to have been created */ + JBUF_SAVE_SOURCE, /* Run source subobject only, save output */ + JBUF_CRANK_DEST, /* Run dest subobject only, using saved data */ + JBUF_SAVE_AND_PASS /* Run both subobjects, save output */ +} J_BUF_MODE; + +/* Values of global_state field (jdapi.c has some dependencies on ordering!) */ +#define CSTATE_START 100 /* after create_compress */ +#define CSTATE_SCANNING 101 /* start_compress done, write_scanlines OK */ +#define CSTATE_RAW_OK 102 /* start_compress done, write_raw_data OK */ +#define CSTATE_WRCOEFS 103 /* jpeg_write_coefficients done */ +#define DSTATE_START 200 /* after create_decompress */ +#define DSTATE_INHEADER 201 /* reading header markers, no SOS yet */ +#define DSTATE_READY 202 /* found SOS, ready for start_decompress */ +#define DSTATE_PRELOAD 203 /* reading multiscan file in start_decompress*/ +#define DSTATE_PRESCAN 204 /* performing dummy pass for 2-pass quant */ +#define DSTATE_SCANNING 205 /* start_decompress done, read_scanlines OK */ +#define DSTATE_RAW_OK 206 /* start_decompress done, read_raw_data OK */ +#define DSTATE_BUFIMAGE 207 /* expecting jpeg_start_output */ +#define DSTATE_BUFPOST 208 /* looking for SOS/EOI in jpeg_finish_output */ +#define DSTATE_RDCOEFS 209 /* reading file in jpeg_read_coefficients */ +#define DSTATE_STOPPING 210 /* looking for EOI in jpeg_finish_decompress */ + + +/* Declarations for compression modules */ + +/* Master control module */ +struct jpeg_comp_master { + JMETHOD(void, prepare_for_pass, (j_compress_ptr cinfo)); + JMETHOD(void, pass_startup, (j_compress_ptr cinfo)); + JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); + + /* State variables made visible to other modules */ + jboolean call_pass_startup; /* True if pass_startup must be called */ + jboolean is_last_pass; /* True during last pass */ +}; + +/* Main buffer control (downsampled-data buffer) */ +struct jpeg_c_main_controller { + JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, process_data, (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail)); +}; + +/* Compression preprocessing (downsampling input buffer control) */ +struct jpeg_c_prep_controller { + JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, pre_process_data, (j_compress_ptr cinfo, + JSAMPARRAY input_buf, + JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail, + JSAMPIMAGE output_buf, + JDIMENSION *out_row_group_ctr, + JDIMENSION out_row_groups_avail)); +}; + +/* Coefficient buffer control */ +struct jpeg_c_coef_controller { + JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(jboolean, compress_data, (j_compress_ptr cinfo, + JSAMPIMAGE input_buf)); +}; + +/* Colorspace conversion */ +struct jpeg_color_converter { + JMETHOD(void, start_pass, (j_compress_ptr cinfo)); + JMETHOD(void, color_convert, (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows)); +}; + +/* Downsampling */ +struct jpeg_downsampler { + JMETHOD(void, start_pass, (j_compress_ptr cinfo)); + JMETHOD(void, downsample, (j_compress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION in_row_index, + JSAMPIMAGE output_buf, + JDIMENSION out_row_group_index)); + + jboolean need_context_rows; /* TRUE if need rows above & below */ +}; + +/* Forward DCT (also controls coefficient quantization) */ +struct jpeg_forward_dct { + JMETHOD(void, start_pass, (j_compress_ptr cinfo)); + /* perhaps this should be an array??? */ + JMETHOD(void, forward_DCT, (j_compress_ptr cinfo, + jpeg_component_info * compptr, + JSAMPARRAY sample_data, JBLOCKROW coef_blocks, + JDIMENSION start_row, JDIMENSION start_col, + JDIMENSION num_blocks)); +}; + +/* Entropy encoding */ +struct jpeg_entropy_encoder { + JMETHOD(void, start_pass, (j_compress_ptr cinfo, jboolean gather_statistics)); + JMETHOD(jboolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data)); + JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); +}; + +/* Marker writing */ +struct jpeg_marker_writer { + JMETHOD(void, write_file_header, (j_compress_ptr cinfo)); + JMETHOD(void, write_frame_header, (j_compress_ptr cinfo)); + JMETHOD(void, write_scan_header, (j_compress_ptr cinfo)); + JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo)); + JMETHOD(void, write_tables_only, (j_compress_ptr cinfo)); + /* These routines are exported to allow insertion of extra markers */ + /* Probably only COM and APPn markers should be written this way */ + JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker, + unsigned int datalen)); + JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val)); +}; + + +/* Declarations for decompression modules */ + +/* Master control module */ +struct jpeg_decomp_master { + JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo)); + + /* State variables made visible to other modules */ + jboolean is_dummy_pass; /* True during 1st pass for 2-pass quant */ +}; + +/* Input control module */ +struct jpeg_input_controller { + JMETHOD(int, consume_input, (j_decompress_ptr cinfo)); + JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo)); + JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo)); + + /* State variables made visible to other modules */ + jboolean has_multiple_scans; /* True if file has multiple scans */ + jboolean eoi_reached; /* True when EOI has been consumed */ +}; + +/* Main buffer control (downsampled-data buffer) */ +struct jpeg_d_main_controller { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, process_data, (j_decompress_ptr cinfo, + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +}; + +/* Coefficient buffer control */ +struct jpeg_d_coef_controller { + JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); + JMETHOD(int, consume_data, (j_decompress_ptr cinfo)); + JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo)); + JMETHOD(int, decompress_data, (j_decompress_ptr cinfo, + JSAMPIMAGE output_buf)); + /* Pointer to array of coefficient virtual arrays, or NULL if none */ + jvirt_barray_ptr *coef_arrays; +}; + +/* Decompression postprocessing (color quantization buffer control) */ +struct jpeg_d_post_controller { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, post_process_data, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, + JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); +}; + +/* Marker reading & parsing */ +struct jpeg_marker_reader { + JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo)); + /* Read markers until SOS or EOI. + * Returns same codes as are defined for jpeg_consume_input: + * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. + */ + JMETHOD(int, read_markers, (j_decompress_ptr cinfo)); + /* Read a restart marker --- exported for use by entropy decoder only */ + jpeg_marker_parser_method read_restart_marker; + + /* State of marker reader --- nominally internal, but applications + * supplying COM or APPn handlers might like to know the state. + */ + jboolean saw_SOI; /* found SOI? */ + jboolean saw_SOF; /* found SOF? */ + int next_restart_num; /* next restart number expected (0-7) */ + unsigned int discarded_bytes; /* # of bytes skipped looking for a marker */ +}; + +/* Entropy decoding */ +struct jpeg_entropy_decoder { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + JMETHOD(jboolean, decode_mcu, (j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); + + /* This is here to share code between baseline and progressive decoders; */ + /* other modules probably should not use it */ + jboolean insufficient_data; /* set TRUE after emitting warning */ +}; + +/* Inverse DCT (also performs dequantization) */ +typedef JMETHOD(void, inverse_DCT_method_ptr, + (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col)); + +struct jpeg_inverse_dct { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + /* It is useful to allow each component to have a separate IDCT method. */ + inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS]; +}; + +/* Upsampling (note that upsampler must also call color converter) */ +struct jpeg_upsampler { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, upsample, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, + JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); + + jboolean need_context_rows; /* TRUE if need rows above & below */ +}; + +/* Colorspace conversion */ +struct jpeg_color_deconverter { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, color_convert, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows)); +}; + +/* Color quantization or color precision reduction */ +struct jpeg_color_quantizer { + JMETHOD(void, start_pass, (j_decompress_ptr cinfo, jboolean is_pre_scan)); + JMETHOD(void, color_quantize, (j_decompress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPARRAY output_buf, + int num_rows)); + JMETHOD(void, finish_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, new_color_map, (j_decompress_ptr cinfo)); +}; + + +/* Miscellaneous useful macros */ + +#undef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#undef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + + +/* We assume that right shift corresponds to signed division by 2 with + * rounding towards minus infinity. This is correct for typical "arithmetic + * shift" instructions that shift in copies of the sign bit. But some + * C compilers implement >> with an unsigned shift. For these machines you + * must define RIGHT_SHIFT_IS_UNSIGNED. + * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity. + * It is only applied with constant shift counts. SHIFT_TEMPS must be + * included in the variables of any routine using RIGHT_SHIFT. + */ + +#ifdef RIGHT_SHIFT_IS_UNSIGNED +#define SHIFT_TEMPS INT32 shift_temp; +#define RIGHT_SHIFT(x,shft) \ + ((shift_temp = (x)) < 0 ? \ + (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \ + (shift_temp >> (shft))) +#else +#define SHIFT_TEMPS +#define RIGHT_SHIFT(x,shft) ((x) >> (shft)) +#endif + + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jinit_compress_master jICompress +#define jinit_c_master_control jICMaster +#define jinit_c_main_controller jICMainC +#define jinit_c_prep_controller jICPrepC +#define jinit_c_coef_controller jICCoefC +#define jinit_color_converter jICColor +#define jinit_downsampler jIDownsampler +#define jinit_forward_dct jIFDCT +#define jinit_huff_encoder jIHEncoder +#define jinit_phuff_encoder jIPHEncoder +#define jinit_marker_writer jIMWriter +#define jinit_master_decompress jIDMaster +#define jinit_d_main_controller jIDMainC +#define jinit_d_coef_controller jIDCoefC +#define jinit_d_post_controller jIDPostC +#define jinit_input_controller jIInCtlr +#define jinit_marker_reader jIMReader +#define jinit_huff_decoder jIHDecoder +#define jinit_phuff_decoder jIPHDecoder +#define jinit_inverse_dct jIIDCT +#define jinit_upsampler jIUpsampler +#define jinit_color_deconverter jIDColor +#define jinit_1pass_quantizer jI1Quant +#define jinit_2pass_quantizer jI2Quant +#define jinit_merged_upsampler jIMUpsampler +#define jinit_memory_mgr jIMemMgr +#define jdiv_round_up jDivRound +#define jround_up jRound +#define jcopy_sample_rows jCopySamples +#define jcopy_block_row jCopyBlocks +#define jzero_far jZeroFar +#define jpeg_zigzag_order jZIGTable +#define jpeg_natural_order jZAGTable +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Compression module initialization routines */ +EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo, + jboolean transcode_only)); +EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo, + jboolean need_full_buffer)); +EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo, + jboolean need_full_buffer)); +EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo, + jboolean need_full_buffer)); +EXTERN(void) jinit_color_converter JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_phuff_encoder JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo)); +/* Decompression module initialization routines */ +EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo, + jboolean need_full_buffer)); +EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo, + jboolean need_full_buffer)); +EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo, + jboolean need_full_buffer)); +EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_phuff_decoder JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_upsampler JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_2pass_quantizer JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_merged_upsampler JPP((j_decompress_ptr cinfo)); +/* Memory manager initialization */ +EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo)); + +/* Utility routines in jutils.c */ +EXTERN(long) jdiv_round_up JPP((long a, long b)); +EXTERN(long) jround_up JPP((long a, long b)); +EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row, + JSAMPARRAY output_array, int dest_row, + int num_rows, JDIMENSION num_cols)); +EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row, + JDIMENSION num_blocks)); +EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero)); +/* Constant tables in jutils.c */ +#if 0 /* This table is not actually needed in v6a */ +extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */ +#endif +extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */ + +/* Suppress undefined-structure complaints if necessary. */ + +#ifdef INCOMPLETE_TYPES_BROKEN +#ifndef AM_MEMORY_MANAGER /* only jmemmgr.c defines these */ +struct jvirt_sarray_control { long dummy; }; +struct jvirt_barray_control { long dummy; }; +#endif +#endif /* INCOMPLETE_TYPES_BROKEN */ diff --git a/winclude/jpeglib.h b/winclude/jpeglib.h new file mode 100755 index 000000000..9a06b5d07 --- /dev/null +++ b/winclude/jpeglib.h @@ -0,0 +1,1096 @@ +/* + * jpeglib.h + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the application interface for the JPEG library. + * Most applications using the library need only include this file, + * and perhaps jerror.h if they want to know the exact error codes. + */ + +#ifndef JPEGLIB_H +#define JPEGLIB_H + +/* + * First we include the configuration files that record how this + * installation of the JPEG library is set up. jconfig.h can be + * generated automatically for many systems. jmorecfg.h contains + * manual configuration options that most people need not worry about. + */ + +#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */ +#include "jconfig.h" /* widely used configuration options */ +#endif +#include "jmorecfg.h" /* seldom changed options */ + + +/* Version ID for the JPEG library. + * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60". + */ + +#define JPEG_LIB_VERSION 62 /* Version 6b */ + + +/* Various constants determining the sizes of things. + * All of these are specified by the JPEG standard, so don't change them + * if you want to be compatible. + */ + +#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */ +#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */ +#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */ +#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */ +#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */ +#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */ +#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */ +/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; + * the PostScript DCT filter can emit files with many more than 10 blocks/MCU. + * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU + * to handle it. We even let you do this from the jconfig.h file. However, + * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe + * sometimes emits noncompliant files doesn't mean you should too. + */ +#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */ +#ifndef D_MAX_BLOCKS_IN_MCU +#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */ +#endif + + +/* Data structures for images (arrays of samples and of DCT coefficients). + * On 80x86 machines, the image arrays are too big for near pointers, + * but the pointer arrays can fit in near memory. + */ + +typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */ +typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */ +typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */ + +typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */ +typedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */ +typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */ +typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */ + +typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */ + + +/* Types for JPEG compression parameters and working tables. */ + + +/* DCT coefficient quantization tables. */ + +typedef struct { + /* This array gives the coefficient quantizers in natural array order + * (not the zigzag order in which they are stored in a JPEG DQT marker). + * CAUTION: IJG versions prior to v6a kept this array in zigzag order. + */ + UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + jboolean sent_table; /* TRUE when table has been output */ +} JQUANT_TBL; + + +/* Huffman coding tables. */ + +typedef struct { + /* These two fields directly represent the contents of a JPEG DHT marker */ + UINT8 bits[17]; /* bits[k] = # of symbols with codes of */ + /* length k bits; bits[0] is unused */ + UINT8 huffval[256]; /* The symbols, in order of incr code length */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + jboolean sent_table; /* TRUE when table has been output */ +} JHUFF_TBL; + + +/* Basic info about one component (color channel). */ + +typedef struct { + /* These values are fixed over the whole image. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOF marker. */ + int component_id; /* identifier for this component (0..255) */ + int component_index; /* its index in SOF or cinfo->comp_info[] */ + int h_samp_factor; /* horizontal sampling factor (1..4) */ + int v_samp_factor; /* vertical sampling factor (1..4) */ + int quant_tbl_no; /* quantization table selector (0..3) */ + /* These values may vary between scans. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOS marker. */ + /* The decompressor output side may not use these variables. */ + int dc_tbl_no; /* DC entropy table selector (0..3) */ + int ac_tbl_no; /* AC entropy table selector (0..3) */ + + /* Remaining fields should be treated as private by applications. */ + + /* These values are computed during compression or decompression startup: */ + /* Component's size in DCT blocks. + * Any dummy blocks added to complete an MCU are not counted; therefore + * these values do not depend on whether a scan is interleaved or not. + */ + JDIMENSION width_in_blocks; + JDIMENSION height_in_blocks; + /* Size of a DCT block in samples. Always DCTSIZE for compression. + * For decompression this is the size of the output from one DCT block, + * reflecting any scaling we choose to apply during the IDCT step. + * Values of 1,2,4,8 are likely to be supported. Note that different + * components may receive different IDCT scalings. + */ + int DCT_scaled_size; + /* The downsampled dimensions are the component's actual, unpadded number + * of samples at the main buffer (preprocessing/compression interface), thus + * downsampled_width = ceil(image_width * Hi/Hmax) + * and similarly for height. For decompression, IDCT scaling is included, so + * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE) + */ + JDIMENSION downsampled_width; /* actual width in samples */ + JDIMENSION downsampled_height; /* actual height in samples */ + /* This flag is used only for decompression. In cases where some of the + * components will be ignored (eg grayscale output from YCbCr image), + * we can skip most computations for the unused components. + */ + jboolean component_needed; /* do we need the value of this component? */ + + /* These values are computed before starting a scan of the component. */ + /* The decompressor output side may not use these variables. */ + int MCU_width; /* number of blocks per MCU, horizontally */ + int MCU_height; /* number of blocks per MCU, vertically */ + int MCU_blocks; /* MCU_width * MCU_height */ + int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_scaled_size */ + int last_col_width; /* # of non-dummy blocks across in last MCU */ + int last_row_height; /* # of non-dummy blocks down in last MCU */ + + /* Saved quantization table for component; NULL if none yet saved. + * See jdinput.c comments about the need for this information. + * This field is currently used only for decompression. + */ + JQUANT_TBL * quant_table; + + /* Private per-component storage for DCT or IDCT subsystem. */ + void * dct_table; +} jpeg_component_info; + + +/* The script for encoding a multiple-scan file is an array of these: */ + +typedef struct { + int comps_in_scan; /* number of components encoded in this scan */ + int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */ + int Ss, Se; /* progressive JPEG spectral selection parms */ + int Ah, Al; /* progressive JPEG successive approx. parms */ +} jpeg_scan_info; + +/* The decompressor can save APPn and COM markers in a list of these: */ + +typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr; + +struct jpeg_marker_struct { + jpeg_saved_marker_ptr next; /* next in list, or NULL */ + UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */ + unsigned int original_length; /* # bytes of data in the file */ + unsigned int data_length; /* # bytes of data saved at data[] */ + JOCTET FAR * data; /* the data contained in the marker */ + /* the marker length word is not counted in data_length or original_length */ +}; + +/* Known color spaces. */ + +typedef enum { + JCS_UNKNOWN, /* error/unspecified */ + JCS_GRAYSCALE, /* monochrome */ + JCS_RGB, /* red/green/blue */ + JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ + JCS_CMYK, /* C/M/Y/K */ + JCS_YCCK /* Y/Cb/Cr/K */ +} J_COLOR_SPACE; + +/* DCT/IDCT algorithm options. */ + +typedef enum { + JDCT_ISLOW, /* slow but accurate integer algorithm */ + JDCT_IFAST, /* faster, less accurate integer method */ + JDCT_FLOAT /* floating-point: accurate, fast on fast HW */ +} J_DCT_METHOD; + +#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */ +#define JDCT_DEFAULT JDCT_ISLOW +#endif +#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */ +#define JDCT_FASTEST JDCT_IFAST +#endif + +/* Dithering options for decompression. */ + +typedef enum { + JDITHER_NONE, /* no dithering */ + JDITHER_ORDERED, /* simple ordered dither */ + JDITHER_FS /* Floyd-Steinberg error diffusion dither */ +} J_DITHER_MODE; + + +/* Common fields between JPEG compression and decompression master structs. */ + +#define jpeg_common_fields \ + struct jpeg_error_mgr * err; /* Error handler module */\ + struct jpeg_memory_mgr * mem; /* Memory manager module */\ + struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ + void * client_data; /* Available for use by application */\ + jboolean is_decompressor; /* So common code can tell which is which */\ + int global_state /* For checking call sequence validity */ + +/* Routines that are to be used by both halves of the library are declared + * to receive a pointer to this structure. There are no actual instances of + * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. + */ +struct jpeg_common_struct { + jpeg_common_fields; /* Fields common to both master struct types */ + /* Additional fields follow in an actual jpeg_compress_struct or + * jpeg_decompress_struct. All three structs must agree on these + * initial fields! (This would be a lot cleaner in C++.) + */ +}; + +typedef struct jpeg_common_struct * j_common_ptr; +typedef struct jpeg_compress_struct * j_compress_ptr; +typedef struct jpeg_decompress_struct * j_decompress_ptr; + + +/* Master record for a compression instance */ + +struct jpeg_compress_struct { + jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */ + + /* Destination for compressed data */ + struct jpeg_destination_mgr * dest; + + /* Description of source image --- these fields must be filled in by + * outer application before starting compression. in_color_space must + * be correct before you can even call jpeg_set_defaults(). + */ + + JDIMENSION image_width; /* input image width */ + JDIMENSION image_height; /* input image height */ + int input_components; /* # of color components in input image */ + J_COLOR_SPACE in_color_space; /* colorspace of input image */ + + double input_gamma; /* image gamma of input image */ + + /* Compression parameters --- these fields must be set before calling + * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to + * initialize everything to reasonable defaults, then changing anything + * the application specifically wants to change. That way you won't get + * burnt when new parameters are added. Also note that there are several + * helper routines to simplify changing parameters. + */ + + int data_precision; /* bits of precision in image data */ + + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + int num_scans; /* # of entries in scan_info array */ + const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */ + /* The default value of scan_info is NULL, which causes a single-scan + * sequential JPEG file to be emitted. To create a multi-scan file, + * set num_scans and scan_info to point to an array of scan definitions. + */ + + jboolean raw_data_in; /* TRUE=caller supplies downsampled data */ + jboolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + jboolean optimize_coding; /* TRUE=optimize entropy encoding parms */ + jboolean CCIR601_sampling; /* TRUE=first samples are cosited */ + int smoothing_factor; /* 1..100, or 0 for no input smoothing */ + J_DCT_METHOD dct_method; /* DCT algorithm selector */ + + /* The restart interval can be specified in absolute MCUs by setting + * restart_interval, or in MCU rows by setting restart_in_rows + * (in which case the correct restart_interval will be figured + * for each scan). + */ + unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ + int restart_in_rows; /* if > 0, MCU rows per restart interval */ + + /* Parameters controlling emission of special markers. */ + + jboolean write_JFIF_header; /* should a JFIF marker be written? */ + UINT8 JFIF_major_version; /* What to write for the JFIF version number */ + UINT8 JFIF_minor_version; + /* These three values are not used by the JPEG code, merely copied */ + /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ + /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ + /* ratio is defined by X_density/Y_density even when density_unit=0. */ + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + jboolean write_Adobe_marker; /* should an Adobe marker be written? */ + + /* State variable: index of next scanline to be written to + * jpeg_write_scanlines(). Application may use this to control its + * processing loop, e.g., "while (next_scanline < image_height)". + */ + + JDIMENSION next_scanline; /* 0 .. image_height-1 */ + + /* Remaining fields are known throughout compressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during compression startup + */ + jboolean progressive_mode; /* TRUE if scan script uses progressive mode */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */ + /* The coefficient controller receives data in units of MCU rows as defined + * for fully interleaved scans (whether the JPEG file is interleaved or not). + * There are v_samp_factor * DCTSIZE sample rows of each component in an + * "iMCU" (interleaved MCU) row. + */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[C_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* + * Links to compression subobjects (methods and private variables of modules) + */ + struct jpeg_comp_master * master; + struct jpeg_c_main_controller * main; + struct jpeg_c_prep_controller * prep; + struct jpeg_c_coef_controller * coef; + struct jpeg_marker_writer * marker; + struct jpeg_color_converter * cconvert; + struct jpeg_downsampler * downsample; + struct jpeg_forward_dct * fdct; + struct jpeg_entropy_encoder * entropy; + jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */ + int script_space_size; +}; + + +/* Master record for a decompression instance */ + +struct jpeg_decompress_struct { + jpeg_common_fields; /* Fields shared with jpeg_compress_struct */ + + /* Source of compressed data */ + struct jpeg_source_mgr * src; + + /* Basic description of image --- filled in by jpeg_read_header(). */ + /* Application may inspect these values to decide how to process image. */ + + JDIMENSION image_width; /* nominal image width (from SOF marker) */ + JDIMENSION image_height; /* nominal image height */ + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + /* Decompression processing parameters --- these fields must be set before + * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes + * them to default values. + */ + + J_COLOR_SPACE out_color_space; /* colorspace for output */ + + unsigned int scale_num, scale_denom; /* fraction by which to scale image */ + + double output_gamma; /* image gamma wanted in output */ + + jboolean buffered_image; /* TRUE=multiple output passes */ + jboolean raw_data_out; /* TRUE=downsampled data wanted */ + + J_DCT_METHOD dct_method; /* IDCT algorithm selector */ + jboolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */ + jboolean do_block_smoothing; /* TRUE=apply interblock smoothing */ + + jboolean quantize_colors; /* TRUE=colormapped output wanted */ + /* the following are ignored if not quantize_colors: */ + J_DITHER_MODE dither_mode; /* type of color dithering to use */ + jboolean two_pass_quantize; /* TRUE=use two-pass color quantization */ + int desired_number_of_colors; /* max # colors to use in created colormap */ + /* these are significant only in buffered-image mode: */ + jboolean enable_1pass_quant; /* enable future use of 1-pass quantizer */ + jboolean enable_external_quant;/* enable future use of external colormap */ + jboolean enable_2pass_quant; /* enable future use of 2-pass quantizer */ + + /* Description of actual output image that will be returned to application. + * These fields are computed by jpeg_start_decompress(). + * You can also use jpeg_calc_output_dimensions() to determine these values + * in advance of calling jpeg_start_decompress(). + */ + + JDIMENSION output_width; /* scaled image width */ + JDIMENSION output_height; /* scaled image height */ + int out_color_components; /* # of color components in out_color_space */ + int output_components; /* # of color components returned */ + /* output_components is 1 (a colormap index) when quantizing colors; + * otherwise it equals out_color_components. + */ + int rec_outbuf_height; /* min recommended height of scanline buffer */ + /* If the buffer passed to jpeg_read_scanlines() is less than this many rows + * high, space and time will be wasted due to unnecessary data copying. + * Usually rec_outbuf_height will be 1 or 2, at most 4. + */ + + /* When quantizing colors, the output colormap is described by these fields. + * The application can supply a colormap by setting colormap non-NULL before + * calling jpeg_start_decompress; otherwise a colormap is created during + * jpeg_start_decompress or jpeg_start_output. + * The map has out_color_components rows and actual_number_of_colors columns. + */ + int actual_number_of_colors; /* number of entries in use */ + JSAMPARRAY colormap; /* The color map as a 2-D pixel array */ + + /* State variables: these variables indicate the progress of decompression. + * The application may examine these but must not modify them. + */ + + /* Row index of next scanline to be read from jpeg_read_scanlines(). + * Application may use this to control its processing loop, e.g., + * "while (output_scanline < output_height)". + */ + JDIMENSION output_scanline; /* 0 .. output_height-1 */ + + /* Current input scan number and number of iMCU rows completed in scan. + * These indicate the progress of the decompressor input side. + */ + int input_scan_number; /* Number of SOS markers seen so far */ + JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */ + + /* The "output scan number" is the notional scan being displayed by the + * output side. The decompressor will not allow output scan/row number + * to get ahead of input scan/row, but it can fall arbitrarily far behind. + */ + int output_scan_number; /* Nominal scan number being displayed */ + JDIMENSION output_iMCU_row; /* Number of iMCU rows read */ + + /* Current progression status. coef_bits[c][i] indicates the precision + * with which component c's DCT coefficient i (in zigzag order) is known. + * It is -1 when no data has yet been received, otherwise it is the point + * transform (shift) value for the most recent scan of the coefficient + * (thus, 0 at completion of the progression). + * This pointer is NULL when reading a non-progressive file. + */ + int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */ + + /* Internal JPEG parameters --- the application usually need not look at + * these fields. Note that the decompressor output side may not use + * any parameters that can change between scans. + */ + + /* Quantization and Huffman tables are carried forward across input + * datastreams when processing abbreviated JPEG datastreams. + */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + /* These parameters are never carried across datastreams, since they + * are given in SOF/SOS markers or defined to be reset by SOI. + */ + + int data_precision; /* bits of precision in image data */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + jboolean progressive_mode; /* TRUE if SOFn specifies progressive mode */ + jboolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */ + + /* These fields record data obtained from optional markers recognized by + * the JPEG library. + */ + jboolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ + /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */ + UINT8 JFIF_major_version; /* JFIF version number */ + UINT8 JFIF_minor_version; + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + jboolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ + UINT8 Adobe_transform; /* Color transform code from Adobe marker */ + + jboolean CCIR601_sampling; /* TRUE=first samples are cosited */ + + /* Aside from the specific data retained from APPn markers known to the + * library, the uninterpreted contents of any or all APPn and COM markers + * can be saved in a list for examination by the application. + */ + jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */ + + /* Remaining fields are known throughout decompressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during decompression startup + */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ + /* The coefficient controller's input and output progress is measured in + * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows + * in fully interleaved JPEG scans, but are used whether the scan is + * interleaved or not. We define an iMCU row as v_samp_factor DCT block + * rows of each component. Therefore, the IDCT output contains + * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row. + */ + + JSAMPLE * sample_range_limit; /* table for fast range-limiting */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + * Note that the decompressor output side must not use these fields. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[D_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* This field is shared between entropy decoder and marker parser. + * It is either zero or the code of a JPEG marker that has been + * read from the data source, but has not yet been processed. + */ + int unread_marker; + + /* + * Links to decompression subobjects (methods, private variables of modules) + */ + struct jpeg_decomp_master * master; + struct jpeg_d_main_controller * main; + struct jpeg_d_coef_controller * coef; + struct jpeg_d_post_controller * post; + struct jpeg_input_controller * inputctl; + struct jpeg_marker_reader * marker; + struct jpeg_entropy_decoder * entropy; + struct jpeg_inverse_dct * idct; + struct jpeg_upsampler * upsample; + struct jpeg_color_deconverter * cconvert; + struct jpeg_color_quantizer * cquantize; +}; + + +/* "Object" declarations for JPEG modules that may be supplied or called + * directly by the surrounding application. + * As with all objects in the JPEG library, these structs only define the + * publicly visible methods and state variables of a module. Additional + * private fields may exist after the public ones. + */ + + +/* Error handler object */ + +struct jpeg_error_mgr { + /* Error exit handler: does not return to caller */ + JMETHOD(void, error_exit, (j_common_ptr cinfo)); + /* Conditionally emit a trace or warning message */ + JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level)); + /* Routine that actually outputs a trace or error message */ + JMETHOD(void, output_message, (j_common_ptr cinfo)); + /* Format a message string for the most recent JPEG error or message */ + JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer)); +#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ + /* Reset error state variables at start of a new image */ + JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo)); + + /* The message ID code and any parameters are saved here. + * A message can have one string parameter or up to 8 int parameters. + */ + int msg_code; +#define JMSG_STR_PARM_MAX 80 + union { + int i[8]; + char s[JMSG_STR_PARM_MAX]; + } msg_parm; + + /* Standard state variables for error facility */ + + int trace_level; /* max msg_level that will be displayed */ + + /* For recoverable corrupt-data errors, we emit a warning message, + * but keep going unless emit_message chooses to abort. emit_message + * should count warnings in num_warnings. The surrounding application + * can check for bad data by seeing if num_warnings is nonzero at the + * end of processing. + */ + long num_warnings; /* number of corrupt-data warnings */ + + /* These fields point to the table(s) of error message strings. + * An application can change the table pointer to switch to a different + * message list (typically, to change the language in which errors are + * reported). Some applications may wish to add additional error codes + * that will be handled by the JPEG library error mechanism; the second + * table pointer is used for this purpose. + * + * First table includes all errors generated by JPEG library itself. + * Error code 0 is reserved for a "no such error string" message. + */ + const char * const * jpeg_message_table; /* Library errors */ + int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */ + /* Second table can be added by application (see cjpeg/djpeg for example). + * It contains strings numbered first_addon_message..last_addon_message. + */ + const char * const * addon_message_table; /* Non-library errors */ + int first_addon_message; /* code for first string in addon table */ + int last_addon_message; /* code for last string in addon table */ +}; + + +/* Progress monitor object */ + +struct jpeg_progress_mgr { + JMETHOD(void, progress_monitor, (j_common_ptr cinfo)); + + long pass_counter; /* work units completed in this pass */ + long pass_limit; /* total number of work units in this pass */ + int completed_passes; /* passes completed so far */ + int total_passes; /* total number of passes expected */ +}; + + +/* Data destination object for compression */ + +struct jpeg_destination_mgr { + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + + JMETHOD(void, init_destination, (j_compress_ptr cinfo)); + JMETHOD(jboolean, empty_output_buffer, (j_compress_ptr cinfo)); + JMETHOD(void, term_destination, (j_compress_ptr cinfo)); +}; + + +/* Data source object for decompression */ + +struct jpeg_source_mgr { + const JOCTET * next_input_byte; /* => next byte to read from buffer */ + size_t bytes_in_buffer; /* # of bytes remaining in buffer */ + + JMETHOD(void, init_source, (j_decompress_ptr cinfo)); + JMETHOD(jboolean, fill_input_buffer, (j_decompress_ptr cinfo)); + JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes)); + JMETHOD(jboolean, resync_to_restart, (j_decompress_ptr cinfo, int desired)); + JMETHOD(void, term_source, (j_decompress_ptr cinfo)); +}; + + +/* Memory manager object. + * Allocates "small" objects (a few K total), "large" objects (tens of K), + * and "really big" objects (virtual arrays with backing store if needed). + * The memory manager does not allow individual objects to be freed; rather, + * each created object is assigned to a pool, and whole pools can be freed + * at once. This is faster and more convenient than remembering exactly what + * to free, especially where malloc()/free() are not too speedy. + * NB: alloc routines never return NULL. They exit to error_exit if not + * successful. + */ + +#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */ +#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */ +#define JPOOL_NUMPOOLS 2 + +typedef struct jvirt_sarray_control * jvirt_sarray_ptr; +typedef struct jvirt_barray_control * jvirt_barray_ptr; + + +struct jpeg_memory_mgr { + /* Method pointers */ + JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id, + JDIMENSION samplesperrow, + JDIMENSION numrows)); + JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id, + JDIMENSION blocksperrow, + JDIMENSION numrows)); + JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo, + int pool_id, + jboolean pre_zero, + JDIMENSION samplesperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo, + int pool_id, + jboolean pre_zero, + JDIMENSION blocksperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo)); + JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo, + jvirt_sarray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + jboolean writable)); + JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo, + jvirt_barray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + jboolean writable)); + JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id)); + JMETHOD(void, self_destruct, (j_common_ptr cinfo)); + + /* Limit on memory allocation for this JPEG object. (Note that this is + * merely advisory, not a guaranteed maximum; it only affects the space + * used for virtual-array buffers.) May be changed by outer application + * after creating the JPEG object. + */ + long max_memory_to_use; + + /* Maximum allocation request accepted by alloc_large. */ + long max_alloc_chunk; +}; + + +/* Routine signature for application-supplied marker processing methods. + * Need not pass marker code since it is stored in cinfo->unread_marker. + */ +typedef JMETHOD(jboolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); + + +/* Declarations for routines called by application. + * The JPP macro hides prototype parameters from compilers that can't cope. + * Note JPP requires double parentheses. + */ + +#ifdef HAVE_PROTOTYPES +#define JPP(arglist) arglist +#else +#define JPP(arglist) () +#endif + + +/* Short forms of external names for systems with brain-damaged linkers. + * We shorten external names to be unique in the first six letters, which + * is good enough for all known systems. + * (If your compiler itself needs names to be unique in less than 15 + * characters, you are out of luck. Get a better compiler.) + */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_std_error jStdError +#define jpeg_CreateCompress jCreaCompress +#define jpeg_CreateDecompress jCreaDecompress +#define jpeg_destroy_compress jDestCompress +#define jpeg_destroy_decompress jDestDecompress +#define jpeg_stdio_dest jStdDest +#define jpeg_stdio_src jStdSrc +#define jpeg_set_defaults jSetDefaults +#define jpeg_set_colorspace jSetColorspace +#define jpeg_default_colorspace jDefColorspace +#define jpeg_set_quality jSetQuality +#define jpeg_set_linear_quality jSetLQuality +#define jpeg_add_quant_table jAddQuantTable +#define jpeg_quality_scaling jQualityScaling +#define jpeg_simple_progression jSimProgress +#define jpeg_suppress_tables jSuppressTables +#define jpeg_alloc_quant_table jAlcQTable +#define jpeg_alloc_huff_table jAlcHTable +#define jpeg_start_compress jStrtCompress +#define jpeg_write_scanlines jWrtScanlines +#define jpeg_finish_compress jFinCompress +#define jpeg_write_raw_data jWrtRawData +#define jpeg_write_marker jWrtMarker +#define jpeg_write_m_header jWrtMHeader +#define jpeg_write_m_byte jWrtMByte +#define jpeg_write_tables jWrtTables +#define jpeg_read_header jReadHeader +#define jpeg_start_decompress jStrtDecompress +#define jpeg_read_scanlines jReadScanlines +#define jpeg_finish_decompress jFinDecompress +#define jpeg_read_raw_data jReadRawData +#define jpeg_has_multiple_scans jHasMultScn +#define jpeg_start_output jStrtOutput +#define jpeg_finish_output jFinOutput +#define jpeg_input_complete jInComplete +#define jpeg_new_colormap jNewCMap +#define jpeg_consume_input jConsumeInput +#define jpeg_calc_output_dimensions jCalcDimensions +#define jpeg_save_markers jSaveMarkers +#define jpeg_set_marker_processor jSetMarker +#define jpeg_read_coefficients jReadCoefs +#define jpeg_write_coefficients jWrtCoefs +#define jpeg_copy_critical_parameters jCopyCrit +#define jpeg_abort_compress jAbrtCompress +#define jpeg_abort_decompress jAbrtDecompress +#define jpeg_abort jAbort +#define jpeg_destroy jDestroy +#define jpeg_resync_to_restart jResyncRestart +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Default error-management setup */ +EXTERN(struct jpeg_error_mgr *) jpeg_std_error + JPP((struct jpeg_error_mgr * err)); + +/* Initialization of JPEG compression objects. + * jpeg_create_compress() and jpeg_create_decompress() are the exported + * names that applications should call. These expand to calls on + * jpeg_CreateCompress and jpeg_CreateDecompress with additional information + * passed for version mismatch checking. + * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx. + */ +#define jpeg_create_compress(cinfo) \ + jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_compress_struct)) +#define jpeg_create_decompress(cinfo) \ + jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_decompress_struct)) +EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo, + int version, size_t structsize)); +EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo, + int version, size_t structsize)); +/* Destruction of JPEG compression objects */ +EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); + +/* Standard data source and destination managers: stdio streams. */ +/* Caller is responsible for opening the file before and closing after. */ +EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); +EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile)); + +/* Default parameter setup for compression */ +EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo)); +/* Compression parameter setup aids */ +EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo, + J_COLOR_SPACE colorspace)); +EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality, + jboolean force_baseline)); +EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo, + int scale_factor, + jboolean force_baseline)); +EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl, + const unsigned int *basic_table, + int scale_factor, + jboolean force_baseline)); +EXTERN(int) jpeg_quality_scaling JPP((int quality)); +EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo, + jboolean suppress)); +EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo)); +EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo)); + +/* Main entry points for compression */ +EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo, + jboolean write_all_tables)); +EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION num_lines)); +EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo)); + +/* Replaces jpeg_write_scanlines when writing raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION num_lines)); + +/* Write a special marker. See libjpeg.doc concerning safe usage. */ +EXTERN(void) jpeg_write_marker + JPP((j_compress_ptr cinfo, int marker, + const JOCTET * dataptr, unsigned int datalen)); +/* Same, but piecemeal. */ +EXTERN(void) jpeg_write_m_header + JPP((j_compress_ptr cinfo, int marker, unsigned int datalen)); +EXTERN(void) jpeg_write_m_byte + JPP((j_compress_ptr cinfo, int val)); + +/* Alternate compression function: just write an abbreviated table file */ +EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo)); + +/* Decompression startup: read start of JPEG datastream to see what's there */ +EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo, + jboolean require_image)); +/* Return value is one of: */ +#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */ +#define JPEG_HEADER_OK 1 /* Found valid image datastream */ +#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */ +/* If you pass require_image = TRUE (normal case), you need not check for + * a TABLES_ONLY return code; an abbreviated file will cause an error exit. + * JPEG_SUSPENDED is only possible if you use a data source module that can + * give a suspension return (the stdio source module doesn't). + */ + +/* Main entry points for decompression */ +EXTERN(jboolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo)); +EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION max_lines)); +EXTERN(jboolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo)); + +/* Replaces jpeg_read_scanlines when reading raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION max_lines)); + +/* Additional entry points for buffered-image mode. */ +EXTERN(jboolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo)); +EXTERN(jboolean) jpeg_start_output JPP((j_decompress_ptr cinfo, + int scan_number)); +EXTERN(jboolean) jpeg_finish_output JPP((j_decompress_ptr cinfo)); +EXTERN(jboolean) jpeg_input_complete JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo)); +EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo)); +/* Return value is one of: */ +/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */ +#define JPEG_REACHED_SOS 1 /* Reached start of new scan */ +#define JPEG_REACHED_EOI 2 /* Reached end of image */ +#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */ +#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */ + +/* Precalculate output dimensions for current decompression parameters. */ +EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo)); + +/* Control saving of COM and APPn markers into marker_list. */ +EXTERN(void) jpeg_save_markers + JPP((j_decompress_ptr cinfo, int marker_code, + unsigned int length_limit)); + +/* Install a special processing method for COM or APPn markers. */ +EXTERN(void) jpeg_set_marker_processor + JPP((j_decompress_ptr cinfo, int marker_code, + jpeg_marker_parser_method routine)); + +/* Read or write raw DCT coefficients --- useful for lossless transcoding. */ +EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays)); +EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, + j_compress_ptr dstinfo)); + +/* If you choose to abort compression or decompression before completing + * jpeg_finish_(de)compress, then you need to clean up to release memory, + * temporary files, etc. You can just call jpeg_destroy_(de)compress + * if you're done with the JPEG object, but if you want to clean it up and + * reuse it, call this: + */ +EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo)); + +/* Generic versions of jpeg_abort and jpeg_destroy that work on either + * flavor of JPEG object. These may be more convenient in some places. + */ +EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo)); +EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo)); + +/* Default restart-marker-resync procedure for use by data source modules */ +EXTERN(jboolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, + int desired)); + + +/* These marker codes are exported since applications and data source modules + * are likely to want to use them. + */ + +#define JPEG_RST0 0xD0 /* RST0 marker code */ +#define JPEG_EOI 0xD9 /* EOI marker code */ +#define JPEG_APP0 0xE0 /* APP0 marker code */ +#define JPEG_COM 0xFE /* COM marker code */ + + +/* If we have a brain-damaged compiler that emits warnings (or worse, errors) + * for structure definitions that are never filled in, keep it quiet by + * supplying dummy definitions for the various substructures. + */ + +#ifdef INCOMPLETE_TYPES_BROKEN +#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */ +struct jvirt_sarray_control { long dummy; }; +struct jvirt_barray_control { long dummy; }; +struct jpeg_comp_master { long dummy; }; +struct jpeg_c_main_controller { long dummy; }; +struct jpeg_c_prep_controller { long dummy; }; +struct jpeg_c_coef_controller { long dummy; }; +struct jpeg_marker_writer { long dummy; }; +struct jpeg_color_converter { long dummy; }; +struct jpeg_downsampler { long dummy; }; +struct jpeg_forward_dct { long dummy; }; +struct jpeg_entropy_encoder { long dummy; }; +struct jpeg_decomp_master { long dummy; }; +struct jpeg_d_main_controller { long dummy; }; +struct jpeg_d_coef_controller { long dummy; }; +struct jpeg_d_post_controller { long dummy; }; +struct jpeg_input_controller { long dummy; }; +struct jpeg_marker_reader { long dummy; }; +struct jpeg_entropy_decoder { long dummy; }; +struct jpeg_inverse_dct { long dummy; }; +struct jpeg_upsampler { long dummy; }; +struct jpeg_color_deconverter { long dummy; }; +struct jpeg_color_quantizer { long dummy; }; +#endif /* JPEG_INTERNALS */ +#endif /* INCOMPLETE_TYPES_BROKEN */ + + +/* + * The JPEG library modules define JPEG_INTERNALS before including this file. + * The internal structure declarations are read only when that is true. + * Applications using the library should not include jpegint.h, but may wish + * to include jerror.h. + */ + +#ifdef JPEG_INTERNALS +#include "jpegint.h" /* fetch private declarations */ +#include "jerror.h" /* fetch error codes too */ +#endif + +#endif /* JPEGLIB_H */ diff --git a/winclude/jversion.h b/winclude/jversion.h new file mode 100755 index 000000000..6472c58d3 --- /dev/null +++ b/winclude/jversion.h @@ -0,0 +1,14 @@ +/* + * jversion.h + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains software version identification. + */ + + +#define JVERSION "6b 27-Mar-1998" + +#define JCOPYRIGHT "Copyright (C) 1998, Thomas G. Lane" diff --git a/winclude/lcms.h b/winclude/lcms.h new file mode 100755 index 000000000..c90a2b496 --- /dev/null +++ b/winclude/lcms.h @@ -0,0 +1,2052 @@ +// +// Little cms +// Copyright (C) 1998-2006 Marti Maria +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// Version 1.16 + +#ifndef __cms_H + +// ********** Configuration toggles **************************************** + +// Optimization mode. +// +// Note that USE_ASSEMBLER Is fastest by far, but it is limited to Pentium. +// USE_FLOAT are the generic floating-point routines. USE_C should work on +// virtually any machine. + +//#define USE_FLOAT 1 +// #define USE_C 1 +#define USE_ASSEMBLER 1 + +// Define this if you are using this package as a DLL (windows only) + +// #define LCMS_DLL 1 +// #define LCMS_DLL_BUILD 1 + +// Uncomment if you are trying the engine in a non-windows environment +// like linux, SGI, VAX, FreeBSD, BeOS, etc. +#define NON_WINDOWS 1 + +// Uncomment this one if you are using big endian machines (only meaningful +// when NON_WINDOWS is used) +// #define USE_BIG_ENDIAN 1 + +// Uncomment this one if your compiler/machine does support the +// "long long" type This will speedup fixed point math. (USE_C only) +#define USE_INT64 1 + +// Some machines does not have a reliable 'swab' function. Usually +// leave commented unless the testbed diagnoses the contrary. +// #define USE_CUSTOM_SWAB 1 + +// Uncomment this if your compiler supports inline +#define USE_INLINE 1 + +// Uncomment this if your compiler doesn't work with fast floor function +// #define USE_DEFAULT_FLOOR_CONVERSION 1 + +// Uncomment this line on multithreading environments +// #define USE_PTHREADS 1 + +// Uncomment this line if you want lcms to use the black point tag in profile, +// if commented, lcms will compute the black point by its own. +// It is safer to leve it commented out +// #define HONOR_BLACK_POINT_TAG 1 + +// ********** End of configuration toggles ****************************** + +#define LCMS_VERSION 116 + +// Microsoft VisualC++ + +// Deal with Microsoft's attempt at deprecating C standard runtime functions + +#ifdef _MSC_VER +# undef NON_WINDOWS +# if (_MSC_VER >= 1400) +# define _CRT_SECURE_NO_DEPRECATE 1 +# endif +#endif + +// Borland C + +#ifdef __BORLANDC__ +# undef NON_WINDOWS +#endif + + +#include +#include +#include +#include +#include +#include + +// Metroworks CodeWarrior +#ifdef __MWERKS__ +# define unlink remove +# if WIN32 +# define USE_CUSTOM_SWAB 1 +# undef NON_WINDOWS +# else +# define NON_WINDOWS 1 +# endif +#endif + + +// Here comes the Non-Windows settings + +#ifdef NON_WINDOWS + +// Non windows environments. Also avoid indentation on includes. + +#ifdef USE_PTHREADS +# include +typedef pthread_rwlock_t LCMS_RWLOCK_T; +# define LCMS_CREATE_LOCK(x) pthread_rwlock_init((x), NULL) +# define LCMS_FREE_LOCK(x) pthread_rwlock_destroy((x)) +# define LCMS_READ_LOCK(x) pthread_rwlock_rdlock((x)) +# define LCMS_WRITE_LOCK(x) pthread_rwlock_wrlock((x)) +# define LCMS_UNLOCK(x) pthread_rwlock_unlock((x)) +#endif + +#undef LCMS_DLL + +#ifdef USE_ASSEMBLER +# undef USE_ASSEMBLER +# define USE_C 1 +#endif + +#ifdef _HOST_BIG_ENDIAN +# define USE_BIG_ENDIAN 1 +#endif + +#if defined(__sgi__) || defined(__sgi) || defined(__powerpc__) || defined(sparc) || defined(__ppc__) +# define USE_BIG_ENDIAN 1 +#endif + +#if TARGET_CPU_PPC +# define USE_BIG_ENDIAN 1 +#endif + +#if macintosh +# ifndef __LITTLE_ENDIAN__ +# define USE_BIG_ENDIAN 1 +# endif +#endif + +#if __BIG_ENDIAN__ +# define USE_BIG_ENDIAN 1 +#endif + +#ifdef WORDS_BIGENDIAN +# define USE_BIG_ENDIAN 1 +#endif + +#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) +# include +# define USE_INT64 1 +# define LCMSSLONGLONG int64_t +# define LCMSULONGLONG u_int64_t +#endif + +#ifdef USE_INT64 +# ifndef LCMSULONGLONG +# define LCMSULONGLONG unsigned long long +# define LCMSSLONGLONG long long +# endif +#endif + +#if !defined(__INTEGRITY) +# include +#endif + +#include + +#if defined(__GNUC__) || defined(__FreeBSD__) +# include +#endif + +#ifndef LCMS_WIN_TYPES_ALREADY_DEFINED + +typedef unsigned char BYTE, *LPBYTE; +typedef unsigned short WORD, *LPWORD; +typedef unsigned long DWORD, *LPDWORD; +typedef int BOOL; +typedef char *LPSTR; +typedef void *LPVOID; +typedef void* LCMSHANDLE; + + +#define ZeroMemory(p,l) memset((p),0,(l)) +#define CopyMemory(d,s,l) memcpy((d),(s),(l)) +#define FAR + +#ifndef stricmp +# define stricmp strcasecmp +#endif + + +#ifndef FALSE +# define FALSE 0 +#endif +#ifndef TRUE +# define TRUE 1 +#endif + +#define LOWORD(l) ((WORD)(l)) +#define HIWORD(l) ((WORD)((DWORD)(l) >> 16)) + +#ifndef MAX_PATH +# define MAX_PATH (256) +#endif + +#define cdecl +#endif + +// The specification for "inline" is section 6.7.4 of the C99 standard (ISO/IEC 9899:1999). + +#define LCMS_INLINE static inline + +#else + +// Win32 stuff + +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif + +#include + +typedef HANDLE LCMSHANDLE; + + +#ifdef USE_INT64 +# ifndef LCMSULONGLONG +# define LCMSULONGLONG unsigned __int64 +# define LCMSSLONGLONG __int64 +# endif +#endif + +// This works for both VC & BorlandC +#define LCMS_INLINE __inline + +#ifdef USE_PTHREADS +typedef CRITICAL_SECTION LCMS_RWLOCK_T; +# define LCMS_CREATE_LOCK(x) InitializeCriticalSection((x)) +# define LCMS_FREE_LOCK(x) DeleteCriticalSection((x)) +# define LCMS_READ_LOCK(x) EnterCriticalSection((x)) +# define LCMS_WRITE_LOCK(x) EnterCriticalSection((x)) +# define LCMS_UNLOCK(x) LeaveCriticalSection((x)) +#endif + +#endif + +#ifndef USE_PTHREADS +typedef int LCMS_RWLOCK_T; +# define LCMS_CREATE_LOCK(x) +# define LCMS_FREE_LOCK(x) +# define LCMS_READ_LOCK(x) +# define LCMS_WRITE_LOCK(x) +# define LCMS_UNLOCK(x) +#endif + + +#include "icc34.h" // ICC header file + + +// Some tag & type additions + +#define lcmsSignature ((icSignature) 0x6c636d73L) + +#define icSigLuvKData ((icColorSpaceSignature) 0x4C75764BL) // 'LuvK' + +#define icSigHexachromeData ((icColorSpaceSignature) 0x4d434836L) // MCH6 +#define icSigHeptachromeData ((icColorSpaceSignature) 0x4d434837L) // MCH7 +#define icSigOctachromeData ((icColorSpaceSignature) 0x4d434838L) // MCH8 + +#define icSigMCH5Data ((icColorSpaceSignature) 0x4d434835L) // MCH5 +#define icSigMCH6Data ((icColorSpaceSignature) 0x4d434836L) // MCH6 +#define icSigMCH7Data ((icColorSpaceSignature) 0x4d434837L) // MCH7 +#define icSigMCH8Data ((icColorSpaceSignature) 0x4d434838L) // MCH8 +#define icSigMCH9Data ((icColorSpaceSignature) 0x4d434839L) // MCH9 +#define icSigMCHAData ((icColorSpaceSignature) 0x4d434841L) // MCHA +#define icSigMCHBData ((icColorSpaceSignature) 0x4d434842L) // MCHB +#define icSigMCHCData ((icColorSpaceSignature) 0x4d434843L) // MCHC +#define icSigMCHDData ((icColorSpaceSignature) 0x4d434844L) // MCHD +#define icSigMCHEData ((icColorSpaceSignature) 0x4d434845L) // MCHE +#define icSigMCHFData ((icColorSpaceSignature) 0x4d434846L) // MCHF + +#define icSigCAM97JABData ((icColorSpaceSignature) 0x4A616231L) // 'Jab1' H. Zeng +#define icSigCAM02JABData ((icColorSpaceSignature) 0x4A616232L) // 'Jab2' H. Zeng +#define icSigCAM02JCHData ((icColorSpaceSignature) 0x4A636A32L) // 'Jch2' H. Zeng + +#define icSigChromaticityTag ((icTagSignature) 0x6368726dL) // As per Addendum 2 to Spec. ICC.1:1998-09 +#define icSigChromaticAdaptationTag ((icTagSignature) 0x63686164L) // 'chad' +#define icSigColorantTableTag ((icTagSignature) 0x636c7274L) // 'clrt' +#define icSigColorantTableOutTag ((icTagSignature) 0x636c6f74L) // 'clot' +#define icSigHPGamutDescTag ((icTagSignature) 0x676D7441L) // 'gmtA' H. Zeng + + +#define icSigParametricCurveType ((icTagTypeSignature) 0x70617261L) // parametric (ICC 4.0) +#define icSigMultiLocalizedUnicodeType ((icTagTypeSignature) 0x6D6C7563L) +#define icSigS15Fixed16ArrayType ((icTagTypeSignature) 0x73663332L) +#define icSigChromaticityType ((icTagTypeSignature) 0x6368726dL) +#define icSiglutAtoBType ((icTagTypeSignature) 0x6d414220L) // mAB +#define icSiglutBtoAType ((icTagTypeSignature) 0x6d424120L) // mBA +#define icSigColorantTableType ((icTagTypeSignature) 0x636c7274L) // clrt +#define icSigHPGamutDescType ((icTagTypeSignature) 0x676D7441L) // gmtA H. Zeng + + +typedef struct { + icUInt8Number gridPoints[16]; // Number of grid points in each dimension. + icUInt8Number prec; // Precision of data elements in bytes. + icUInt8Number pad1; + icUInt8Number pad2; + icUInt8Number pad3; + /*icUInt8Number data[icAny]; Data follows see spec for size */ +} icCLutStruct; + +// icLutAtoB +typedef struct { + icUInt8Number inputChan; // Number of input channels + icUInt8Number outputChan; // Number of output channels + icUInt8Number pad1; + icUInt8Number pad2; + icUInt32Number offsetB; // Offset to first "B" curve + icUInt32Number offsetMat; // Offset to matrix + icUInt32Number offsetM; // Offset to first "M" curve + icUInt32Number offsetC; // Offset to CLUT + icUInt32Number offsetA; // Offset to first "A" curve + /*icUInt8Number data[icAny]; Data follows see spec for size */ +} icLutAtoB; + +// icLutBtoA +typedef struct { + icUInt8Number inputChan; // Number of input channels + icUInt8Number outputChan; // Number of output channels + icUInt8Number pad1; + icUInt8Number pad2; + icUInt32Number offsetB; // Offset to first "B" curve + icUInt32Number offsetMat; // Offset to matrix + icUInt32Number offsetM; // Offset to first "M" curve + icUInt32Number offsetC; // Offset to CLUT + icUInt32Number offsetA; // Offset to first "A" curve + /*icUInt8Number data[icAny]; Data follows see spec for size */ +} icLutBtoA; + + + + + +#ifdef __cplusplus +extern "C" { +#endif + +// Calling convention + +#ifdef NON_WINDOWS +# define LCMSEXPORT +# define LCMSAPI +#else +# ifdef LCMS_DLL +# ifdef __BORLANDC__ +# define LCMSEXPORT __stdcall _export +# define LCMSAPI +# else + // VC++ +# define LCMSEXPORT _stdcall +# ifdef LCMS_DLL_BUILD +# define LCMSAPI __declspec(dllexport) +# else +# define LCMSAPI __declspec(dllimport) +# endif +# endif +# else +# define LCMSEXPORT cdecl +# define LCMSAPI +# endif +#endif + +#ifdef USE_ASSEMBLER +#ifdef __BORLANDC__ + +# define ASM asm +# define RET(v) return(v) +#else + // VC++ +# define ASM __asm +# define RET(v) return +#endif +#endif + +#ifdef _MSC_VER +#ifndef stricmp +# define stricmp _stricmp +#endif +#ifndef unlink +# define unlink _unlink +#endif +#ifndef swab +# define swab _swab +#endif +#ifndef itoa +# define itoa _itoa +#endif +#ifndef filelength +# define filelength _filelength +#endif +#ifndef fileno +# define fileno _fileno +#endif +#ifndef strupr +# define strupr _strupr +#endif +#ifndef hypot +# define hypot _hypot +#endif +#endif + + +#ifndef M_PI +# define M_PI 3.14159265358979323846 +#endif + +#ifndef LOGE +# define LOGE 0.4342944819 +#endif + +// ********** Little cms API *************************************************** + +typedef LCMSHANDLE cmsHPROFILE; // Opaque typedefs to hide internals +typedef LCMSHANDLE cmsHTRANSFORM; + +#define MAXCHANNELS 16 // Maximum number of channels + +// Format of pixel is defined by one DWORD, using bit fields as follows +// +// TTTTT U Y F P X S EEE CCCC BBB +// +// T: Pixeltype +// F: Flavor 0=MinIsBlack(Chocolate) 1=MinIsWhite(Vanilla) +// P: Planar? 0=Chunky, 1=Planar +// X: swap 16 bps endianess? +// S: Do swap? ie, BGR, KYMC +// E: Extra samples +// C: Channels (Samples per pixel) +// B: Bytes per sample +// Y: Swap first - changes ABGR to BGRA and KCMY to CMYK + + +#define COLORSPACE_SH(s) ((s) << 16) +#define SWAPFIRST_SH(s) ((s) << 14) +#define FLAVOR_SH(s) ((s) << 13) +#define PLANAR_SH(p) ((p) << 12) +#define ENDIAN16_SH(e) ((e) << 11) +#define DOSWAP_SH(e) ((e) << 10) +#define EXTRA_SH(e) ((e) << 7) +#define CHANNELS_SH(c) ((c) << 3) +#define BYTES_SH(b) (b) + +// Pixel types + +#define PT_ANY 0 // Don't check colorspace + // 1 & 2 are reserved +#define PT_GRAY 3 +#define PT_RGB 4 +#define PT_CMY 5 +#define PT_CMYK 6 +#define PT_YCbCr 7 +#define PT_YUV 8 // Lu'v' +#define PT_XYZ 9 +#define PT_Lab 10 +#define PT_YUVK 11 // Lu'v'K +#define PT_HSV 12 +#define PT_HLS 13 +#define PT_Yxy 14 +#define PT_HiFi 15 +#define PT_HiFi7 16 +#define PT_HiFi8 17 +#define PT_HiFi9 18 +#define PT_HiFi10 19 +#define PT_HiFi11 20 +#define PT_HiFi12 21 +#define PT_HiFi13 22 +#define PT_HiFi14 23 +#define PT_HiFi15 24 + +#define NOCOLORSPACECHECK(x) ((x) & 0xFFFF) + +// Some (not all!) representations + +#ifndef TYPE_RGB_8 // TYPE_RGB_8 is a very common identifier, so don't include ours + // if user has it already defined. + +#define TYPE_GRAY_8 (COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(1)) +#define TYPE_GRAY_8_REV (COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1)) +#define TYPE_GRAY_16 (COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(2)) +#define TYPE_GRAY_16_REV (COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1)) +#define TYPE_GRAY_16_SE (COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_GRAYA_8 (COLORSPACE_SH(PT_GRAY)|EXTRA_SH(1)|CHANNELS_SH(1)|BYTES_SH(1)) +#define TYPE_GRAYA_16 (COLORSPACE_SH(PT_GRAY)|EXTRA_SH(1)|CHANNELS_SH(1)|BYTES_SH(2)) +#define TYPE_GRAYA_16_SE (COLORSPACE_SH(PT_GRAY)|EXTRA_SH(1)|CHANNELS_SH(1)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_GRAYA_8_PLANAR (COLORSPACE_SH(PT_GRAY)|EXTRA_SH(1)|CHANNELS_SH(1)|BYTES_SH(1)|PLANAR_SH(1)) +#define TYPE_GRAYA_16_PLANAR (COLORSPACE_SH(PT_GRAY)|EXTRA_SH(1)|CHANNELS_SH(1)|BYTES_SH(2)|PLANAR_SH(1)) + +#define TYPE_RGB_8 (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(1)) +#define TYPE_RGB_8_PLANAR (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(1)|PLANAR_SH(1)) +#define TYPE_BGR_8 (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)) +#define TYPE_BGR_8_PLANAR (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|PLANAR_SH(1)) +#define TYPE_RGB_16 (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_RGB_16_PLANAR (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2)|PLANAR_SH(1)) +#define TYPE_RGB_16_SE (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_BGR_16 (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_BGR_16_PLANAR (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|PLANAR_SH(1)) +#define TYPE_BGR_16_SE (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1)) + +#define TYPE_RGBA_8 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)) +#define TYPE_RGBA_8_PLANAR (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|PLANAR_SH(1)) +#define TYPE_RGBA_16 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_RGBA_16_PLANAR (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|PLANAR_SH(1)) +#define TYPE_RGBA_16_SE (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1)) + +#define TYPE_ARGB_8 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|SWAPFIRST_SH(1)) +#define TYPE_ARGB_16 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|SWAPFIRST_SH(1)) + +#define TYPE_ABGR_8 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)) +#define TYPE_ABGR_16 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_ABGR_16_PLANAR (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|PLANAR_SH(1)) +#define TYPE_ABGR_16_SE (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1)) + +#define TYPE_BGRA_8 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1)) +#define TYPE_BGRA_16 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|SWAPFIRST_SH(1)) +#define TYPE_BGRA_16_SE (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1)|SWAPFIRST_SH(1)) + +#define TYPE_CMY_8 (COLORSPACE_SH(PT_CMY)|CHANNELS_SH(3)|BYTES_SH(1)) +#define TYPE_CMY_8_PLANAR (COLORSPACE_SH(PT_CMY)|CHANNELS_SH(3)|BYTES_SH(1)|PLANAR_SH(1)) +#define TYPE_CMY_16 (COLORSPACE_SH(PT_CMY)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_CMY_16_PLANAR (COLORSPACE_SH(PT_CMY)|CHANNELS_SH(3)|BYTES_SH(2)|PLANAR_SH(1)) +#define TYPE_CMY_16_SE (COLORSPACE_SH(PT_CMY)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1)) + +#define TYPE_CMYK_8 (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(1)) +#define TYPE_CMYKA_8 (COLORSPACE_SH(PT_CMYK)|EXTRA_SH(1)|CHANNELS_SH(4)|BYTES_SH(1)) +#define TYPE_CMYK_8_REV (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1)) +#define TYPE_YUVK_8 TYPE_CMYK_8_REV +#define TYPE_CMYK_8_PLANAR (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(1)|PLANAR_SH(1)) +#define TYPE_CMYK_16 (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)) +#define TYPE_CMYK_16_REV (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1)) +#define TYPE_YUVK_16 TYPE_CMYK_16_REV +#define TYPE_CMYK_16_PLANAR (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)|PLANAR_SH(1)) +#define TYPE_CMYK_16_SE (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)|ENDIAN16_SH(1)) + +#define TYPE_KYMC_8 (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)) +#define TYPE_KYMC_16 (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_KYMC_16_SE (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1)) + +#define TYPE_KCMY_8 (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(1)|SWAPFIRST_SH(1)) +#define TYPE_KCMY_8_REV (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(1)|FLAVOR_SH(1)|SWAPFIRST_SH(1)) +#define TYPE_KCMY_16 (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)|SWAPFIRST_SH(1)) +#define TYPE_KCMY_16_REV (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)|FLAVOR_SH(1)|SWAPFIRST_SH(1)) +#define TYPE_KCMY_16_SE (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2)|ENDIAN16_SH(1)|SWAPFIRST_SH(1)) + + +// HiFi separations, Thanks to Steven Greaves for providing the code, +// the colorspace is not checked +#define TYPE_CMYK5_8 (CHANNELS_SH(5)|BYTES_SH(1)) +#define TYPE_CMYK5_16 (CHANNELS_SH(5)|BYTES_SH(2)) +#define TYPE_CMYK5_16_SE (CHANNELS_SH(5)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_KYMC5_8 (CHANNELS_SH(5)|BYTES_SH(1)|DOSWAP_SH(1)) +#define TYPE_KYMC5_16 (CHANNELS_SH(5)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_KYMC5_16_SE (CHANNELS_SH(5)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1)) + +#define TYPE_CMYKcm_8 (CHANNELS_SH(6)|BYTES_SH(1)) +#define TYPE_CMYKcm_8_PLANAR (CHANNELS_SH(6)|BYTES_SH(1)|PLANAR_SH(1)) +#define TYPE_CMYKcm_16 (CHANNELS_SH(6)|BYTES_SH(2)) +#define TYPE_CMYKcm_16_PLANAR (CHANNELS_SH(6)|BYTES_SH(2)|PLANAR_SH(1)) +#define TYPE_CMYKcm_16_SE (CHANNELS_SH(6)|BYTES_SH(2)|ENDIAN16_SH(1)) + +// Separations with more than 6 channels aren't very standarized, +// Except most start with CMYK and add other colors, so I just used +// then total number of channels after CMYK i.e CMYK8_8 + +#define TYPE_CMYK7_8 (CHANNELS_SH(7)|BYTES_SH(1)) +#define TYPE_CMYK7_16 (CHANNELS_SH(7)|BYTES_SH(2)) +#define TYPE_CMYK7_16_SE (CHANNELS_SH(7)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_KYMC7_8 (CHANNELS_SH(7)|BYTES_SH(1)|DOSWAP_SH(1)) +#define TYPE_KYMC7_16 (CHANNELS_SH(7)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_KYMC7_16_SE (CHANNELS_SH(7)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1)) +#define TYPE_CMYK8_8 (CHANNELS_SH(8)|BYTES_SH(1)) +#define TYPE_CMYK8_16 (CHANNELS_SH(8)|BYTES_SH(2)) +#define TYPE_CMYK8_16_SE (CHANNELS_SH(8)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_KYMC8_8 (CHANNELS_SH(8)|BYTES_SH(1)|DOSWAP_SH(1)) +#define TYPE_KYMC8_16 (CHANNELS_SH(8)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_KYMC8_16_SE (CHANNELS_SH(8)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1)) +#define TYPE_CMYK9_8 (CHANNELS_SH(9)|BYTES_SH(1)) +#define TYPE_CMYK9_16 (CHANNELS_SH(9)|BYTES_SH(2)) +#define TYPE_CMYK9_16_SE (CHANNELS_SH(9)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_KYMC9_8 (CHANNELS_SH(9)|BYTES_SH(1)|DOSWAP_SH(1)) +#define TYPE_KYMC9_16 (CHANNELS_SH(9)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_KYMC9_16_SE (CHANNELS_SH(9)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1)) +#define TYPE_CMYK10_8 (CHANNELS_SH(10)|BYTES_SH(1)) +#define TYPE_CMYK10_16 (CHANNELS_SH(10)|BYTES_SH(2)) +#define TYPE_CMYK10_16_SE (CHANNELS_SH(10)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_KYMC10_8 (CHANNELS_SH(10)|BYTES_SH(1)|DOSWAP_SH(1)) +#define TYPE_KYMC10_16 (CHANNELS_SH(10)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_KYMC10_16_SE (CHANNELS_SH(10)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1)) +#define TYPE_CMYK11_8 (CHANNELS_SH(11)|BYTES_SH(1)) +#define TYPE_CMYK11_16 (CHANNELS_SH(11)|BYTES_SH(2)) +#define TYPE_CMYK11_16_SE (CHANNELS_SH(11)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_KYMC11_8 (CHANNELS_SH(11)|BYTES_SH(1)|DOSWAP_SH(1)) +#define TYPE_KYMC11_16 (CHANNELS_SH(11)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_KYMC11_16_SE (CHANNELS_SH(11)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1)) +#define TYPE_CMYK12_8 (CHANNELS_SH(12)|BYTES_SH(1)) +#define TYPE_CMYK12_16 (CHANNELS_SH(12)|BYTES_SH(2)) +#define TYPE_CMYK12_16_SE (CHANNELS_SH(12)|BYTES_SH(2)|ENDIAN16_SH(1)) +#define TYPE_KYMC12_8 (CHANNELS_SH(12)|BYTES_SH(1)|DOSWAP_SH(1)) +#define TYPE_KYMC12_16 (CHANNELS_SH(12)|BYTES_SH(2)|DOSWAP_SH(1)) +#define TYPE_KYMC12_16_SE (CHANNELS_SH(12)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1)) + +// Colorimetric + +#define TYPE_XYZ_16 (COLORSPACE_SH(PT_XYZ)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_Lab_8 (COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(1)) +#define TYPE_ALab_8 (COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1)) +#define TYPE_Lab_16 (COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_Yxy_16 (COLORSPACE_SH(PT_Yxy)|CHANNELS_SH(3)|BYTES_SH(2)) + +// YCbCr + +#define TYPE_YCbCr_8 (COLORSPACE_SH(PT_YCbCr)|CHANNELS_SH(3)|BYTES_SH(1)) +#define TYPE_YCbCr_8_PLANAR (COLORSPACE_SH(PT_YCbCr)|CHANNELS_SH(3)|BYTES_SH(1)|PLANAR_SH(1)) +#define TYPE_YCbCr_16 (COLORSPACE_SH(PT_YCbCr)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_YCbCr_16_PLANAR (COLORSPACE_SH(PT_YCbCr)|CHANNELS_SH(3)|BYTES_SH(2)|PLANAR_SH(1)) +#define TYPE_YCbCr_16_SE (COLORSPACE_SH(PT_YCbCr)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1)) + +// YUV + +#define TYPE_YUV_8 (COLORSPACE_SH(PT_YUV)|CHANNELS_SH(3)|BYTES_SH(1)) +#define TYPE_YUV_8_PLANAR (COLORSPACE_SH(PT_YUV)|CHANNELS_SH(3)|BYTES_SH(1)|PLANAR_SH(1)) +#define TYPE_YUV_16 (COLORSPACE_SH(PT_YUV)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_YUV_16_PLANAR (COLORSPACE_SH(PT_YUV)|CHANNELS_SH(3)|BYTES_SH(2)|PLANAR_SH(1)) +#define TYPE_YUV_16_SE (COLORSPACE_SH(PT_YUV)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1)) + +// HLS + +#define TYPE_HLS_8 (COLORSPACE_SH(PT_HLS)|CHANNELS_SH(3)|BYTES_SH(1)) +#define TYPE_HLS_8_PLANAR (COLORSPACE_SH(PT_HLS)|CHANNELS_SH(3)|BYTES_SH(1)|PLANAR_SH(1)) +#define TYPE_HLS_16 (COLORSPACE_SH(PT_HLS)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_HLS_16_PLANAR (COLORSPACE_SH(PT_HLS)|CHANNELS_SH(3)|BYTES_SH(2)|PLANAR_SH(1)) +#define TYPE_HLS_16_SE (COLORSPACE_SH(PT_HLS)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1)) + + +// HSV + +#define TYPE_HSV_8 (COLORSPACE_SH(PT_HSV)|CHANNELS_SH(3)|BYTES_SH(1)) +#define TYPE_HSV_8_PLANAR (COLORSPACE_SH(PT_HSV)|CHANNELS_SH(3)|BYTES_SH(1)|PLANAR_SH(1)) +#define TYPE_HSV_16 (COLORSPACE_SH(PT_HSV)|CHANNELS_SH(3)|BYTES_SH(2)) +#define TYPE_HSV_16_PLANAR (COLORSPACE_SH(PT_HSV)|CHANNELS_SH(3)|BYTES_SH(2)|PLANAR_SH(1)) +#define TYPE_HSV_16_SE (COLORSPACE_SH(PT_HSV)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1)) + +// Named color index. Only 16 bits allowed (don't check colorspace) + +#define TYPE_NAMED_COLOR_INDEX (CHANNELS_SH(1)|BYTES_SH(2)) + +// Double values. Painful slow, but sometimes helpful. NOTE THAT 'BYTES' FIELD IS SET TO ZERO! + +#define TYPE_XYZ_DBL (COLORSPACE_SH(PT_XYZ)|CHANNELS_SH(3)|BYTES_SH(0)) +#define TYPE_Lab_DBL (COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(0)) +#define TYPE_GRAY_DBL (COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(0)) +#define TYPE_RGB_DBL (COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(0)) +#define TYPE_CMYK_DBL (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(0)) + +#endif + + +// Gamma table parameters + +typedef struct { + + unsigned int Crc32; // Has my table been touched? + + // Keep initial parameters for further serialization + + int Type; + double Params[10]; + + } LCMSGAMMAPARAMS, FAR* LPLCMSGAMMAPARAMS; + +// Gamma tables. + +typedef struct { + + LCMSGAMMAPARAMS Seed; // Parameters used for table creation + + // Table-based representation follows + + int nEntries; + WORD GammaTable[1]; + + } GAMMATABLE; + +typedef GAMMATABLE FAR* LPGAMMATABLE; + +// Sampled curves (1D) +typedef struct { + + int nItems; + double* Values; + + } SAMPLEDCURVE; + +typedef SAMPLEDCURVE FAR* LPSAMPLEDCURVE; + +// Vectors +typedef struct { // Float Vector + + double n[3]; + + } VEC3; + +typedef VEC3 FAR* LPVEC3; + + +typedef struct { // Matrix + + VEC3 v[3]; + + } MAT3; + +typedef MAT3 FAR* LPMAT3; + +// Colorspace values +typedef struct { + + double X; + double Y; + double Z; + + } cmsCIEXYZ; + +typedef cmsCIEXYZ FAR* LPcmsCIEXYZ; + +typedef struct { + + double x; + double y; + double Y; + + } cmsCIExyY; + +typedef cmsCIExyY FAR* LPcmsCIExyY; + +typedef struct { + + double L; + double a; + double b; + + } cmsCIELab; + +typedef cmsCIELab FAR* LPcmsCIELab; + +typedef struct { + + double L; + double C; + double h; + + } cmsCIELCh; + +typedef cmsCIELCh FAR* LPcmsCIELCh; + +typedef struct { + + double J; + double C; + double h; + + } cmsJCh; + +typedef cmsJCh FAR* LPcmsJCh; + +// Primaries +typedef struct { + + cmsCIEXYZ Red; + cmsCIEXYZ Green; + cmsCIEXYZ Blue; + + } cmsCIEXYZTRIPLE; + +typedef cmsCIEXYZTRIPLE FAR* LPcmsCIEXYZTRIPLE; + + +typedef struct { + + cmsCIExyY Red; + cmsCIExyY Green; + cmsCIExyY Blue; + + } cmsCIExyYTRIPLE; + +typedef cmsCIExyYTRIPLE FAR* LPcmsCIExyYTRIPLE; + + + +// Following ICC spec + +#define D50X (0.9642) +#define D50Y (1.0) +#define D50Z (0.8249) + +#define PERCEPTUAL_BLACK_X (0.00336) +#define PERCEPTUAL_BLACK_Y (0.0034731) +#define PERCEPTUAL_BLACK_Z (0.00287) + +// Does return pointers to constant structs + +LCMSAPI LPcmsCIEXYZ LCMSEXPORT cmsD50_XYZ(void); +LCMSAPI LPcmsCIExyY LCMSEXPORT cmsD50_xyY(void); + + +// Input/Output + +LCMSAPI cmsHPROFILE LCMSEXPORT cmsOpenProfileFromFile(const char *ICCProfile, const char *sAccess); +LCMSAPI cmsHPROFILE LCMSEXPORT cmsOpenProfileFromMem(LPVOID MemPtr, DWORD dwSize); +LCMSAPI BOOL LCMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile); + +// Predefined run-time profiles + +LCMSAPI cmsHPROFILE LCMSEXPORT cmsCreateRGBProfile(LPcmsCIExyY WhitePoint, + LPcmsCIExyYTRIPLE Primaries, + LPGAMMATABLE TransferFunction[3]); + +LCMSAPI cmsHPROFILE LCMSEXPORT cmsCreateGrayProfile(LPcmsCIExyY WhitePoint, + LPGAMMATABLE TransferFunction); + +LCMSAPI cmsHPROFILE LCMSEXPORT cmsCreateLinearizationDeviceLink(icColorSpaceSignature ColorSpace, + LPGAMMATABLE TransferFunctions[]); + +LCMSAPI cmsHPROFILE LCMSEXPORT cmsCreateInkLimitingDeviceLink(icColorSpaceSignature ColorSpace, + double Limit); + + +LCMSAPI cmsHPROFILE LCMSEXPORT cmsCreateLabProfile(LPcmsCIExyY WhitePoint); +LCMSAPI cmsHPROFILE LCMSEXPORT cmsCreateLab4Profile(LPcmsCIExyY WhitePoint); + +LCMSAPI cmsHPROFILE LCMSEXPORT cmsCreateXYZProfile(void); +LCMSAPI cmsHPROFILE LCMSEXPORT cmsCreate_sRGBProfile(void); + + + +LCMSAPI cmsHPROFILE LCMSEXPORT cmsCreateBCHSWabstractProfile(int nLUTPoints, + double Bright, + double Contrast, + double Hue, + double Saturation, + int TempSrc, + int TempDest); + +LCMSAPI cmsHPROFILE LCMSEXPORT cmsCreateNULLProfile(void); + + +// Colorimetric space conversions + +LCMSAPI void LCMSEXPORT cmsXYZ2xyY(LPcmsCIExyY Dest, const cmsCIEXYZ* Source); +LCMSAPI void LCMSEXPORT cmsxyY2XYZ(LPcmsCIEXYZ Dest, const cmsCIExyY* Source); +LCMSAPI void LCMSEXPORT cmsXYZ2Lab(LPcmsCIEXYZ WhitePoint, LPcmsCIELab Lab, const cmsCIEXYZ* xyz); +LCMSAPI void LCMSEXPORT cmsLab2XYZ(LPcmsCIEXYZ WhitePoint, LPcmsCIEXYZ xyz, const cmsCIELab* Lab); +LCMSAPI void LCMSEXPORT cmsLab2LCh(LPcmsCIELCh LCh, const cmsCIELab* Lab); +LCMSAPI void LCMSEXPORT cmsLCh2Lab(LPcmsCIELab Lab, const cmsCIELCh* LCh); + + +// CIELab handling + +LCMSAPI double LCMSEXPORT cmsDeltaE(LPcmsCIELab Lab1, LPcmsCIELab Lab2); +LCMSAPI double LCMSEXPORT cmsCIE94DeltaE(LPcmsCIELab Lab1, LPcmsCIELab Lab2); +LCMSAPI double LCMSEXPORT cmsBFDdeltaE(LPcmsCIELab Lab1, LPcmsCIELab Lab2); +LCMSAPI double LCMSEXPORT cmsCMCdeltaE(LPcmsCIELab Lab1, LPcmsCIELab Lab2); +LCMSAPI double LCMSEXPORT cmsCIE2000DeltaE(LPcmsCIELab Lab1, LPcmsCIELab Lab2, double Kl, double Kc, double Kh); + +LCMSAPI void LCMSEXPORT cmsClampLab(LPcmsCIELab Lab, double amax, double amin, double bmax, double bmin); + +LCMSAPI BOOL LCMSEXPORT cmsWhitePointFromTemp(int TempK, LPcmsCIExyY WhitePoint); + +LCMSAPI BOOL LCMSEXPORT cmsAdaptToIlluminant(LPcmsCIEXYZ Result, + LPcmsCIEXYZ SourceWhitePt, + LPcmsCIEXYZ Illuminant, + LPcmsCIEXYZ Value); + +LCMSAPI BOOL LCMSEXPORT cmsBuildRGB2XYZtransferMatrix(LPMAT3 r, + LPcmsCIExyY WhitePoint, + LPcmsCIExyYTRIPLE Primaries); + +// Viewing conditions + +#define AVG_SURROUND_4 0 +#define AVG_SURROUND 1 +#define DIM_SURROUND 2 +#define DARK_SURROUND 3 +#define CUTSHEET_SURROUND 4 + +#define D_CALCULATE (-1) +#define D_CALCULATE_DISCOUNT (-2) + +typedef struct { + + cmsCIEXYZ whitePoint; + double Yb; + double La; + int surround; + double D_value; + + } cmsViewingConditions; + +typedef cmsViewingConditions FAR* LPcmsViewingConditions; + +// CIECAM97s + +LCMSAPI LCMSHANDLE LCMSEXPORT cmsCIECAM97sInit(LPcmsViewingConditions pVC2); +LCMSAPI void LCMSEXPORT cmsCIECAM97sDone(LCMSHANDLE hModel); +LCMSAPI void LCMSEXPORT cmsCIECAM97sForward(LCMSHANDLE hModel, LPcmsCIEXYZ pIn, LPcmsJCh pOut); +LCMSAPI void LCMSEXPORT cmsCIECAM97sReverse(LCMSHANDLE hModel, LPcmsJCh pIn, LPcmsCIEXYZ pOut); + + +// CIECAM02 + +LCMSAPI LCMSHANDLE LCMSEXPORT cmsCIECAM02Init(LPcmsViewingConditions pVC); +LCMSAPI void LCMSEXPORT cmsCIECAM02Done(LCMSHANDLE hModel); +LCMSAPI void LCMSEXPORT cmsCIECAM02Forward(LCMSHANDLE hModel, LPcmsCIEXYZ pIn, LPcmsJCh pOut); +LCMSAPI void LCMSEXPORT cmsCIECAM02Reverse(LCMSHANDLE hModel, LPcmsJCh pIn, LPcmsCIEXYZ pOut); + + +// Gamma + +LCMSAPI LPGAMMATABLE LCMSEXPORT cmsBuildGamma(int nEntries, double Gamma); +LCMSAPI LPGAMMATABLE LCMSEXPORT cmsBuildParametricGamma(int nEntries, int Type, double Params[]); +LCMSAPI LPGAMMATABLE LCMSEXPORT cmsAllocGamma(int nEntries); +LCMSAPI void LCMSEXPORT cmsFreeGamma(LPGAMMATABLE Gamma); +LCMSAPI void LCMSEXPORT cmsFreeGammaTriple(LPGAMMATABLE Gamma[3]); +LCMSAPI LPGAMMATABLE LCMSEXPORT cmsDupGamma(LPGAMMATABLE Src); +LCMSAPI LPGAMMATABLE LCMSEXPORT cmsReverseGamma(int nResultSamples, LPGAMMATABLE InGamma); +LCMSAPI LPGAMMATABLE LCMSEXPORT cmsJoinGamma(LPGAMMATABLE InGamma, LPGAMMATABLE OutGamma); +LCMSAPI LPGAMMATABLE LCMSEXPORT cmsJoinGammaEx(LPGAMMATABLE InGamma, LPGAMMATABLE OutGamma, int nPoints); +LCMSAPI BOOL LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda); +LCMSAPI double LCMSEXPORT cmsEstimateGamma(LPGAMMATABLE t); +LCMSAPI double LCMSEXPORT cmsEstimateGammaEx(LPWORD Table, int nEntries, double Thereshold); +LCMSAPI LPGAMMATABLE LCMSEXPORT cmsReadICCGamma(cmsHPROFILE hProfile, icTagSignature sig); +LCMSAPI LPGAMMATABLE LCMSEXPORT cmsReadICCGammaReversed(cmsHPROFILE hProfile, icTagSignature sig); + +// Access to Profile data. + +LCMSAPI BOOL LCMSEXPORT cmsTakeMediaWhitePoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile); +LCMSAPI BOOL LCMSEXPORT cmsTakeMediaBlackPoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile); +LCMSAPI BOOL LCMSEXPORT cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile); +LCMSAPI BOOL LCMSEXPORT cmsTakeColorants(LPcmsCIEXYZTRIPLE Dest, cmsHPROFILE hProfile); +LCMSAPI DWORD LCMSEXPORT cmsTakeHeaderFlags(cmsHPROFILE hProfile); +LCMSAPI DWORD LCMSEXPORT cmsTakeHeaderAttributes(cmsHPROFILE hProfile); + +LCMSAPI void LCMSEXPORT cmsSetLanguage(int LanguageCode, int CountryCode); +LCMSAPI const char* LCMSEXPORT cmsTakeProductName(cmsHPROFILE hProfile); +LCMSAPI const char* LCMSEXPORT cmsTakeProductDesc(cmsHPROFILE hProfile); +LCMSAPI const char* LCMSEXPORT cmsTakeProductInfo(cmsHPROFILE hProfile); +LCMSAPI const char* LCMSEXPORT cmsTakeManufacturer(cmsHPROFILE hProfile); +LCMSAPI const char* LCMSEXPORT cmsTakeModel(cmsHPROFILE hProfile); +LCMSAPI const char* LCMSEXPORT cmsTakeCopyright(cmsHPROFILE hProfile); +LCMSAPI const BYTE* LCMSEXPORT cmsTakeProfileID(cmsHPROFILE hProfile); + +LCMSAPI BOOL LCMSEXPORT cmsTakeCreationDateTime(struct tm *Dest, cmsHPROFILE hProfile); +LCMSAPI BOOL LCMSEXPORT cmsTakeCalibrationDateTime(struct tm *Dest, cmsHPROFILE hProfile); + +LCMSAPI BOOL LCMSEXPORT cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig); +LCMSAPI int LCMSEXPORT cmsTakeRenderingIntent(cmsHPROFILE hProfile); + +LCMSAPI BOOL LCMSEXPORT cmsTakeCharTargetData(cmsHPROFILE hProfile, char** Data, size_t* len); + +LCMSAPI int LCMSEXPORT cmsReadICCTextEx(cmsHPROFILE hProfile, icTagSignature sig, char *Text, size_t size); +LCMSAPI int LCMSEXPORT cmsReadICCText(cmsHPROFILE hProfile, icTagSignature sig, char *Text); + + +#define LCMS_DESC_MAX 512 + +typedef struct { + + icSignature deviceMfg; + icSignature deviceModel; + icUInt32Number attributes[2]; + icTechnologySignature technology; + + char Manufacturer[LCMS_DESC_MAX]; + char Model[LCMS_DESC_MAX]; + + } cmsPSEQDESC, FAR *LPcmsPSEQDESC; + +typedef struct { + + int n; + cmsPSEQDESC seq[1]; + + } cmsSEQ, FAR *LPcmsSEQ; + + +LCMSAPI LPcmsSEQ LCMSEXPORT cmsReadProfileSequenceDescription(cmsHPROFILE hProfile); +LCMSAPI void LCMSEXPORT cmsFreeProfileSequenceDescription(LPcmsSEQ pseq); + + +// Extended gamut tag -- an HP extension + +#define LCMSGAMUTMETHOD_SEGMENTMAXIMA 0 +#define LCMSGAMUTMETHOD_CONVEXHULL 1 +#define LCMSGAMUTMETHOD_ALPHASHAPE 2 + + +#define LCMSGAMUT_PHYSICAL 0 +#define LCMSGAMUT_HP1 1 +#define LCMSGAMUT_HP2 2 + +typedef struct { + + icColorSpaceSignature CoordSig; // Gamut coordinates signature + icUInt16Number Method; // Method used to generate gamut + icUInt16Number Usage; // Gamut usage or intent + + char Description[LCMS_DESC_MAX]; // Textual description + + cmsViewingConditions Vc; // The viewing conditions + + icUInt32Number Count; // Number of entries + double Data[1]; // The current data + + } cmsGAMUTEX, FAR* LPcmsGAMUTEX; + + +LCMSAPI LPcmsGAMUTEX LCMSEXPORT cmsReadExtendedGamut(cmsHPROFILE hProfile, int index); +LCMSAPI void LCMSEXPORT cmsFreeExtendedGamut(LPcmsGAMUTEX gex); + + + + +// Translate form/to our notation to ICC +LCMSAPI icColorSpaceSignature LCMSEXPORT _cmsICCcolorSpace(int OurNotation); +LCMSAPI int LCMSEXPORT _cmsLCMScolorSpace(icColorSpaceSignature ProfileSpace); +LCMSAPI int LCMSEXPORT _cmsChannelsOf(icColorSpaceSignature ColorSpace); +LCMSAPI BOOL LCMSEXPORT _cmsIsMatrixShaper(cmsHPROFILE hProfile); + +#define LCMS_USED_AS_INPUT 0 +#define LCMS_USED_AS_OUTPUT 1 +#define LCMS_USED_AS_PROOF 2 + +LCMSAPI BOOL LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, int Intent, int UsedDirection); + +LCMSAPI icColorSpaceSignature LCMSEXPORT cmsGetPCS(cmsHPROFILE hProfile); +LCMSAPI icColorSpaceSignature LCMSEXPORT cmsGetColorSpace(cmsHPROFILE hProfile); +LCMSAPI icProfileClassSignature LCMSEXPORT cmsGetDeviceClass(cmsHPROFILE hProfile); +LCMSAPI DWORD LCMSEXPORT cmsGetProfileICCversion(cmsHPROFILE hProfile); +LCMSAPI void LCMSEXPORT cmsSetProfileICCversion(cmsHPROFILE hProfile, DWORD Version); +LCMSAPI icInt32Number LCMSEXPORT cmsGetTagCount(cmsHPROFILE hProfile); +LCMSAPI icTagSignature LCMSEXPORT cmsGetTagSignature(cmsHPROFILE hProfile, icInt32Number n); + + +LCMSAPI void LCMSEXPORT cmsSetDeviceClass(cmsHPROFILE hProfile, icProfileClassSignature sig); +LCMSAPI void LCMSEXPORT cmsSetColorSpace(cmsHPROFILE hProfile, icColorSpaceSignature sig); +LCMSAPI void LCMSEXPORT cmsSetPCS(cmsHPROFILE hProfile, icColorSpaceSignature pcs); +LCMSAPI void LCMSEXPORT cmsSetRenderingIntent(cmsHPROFILE hProfile, int RenderingIntent); +LCMSAPI void LCMSEXPORT cmsSetHeaderFlags(cmsHPROFILE hProfile, DWORD Flags); +LCMSAPI void LCMSEXPORT cmsSetHeaderAttributes(cmsHPROFILE hProfile, DWORD Flags); +LCMSAPI void LCMSEXPORT cmsSetProfileID(cmsHPROFILE hProfile, LPBYTE ProfileID); + +// Intents + +#define INTENT_PERCEPTUAL 0 +#define INTENT_RELATIVE_COLORIMETRIC 1 +#define INTENT_SATURATION 2 +#define INTENT_ABSOLUTE_COLORIMETRIC 3 + +// Flags + +#define cmsFLAGS_MATRIXINPUT 0x0001 +#define cmsFLAGS_MATRIXOUTPUT 0x0002 +#define cmsFLAGS_MATRIXONLY (cmsFLAGS_MATRIXINPUT|cmsFLAGS_MATRIXOUTPUT) + +#define cmsFLAGS_NOWHITEONWHITEFIXUP 0x0004 // Don't hot fix scum dot +#define cmsFLAGS_NOPRELINEARIZATION 0x0010 // Don't create prelinearization tables + // on precalculated transforms (internal use) + +#define cmsFLAGS_GUESSDEVICECLASS 0x0020 // Guess device class (for transform2devicelink) + +#define cmsFLAGS_NOTCACHE 0x0040 // Inhibit 1-pixel cache + +#define cmsFLAGS_NOTPRECALC 0x0100 +#define cmsFLAGS_NULLTRANSFORM 0x0200 // Don't transform anyway +#define cmsFLAGS_HIGHRESPRECALC 0x0400 // Use more memory to give better accurancy +#define cmsFLAGS_LOWRESPRECALC 0x0800 // Use less memory to minimize resouces + + +#define cmsFLAGS_WHITEBLACKCOMPENSATION 0x2000 +#define cmsFLAGS_BLACKPOINTCOMPENSATION cmsFLAGS_WHITEBLACKCOMPENSATION + +// Proofing flags + +#define cmsFLAGS_GAMUTCHECK 0x1000 // Out of Gamut alarm +#define cmsFLAGS_SOFTPROOFING 0x4000 // Do softproofing + +// Black preservation + +#define cmsFLAGS_PRESERVEBLACK 0x8000 + +// CRD special + +#define cmsFLAGS_NODEFAULTRESOURCEDEF 0x00010000 + +// Gridpoints + +#define cmsFLAGS_GRIDPOINTS(n) (((n) & 0xFF) << 16) + + +// Transforms + +LCMSAPI cmsHTRANSFORM LCMSEXPORT cmsCreateTransform(cmsHPROFILE Input, + DWORD InputFormat, + cmsHPROFILE Output, + DWORD OutputFormat, + int Intent, + DWORD dwFlags); + +LCMSAPI cmsHTRANSFORM LCMSEXPORT cmsCreateProofingTransform(cmsHPROFILE Input, + DWORD InputFormat, + cmsHPROFILE Output, + DWORD OutputFormat, + cmsHPROFILE Proofing, + int Intent, + int ProofingIntent, + DWORD dwFlags); + +LCMSAPI cmsHTRANSFORM LCMSEXPORT cmsCreateMultiprofileTransform(cmsHPROFILE hProfiles[], + int nProfiles, + DWORD InputFormat, + DWORD OutputFormat, + int Intent, + DWORD dwFlags); + +LCMSAPI void LCMSEXPORT cmsDeleteTransform(cmsHTRANSFORM hTransform); + +LCMSAPI void LCMSEXPORT cmsDoTransform(cmsHTRANSFORM Transform, + LPVOID InputBuffer, + LPVOID OutputBuffer, + unsigned int Size); + +LCMSAPI void LCMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform, DWORD InputFormat, DWORD dwOutputFormat); + +LCMSAPI void LCMSEXPORT cmsSetAlarmCodes(int r, int g, int b); +LCMSAPI void LCMSEXPORT cmsGetAlarmCodes(int *r, int *g, int *b); + + +// Adaptation state for absolute colorimetric intent + +LCMSAPI double LCMSEXPORT cmsSetAdaptationState(double d); + + +// Primary preservation strategy + +#define LCMS_PRESERVE_PURE_K 0 +#define LCMS_PRESERVE_K_PLANE 1 + +LCMSAPI int LCMSEXPORT cmsSetCMYKPreservationStrategy(int n); + +// Named color support +typedef struct { + char Name[MAX_PATH]; + WORD PCS[3]; + WORD DeviceColorant[MAXCHANNELS]; + + + } cmsNAMEDCOLOR, FAR* LPcmsNAMEDCOLOR; + +typedef struct { + int nColors; + int Allocated; + int ColorantCount; + char Prefix[33]; + char Suffix[33]; + + cmsNAMEDCOLOR List[1]; + + } cmsNAMEDCOLORLIST, FAR* LPcmsNAMEDCOLORLIST; + +// Named color support + +LCMSAPI int LCMSEXPORT cmsNamedColorCount(cmsHTRANSFORM xform); +LCMSAPI BOOL LCMSEXPORT cmsNamedColorInfo(cmsHTRANSFORM xform, int nColor, char* Name, char* Prefix, char* Suffix); +LCMSAPI int LCMSEXPORT cmsNamedColorIndex(cmsHTRANSFORM xform, const char* Name); + +// Colorant tables + +LCMSAPI LPcmsNAMEDCOLORLIST LCMSEXPORT cmsReadColorantTable(cmsHPROFILE hProfile, icTagSignature sig); + +// Profile creation + +LCMSAPI BOOL LCMSEXPORT cmsAddTag(cmsHPROFILE hProfile, icTagSignature sig, const void* data); + +// Converts a transform to a devicelink profile +LCMSAPI cmsHPROFILE LCMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, DWORD dwFlags); + +// Set the 'save as 8-bit' flag +LCMSAPI void LCMSEXPORT _cmsSetLUTdepth(cmsHPROFILE hProfile, int depth); + + +// Save profile +LCMSAPI BOOL LCMSEXPORT _cmsSaveProfile(cmsHPROFILE hProfile, const char* FileName); +LCMSAPI BOOL LCMSEXPORT _cmsSaveProfileToMem(cmsHPROFILE hProfile, void *MemPtr, + size_t* BytesNeeded); + + + +// PostScript ColorRenderingDictionary and ColorSpaceArray + +LCMSAPI DWORD LCMSEXPORT cmsGetPostScriptCSA(cmsHPROFILE hProfile, int Intent, LPVOID Buffer, DWORD dwBufferLen); +LCMSAPI DWORD LCMSEXPORT cmsGetPostScriptCRD(cmsHPROFILE hProfile, int Intent, LPVOID Buffer, DWORD dwBufferLen); +LCMSAPI DWORD LCMSEXPORT cmsGetPostScriptCRDEx(cmsHPROFILE hProfile, int Intent, DWORD dwFlags, LPVOID Buffer, DWORD dwBufferLen); + + +// Error handling + +#define LCMS_ERROR_ABORT 0 +#define LCMS_ERROR_SHOW 1 +#define LCMS_ERROR_IGNORE 2 + +LCMSAPI int LCMSEXPORT cmsErrorAction(int nAction); + +#define LCMS_ERRC_WARNING 0x1000 +#define LCMS_ERRC_RECOVERABLE 0x2000 +#define LCMS_ERRC_ABORTED 0x3000 + +typedef int (* cmsErrorHandlerFunction)(int ErrorCode, const char *ErrorText); + +LCMSAPI void LCMSEXPORT cmsSetErrorHandler(cmsErrorHandlerFunction Fn); + + +// LUT manipulation + + +typedef struct _lcms_LUT_struc LUT, FAR* LPLUT; // opaque pointer + +LCMSAPI LPLUT LCMSEXPORT cmsAllocLUT(void); +LCMSAPI LPLUT LCMSEXPORT cmsAllocLinearTable(LPLUT NewLUT, LPGAMMATABLE Tables[], int nTable); +LCMSAPI LPLUT LCMSEXPORT cmsAlloc3DGrid(LPLUT Lut, int clutPoints, int inputChan, int outputChan); +LCMSAPI LPLUT LCMSEXPORT cmsSetMatrixLUT(LPLUT Lut, LPMAT3 M); +LCMSAPI LPLUT LCMSEXPORT cmsSetMatrixLUT4(LPLUT Lut, LPMAT3 M, LPVEC3 off, DWORD dwFlags); +LCMSAPI void LCMSEXPORT cmsFreeLUT(LPLUT Lut); +LCMSAPI void LCMSEXPORT cmsEvalLUT(LPLUT Lut, WORD In[], WORD Out[]); +LCMSAPI double LCMSEXPORT cmsEvalLUTreverse(LPLUT Lut, WORD Target[], WORD Result[], LPWORD Hint); +LCMSAPI LPLUT LCMSEXPORT cmsReadICCLut(cmsHPROFILE hProfile, icTagSignature sig); +LCMSAPI LPLUT LCMSEXPORT cmsDupLUT(LPLUT Orig); + +// LUT Sampling + +typedef int (* _cmsSAMPLER)(register WORD In[], + register WORD Out[], + register LPVOID Cargo); + +#define SAMPLER_HASTL1 LUT_HASTL1 +#define SAMPLER_HASTL2 LUT_HASTL2 +#define SAMPLER_INSPECT 0x01000000 + +LCMSAPI int LCMSEXPORT cmsSample3DGrid(LPLUT Lut, _cmsSAMPLER Sampler, LPVOID Cargo, DWORD dwFlags); + +// Formatters + +typedef unsigned char* (* cmsFORMATTER)(register void* CMMcargo, + register WORD ToUnroll[], + register LPBYTE Buffer); + +LCMSAPI void LCMSEXPORT cmsSetUserFormatters(cmsHTRANSFORM hTransform, DWORD dwInput, cmsFORMATTER Input, + DWORD dwOutput, cmsFORMATTER Output); + +LCMSAPI void LCMSEXPORT cmsGetUserFormatters(cmsHTRANSFORM hTransform, + LPDWORD InputFormat, cmsFORMATTER* Input, + LPDWORD OutputFormat, cmsFORMATTER* Output); + + +// IT8.7 / CGATS.17-200x handling + +LCMSAPI LCMSHANDLE LCMSEXPORT cmsIT8Alloc(void); +LCMSAPI void LCMSEXPORT cmsIT8Free(LCMSHANDLE IT8); + +// Tables + +LCMSAPI int LCMSEXPORT cmsIT8TableCount(LCMSHANDLE IT8); +LCMSAPI int LCMSEXPORT cmsIT8SetTable(LCMSHANDLE IT8, int nTable); + +// Persistence +LCMSAPI LCMSHANDLE LCMSEXPORT cmsIT8LoadFromFile(const char* cFileName); +LCMSAPI LCMSHANDLE LCMSEXPORT cmsIT8LoadFromMem(void *Ptr, size_t len); +LCMSAPI BOOL LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE IT8, const char* cFileName); +LCMSAPI BOOL LCMSEXPORT cmsIT8SaveToMem(LCMSHANDLE hIT8, void *MemPtr, size_t* BytesNeeded); + +// Properties +LCMSAPI const char* LCMSEXPORT cmsIT8GetSheetType(LCMSHANDLE hIT8); +LCMSAPI BOOL LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type); + +LCMSAPI BOOL LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* cComment); + +LCMSAPI BOOL LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* cProp, const char *Str); +LCMSAPI BOOL LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val); +LCMSAPI BOOL LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val); + +LCMSAPI BOOL LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer); + + +LCMSAPI const char* LCMSEXPORT cmsIT8GetProperty(LCMSHANDLE hIT8, const char* cProp); +LCMSAPI double LCMSEXPORT cmsIT8GetPropertyDbl(LCMSHANDLE hIT8, const char* cProp); +LCMSAPI int LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE IT8, char ***PropertyNames); + +// Datasets + +LCMSAPI const char* LCMSEXPORT cmsIT8GetDataRowCol(LCMSHANDLE IT8, int row, int col); +LCMSAPI double LCMSEXPORT cmsIT8GetDataRowColDbl(LCMSHANDLE IT8, int row, int col); + +LCMSAPI BOOL LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col, + const char* Val); + +LCMSAPI BOOL LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col, + double Val); + +LCMSAPI const char* LCMSEXPORT cmsIT8GetData(LCMSHANDLE IT8, const char* cPatch, const char* cSample); + + +LCMSAPI double LCMSEXPORT cmsIT8GetDataDbl(LCMSHANDLE IT8, const char* cPatch, const char* cSample); + +LCMSAPI BOOL LCMSEXPORT cmsIT8SetData(LCMSHANDLE IT8, const char* cPatch, + const char* cSample, + const char *Val); + +LCMSAPI BOOL LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch, + const char* cSample, + double Val); + +LCMSAPI int LCMSEXPORT cmsIT8GetDataFormat(LCMSHANDLE hIT8, const char* cSample); +LCMSAPI BOOL LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE IT8, int n, const char *Sample); +LCMSAPI int LCMSEXPORT cmsIT8EnumDataFormat(LCMSHANDLE IT8, char ***SampleNames); + + +LCMSAPI const char* LCMSEXPORT cmsIT8GetPatchName(LCMSHANDLE hIT8, int nPatch, char* buffer); + +// The LABEL extension + +LCMSAPI int LCMSEXPORT cmsIT8SetTableByLabel(LCMSHANDLE hIT8, const char* cSet, const char* cField, const char* ExpectedType); + +// Formatter for double +LCMSAPI void LCMSEXPORT cmsIT8DefineDblFormat(LCMSHANDLE IT8, const char* Formatter); + + +// *************************************************************************** +// End of Little cms API From here functions are private +// You can use them only if using static libraries, and at your own risk of +// be stripped or changed at futures releases. + +#ifndef LCMS_APIONLY + + +// Compatibility with anterior versions-- not needed anymore +// -- Morge + +LCMSAPI void LCMSEXPORT cmsLabEncoded2Float(LPcmsCIELab Lab, const WORD wLab[3]); +LCMSAPI void LCMSEXPORT cmsLabEncoded2Float4(LPcmsCIELab Lab, const WORD wLab[3]); +LCMSAPI void LCMSEXPORT cmsFloat2LabEncoded(WORD wLab[3], const cmsCIELab* Lab); +LCMSAPI void LCMSEXPORT cmsFloat2LabEncoded4(WORD wLab[3], const cmsCIELab* Lab); +LCMSAPI void LCMSEXPORT cmsXYZEncoded2Float(LPcmsCIEXYZ fxyz, const WORD XYZ[3]); +LCMSAPI void LCMSEXPORT cmsFloat2XYZEncoded(WORD XYZ[3], const cmsCIEXYZ* fXYZ); + + +// Profiling Extensions --- Would be removed from API in future revisions + +LCMSAPI BOOL LCMSEXPORT _cmsAddTextTag(cmsHPROFILE hProfile, icTagSignature sig, const char* Text); +LCMSAPI BOOL LCMSEXPORT _cmsAddXYZTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* XYZ); +LCMSAPI BOOL LCMSEXPORT _cmsAddLUTTag(cmsHPROFILE hProfile, icTagSignature sig, const void* lut); +LCMSAPI BOOL LCMSEXPORT _cmsAddGammaTag(cmsHPROFILE hProfile, icTagSignature sig, LPGAMMATABLE TransferFunction); +LCMSAPI BOOL LCMSEXPORT _cmsAddChromaticityTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIExyYTRIPLE Chrm); +LCMSAPI BOOL LCMSEXPORT _cmsAddSequenceDescriptionTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsSEQ PSeq); +LCMSAPI BOOL LCMSEXPORT _cmsAddNamedColorTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc); +LCMSAPI BOOL LCMSEXPORT _cmsAddDateTimeTag(cmsHPROFILE hProfile, icTagSignature sig, struct tm *DateTime); +LCMSAPI BOOL LCMSEXPORT _cmsAddColorantTableTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc); + +// --------------------------------------------------------------------------------------------------- Inline functions + +// Fast floor conversion logic. Thanks to Sree Kotay and Stuart Nixon +// note than this only works in the range ..-32767...+32767 because +// mantissa is interpreted as 15.16 fixed point. +// The union is to avoid pointer aliasing overoptimization. + +LCMS_INLINE int _cmsQuickFloor(double val) +{ +#ifdef USE_DEFAULT_FLOOR_CONVERSION + return (int) floor(val); +#else + const double _lcms_double2fixmagic = 68719476736.0 * 1.5; // 2^36 * 1.5, (52-16=36) uses limited precision to floor + union { + double val; + int halves[2]; + } temp; + + temp.val = val + _lcms_double2fixmagic; + + +#ifdef USE_BIG_ENDIAN + return temp.halves[1] >> 16; +#else + return temp.halves[0] >> 16; +#endif +#endif +} + + + +// Clamp with saturation + +LCMS_INLINE WORD _cmsClampWord(int in) +{ + if (in < 0) return 0; + if (in > 0xFFFF) return 0xFFFFU; // Including marker + return (WORD) in; +} + +// ------------------------------------------------------------------------------------------- end of inline functions + +// Signal error from inside lcms code + +void cdecl cmsSignalError(int ErrorCode, const char *ErrorText, ...); + +// Alignment handling (needed in ReadLUT16 and ReadLUT8) + +typedef struct { + icS15Fixed16Number a; + icUInt16Number b; + + } _cmsTestAlign16; + +#define SIZEOF_UINT16_ALIGNED (sizeof(_cmsTestAlign16) - sizeof(icS15Fixed16Number)) + +typedef struct { + icS15Fixed16Number a; + icUInt8Number b; + + } _cmsTestAlign8; + +#define SIZEOF_UINT8_ALIGNED (sizeof(_cmsTestAlign8) - sizeof(icS15Fixed16Number)) + + +// Fixed point + + +typedef icInt32Number Fixed32; // Fixed 15.16 whith sign + +#define INT_TO_FIXED(x) ((x)<<16) +#define DOUBLE_TO_FIXED(x) ((Fixed32) ((x)*65536.0+0.5)) +#define FIXED_TO_INT(x) ((x)>>16) +#define FIXED_REST_TO_INT(x) ((x)& 0xFFFFU) +#define FIXED_TO_DOUBLE(x) (((double)x)/65536.0) +#define ROUND_FIXED_TO_INT(x) (((x)+0x8000)>>16) + + +Fixed32 cdecl FixedMul(Fixed32 a, Fixed32 b); +Fixed32 cdecl FixedSquare(Fixed32 a); + + +#ifdef USE_INLINE + +LCMS_INLINE Fixed32 ToFixedDomain(int a) { return a + ((a + 0x7fff) / 0xffff); } +LCMS_INLINE int FromFixedDomain(Fixed32 a) { return a - ((a + 0x7fff) >> 16); } + +#else + +Fixed32 cdecl ToFixedDomain(int a); // (a * 65536.0 / 65535.0) +int cdecl FromFixedDomain(Fixed32 a); // (a * 65535.0 + .5) + +#endif + +Fixed32 cdecl FixedLERP(Fixed32 a, Fixed32 l, Fixed32 h); +WORD cdecl FixedScale(WORD a, Fixed32 s); + +// Vector & Matrix operations. I'm using the notation frequently found in +// literature. Mostly 'Graphic Gems' samples. Not to be same routines. + +// Vector members + +#define VX 0 +#define VY 1 +#define VZ 2 + +typedef struct { // Fixed 15.16 bits vector + Fixed32 n[3]; + } WVEC3, FAR* LPWVEC3; + +typedef struct { // Matrix (Fixed 15.16) + WVEC3 v[3]; + } WMAT3, FAR* LPWMAT3; + + + +void cdecl VEC3init(LPVEC3 r, double x, double y, double z); // double version +void cdecl VEC3initF(LPWVEC3 r, double x, double y, double z); // Fix32 version +void cdecl VEC3toFix(LPWVEC3 r, LPVEC3 v); +void cdecl VEC3fromFix(LPVEC3 r, LPWVEC3 v); +void cdecl VEC3scaleFix(LPWORD r, LPWVEC3 Scale); +void cdecl VEC3swap(LPVEC3 a, LPVEC3 b); +void cdecl VEC3divK(LPVEC3 r, LPVEC3 v, double d); +void cdecl VEC3perK(LPVEC3 r, LPVEC3 v, double d); +void cdecl VEC3minus(LPVEC3 r, LPVEC3 a, LPVEC3 b); +void cdecl VEC3perComp(LPVEC3 r, LPVEC3 a, LPVEC3 b); +BOOL cdecl VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance); +BOOL cdecl VEC3equalF(LPVEC3 a, LPVEC3 b, double Tolerance); +void cdecl VEC3scaleAndCut(LPWVEC3 r, LPVEC3 v, double d); +void cdecl VEC3cross(LPVEC3 r, LPVEC3 u, LPVEC3 v); +void cdecl VEC3saturate(LPVEC3 v); +double cdecl VEC3distance(LPVEC3 a, LPVEC3 b); +double cdecl VEC3length(LPVEC3 a); + +void cdecl MAT3identity(LPMAT3 a); +void cdecl MAT3per(LPMAT3 r, LPMAT3 a, LPMAT3 b); +void cdecl MAT3perK(LPMAT3 r, LPMAT3 v, double d); +int cdecl MAT3inverse(LPMAT3 a, LPMAT3 b); +BOOL cdecl MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b); +double cdecl MAT3det(LPMAT3 m); +void cdecl MAT3eval(LPVEC3 r, LPMAT3 a, LPVEC3 v); +void cdecl MAT3toFix(LPWMAT3 r, LPMAT3 v); +void cdecl MAT3fromFix(LPMAT3 r, LPWMAT3 v); +void cdecl MAT3evalW(LPWVEC3 r, LPWMAT3 a, LPWVEC3 v); +BOOL cdecl MAT3isIdentity(LPWMAT3 a, double Tolerance); +void cdecl MAT3scaleAndCut(LPWMAT3 r, LPMAT3 v, double d); + +// Is a table linear? + +int cdecl cmsIsLinear(WORD Table[], int nEntries); + +// I hold this structures describing domain +// details mainly for optimization purposes. + +struct _lcms_l16params_struc; + +typedef void (* _cms3DLERP)(WORD Input[], + WORD Output[], + WORD LutTable[], + struct _lcms_l16params_struc* p); + + + +typedef struct _lcms_l8opt_struc { // Used on 8 bit interpolations + + unsigned int X0[256], Y0[256], Z0[256]; + WORD rx[256], ry[256], rz[256]; + + } L8PARAMS, FAR* LPL8PARAMS; + +typedef struct _lcms_l16params_struc { // Used on 16 bits interpolations + + int nSamples; // Valid on all kinds of tables + int nInputs; // != 1 only in 3D interpolation + int nOutputs; // != 1 only in 3D interpolation + + WORD Domain; + + int opta1, opta2; + int opta3, opta4; // Optimization for 3D LUT + int opta5, opta6; + int opta7, opta8; + + _cms3DLERP Interp3D; // The interpolation routine + + LPL8PARAMS p8; // Points to some tables for 8-bit speedup + + } L16PARAMS, *LPL16PARAMS; + + +void cdecl cmsCalcL16Params(int nSamples, LPL16PARAMS p); +void cdecl cmsCalcCLUT16Params(int nSamples, int InputChan, int OutputChan, LPL16PARAMS p); +void cdecl cmsCalcCLUT16ParamsEx(int nSamples, int InputChan, int OutputChan, + BOOL lUseTetrahedral, LPL16PARAMS p); + +WORD cdecl cmsLinearInterpLUT16(WORD Value, WORD LutTable[], LPL16PARAMS p); +Fixed32 cdecl cmsLinearInterpFixed(WORD Value1, WORD LutTable[], LPL16PARAMS p); +WORD cdecl cmsReverseLinearInterpLUT16(WORD Value, WORD LutTable[], LPL16PARAMS p); + +void cdecl cmsTrilinearInterp16(WORD Input[], + WORD Output[], + WORD LutTable[], + LPL16PARAMS p); + +void cdecl cmsTetrahedralInterp16(WORD Input[], + WORD Output[], + WORD LutTable[], LPL16PARAMS p); + +void cdecl cmsTetrahedralInterp8(WORD Input[], + WORD Output[], + WORD LutTable[], LPL16PARAMS p); + +// LUT handling + +#define LUT_HASMATRIX 0x0001 // Do-op Flags +#define LUT_HASTL1 0x0002 +#define LUT_HASTL2 0x0008 +#define LUT_HAS3DGRID 0x0010 + +// New in rev 4.0 of ICC spec + +#define LUT_HASMATRIX3 0x0020 // Matrix + offset for LutAToB +#define LUT_HASMATRIX4 0x0040 // Matrix + offset for LutBToA + +#define LUT_HASTL3 0x0100 // '3' curves for LutAToB +#define LUT_HASTL4 0x0200 // '4' curves for LutBToA + +// V4 emulation + +#define LUT_V4_OUTPUT_EMULATE_V2 0x10000 // Is a V4 output LUT, emulating V2 +#define LUT_V4_INPUT_EMULATE_V2 0x20000 // Is a V4 input LUT, emulating V2 +#define LUT_V2_OUTPUT_EMULATE_V4 0x40000 // Is a V2 output LUT, emulating V4 +#define LUT_V2_INPUT_EMULATE_V4 0x80000 // Is a V2 input LUT, emulating V4 + + +struct _lcms_LUT_struc { + + DWORD wFlags; + WMAT3 Matrix; // 15fixed16 matrix + + unsigned int InputChan; + unsigned int OutputChan; + unsigned int InputEntries; + unsigned int OutputEntries; + unsigned int cLutPoints; + + + LPWORD L1[MAXCHANNELS]; // First linearization + LPWORD L2[MAXCHANNELS]; // Last linearization + + LPWORD T; // 3D CLUT + unsigned int Tsize; // CLUT size in bytes + + // Parameters & Optimizations + + L16PARAMS In16params; + L16PARAMS Out16params; + L16PARAMS CLut16params; + + int Intent; // Accomplished intent + + // New for Rev 4.0 of spec (reserved) + + WMAT3 Mat3; + WVEC3 Ofs3; + LPWORD L3[MAXCHANNELS]; + L16PARAMS L3params; + unsigned int L3Entries; + + WMAT3 Mat4; + WVEC3 Ofs4; + LPWORD L4[MAXCHANNELS]; + L16PARAMS L4params; + unsigned int L4Entries; + + // Gray axes fixup. Only on v2 8-bit Lab LUT + + BOOL FixGrayAxes; + + + // Parameters used for curve creation + + LCMSGAMMAPARAMS LCurvesSeed[4][MAXCHANNELS]; + + + }; // LUT, FAR* LPLUT; + + +BOOL cdecl _cmsSmoothEndpoints(LPWORD Table, int nEntries); + + +// CRC of gamma tables + +unsigned int _cmsCrc32OfGammaTable(LPGAMMATABLE Table); + +// Sampled curves + +LPSAMPLEDCURVE cdecl cmsAllocSampledCurve(int nItems); +void cdecl cmsFreeSampledCurve(LPSAMPLEDCURVE p); +LPSAMPLEDCURVE cdecl cmsDupSampledCurve(LPSAMPLEDCURVE p); + +LPSAMPLEDCURVE cdecl cmsConvertGammaToSampledCurve(LPGAMMATABLE Gamma, int nPoints); +LPGAMMATABLE cdecl cmsConvertSampledCurveToGamma(LPSAMPLEDCURVE Sampled, double Max); + +void cdecl cmsEndpointsOfSampledCurve(LPSAMPLEDCURVE p, double* Min, double* Max); +void cdecl cmsClampSampledCurve(LPSAMPLEDCURVE p, double Min, double Max); +BOOL cdecl cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double SmoothingLambda); +void cdecl cmsRescaleSampledCurve(LPSAMPLEDCURVE p, double Min, double Max, int nPoints); + +LPSAMPLEDCURVE cdecl cmsJoinSampledCurves(LPSAMPLEDCURVE X, LPSAMPLEDCURVE Y, int nResultingPoints); + +// Shaper/Matrix handling + +#define MATSHAPER_HASMATRIX 0x0001 // Do-ops flags +#define MATSHAPER_HASSHAPER 0x0002 +#define MATSHAPER_INPUT 0x0004 // Behaviour +#define MATSHAPER_OUTPUT 0x0008 +#define MATSHAPER_HASINPSHAPER 0x0010 +#define MATSHAPER_ALLSMELTED (MATSHAPER_INPUT|MATSHAPER_OUTPUT) + + +typedef struct { + DWORD dwFlags; + + WMAT3 Matrix; + + L16PARAMS p16; // Primary curve + LPWORD L[3]; + + L16PARAMS p2_16; // Secondary curve (used as input in smelted ones) + LPWORD L2[3]; + + } MATSHAPER, FAR* LPMATSHAPER; + +LPMATSHAPER cdecl cmsAllocMatShaper(LPMAT3 matrix, LPGAMMATABLE Shaper[], DWORD Behaviour); +LPMATSHAPER cdecl cmsAllocMatShaper2(LPMAT3 matrix, LPGAMMATABLE In[], LPGAMMATABLE Out[], DWORD Behaviour); + +void cdecl cmsFreeMatShaper(LPMATSHAPER MatShaper); +void cdecl cmsEvalMatShaper(LPMATSHAPER MatShaper, WORD In[], WORD Out[]); + +BOOL cdecl cmsReadICCMatrixRGB2XYZ(LPMAT3 r, cmsHPROFILE hProfile); + +LPMATSHAPER cdecl cmsBuildInputMatrixShaper(cmsHPROFILE InputProfile); +LPMATSHAPER cdecl cmsBuildOutputMatrixShaper(cmsHPROFILE OutputProfile); + + + +// White Point & Primary chromas handling +BOOL cdecl cmsAdaptationMatrix(LPMAT3 r, LPMAT3 ConeMatrix, LPcmsCIEXYZ FromIll, LPcmsCIEXYZ ToIll); +BOOL cdecl cmsAdaptMatrixToD50(LPMAT3 r, LPcmsCIExyY SourceWhitePt); +BOOL cdecl cmsAdaptMatrixFromD50(LPMAT3 r, LPcmsCIExyY DestWhitePt); + +BOOL cdecl cmsReadChromaticAdaptationMatrix(LPMAT3 r, cmsHPROFILE hProfile); + +// Inter-PCS conversion routines. They assume D50 as white point. +void cdecl cmsXYZ2LabEncoded(WORD XYZ[3], WORD Lab[3]); +void cdecl cmsLab2XYZEncoded(WORD Lab[3], WORD XYZ[3]); + +// Retrieve text representation of WP +void cdecl _cmsIdentifyWhitePoint(char *Buffer, LPcmsCIEXYZ WhitePt); + +// Quantize to WORD in a (MaxSamples - 1) domain +WORD cdecl _cmsQuantizeVal(double i, int MaxSamples); + +LPcmsNAMEDCOLORLIST cdecl cmsAllocNamedColorList(int n); +int cdecl cmsReadICCnamedColorList(cmsHTRANSFORM xform, cmsHPROFILE hProfile, icTagSignature sig); +void cdecl cmsFreeNamedColorList(LPcmsNAMEDCOLORLIST List); +BOOL cdecl cmsAppendNamedColor(cmsHTRANSFORM xform, const char* Name, WORD PCS[3], WORD Colorant[MAXCHANNELS]); + + +// I/O + +#define MAX_TABLE_TAG 100 + +// This is the internal struct holding profile details. + +typedef struct _lcms_iccprofile_struct { + + void* stream; // Associated stream. If NULL, + // tags are supposed to be in + // memory rather than in a file. + + // Only most important items found in ICC profile + + icProfileClassSignature DeviceClass; + icColorSpaceSignature ColorSpace; + icColorSpaceSignature PCS; + icRenderingIntent RenderingIntent; + icUInt32Number flags; + icUInt32Number attributes; + cmsCIEXYZ Illuminant; + + // Additions for V4 profiles + + icUInt32Number Version; + MAT3 ChromaticAdaptation; + cmsCIEXYZ MediaWhitePoint; + cmsCIEXYZ MediaBlackPoint; + BYTE ProfileID[16]; + + + // Dictionary + + icInt32Number TagCount; + icTagSignature TagNames[MAX_TABLE_TAG]; + size_t TagSizes[MAX_TABLE_TAG]; + size_t TagOffsets[MAX_TABLE_TAG]; + LPVOID TagPtrs[MAX_TABLE_TAG]; + + char PhysicalFile[MAX_PATH]; + + BOOL IsWrite; + BOOL SaveAs8Bits; + + struct tm Created; + + // I/O handlers + + size_t (* Read)(void *buffer, size_t size, size_t count, struct _lcms_iccprofile_struct* Icc); + + BOOL (* Seek)(struct _lcms_iccprofile_struct* Icc, size_t offset); + BOOL (* Close)(struct _lcms_iccprofile_struct* Icc); + size_t (* Tell)(struct _lcms_iccprofile_struct* Icc); + + // Writting + + BOOL (* Write)(struct _lcms_iccprofile_struct* Icc, size_t size, LPVOID Ptr); + + size_t UsedSpace; + + + } LCMSICCPROFILE, FAR* LPLCMSICCPROFILE; + + +// Create an empty template for virtual profiles +cmsHPROFILE cdecl _cmsCreateProfilePlaceholder(void); + +// Search into tag dictionary +icInt32Number cdecl _cmsSearchTag(LPLCMSICCPROFILE Profile, icTagSignature sig, BOOL lSignalError); + +// Search for a particular tag, replace if found or add new one else +LPVOID _cmsInitTag(LPLCMSICCPROFILE Icc, icTagSignature sig, size_t size, const void* Init); + + +LPLCMSICCPROFILE cdecl _cmsCreateProfileFromFilePlaceholder(const char* FileName); +LPLCMSICCPROFILE cdecl _cmsCreateProfileFromMemPlaceholder(LPVOID MemPtr, DWORD dwSize); + +void _cmsSetSaveToDisk(LPLCMSICCPROFILE Icc, const char* FileName); +void _cmsSetSaveToMemory(LPLCMSICCPROFILE Icc, LPVOID MemPtr, size_t dwSize); + + + +// These macros unpack format specifiers into integers + +#define T_COLORSPACE(s) (((s)>>16)&31) +#define T_SWAPFIRST(s) (((s)>>14)&1) +#define T_FLAVOR(s) (((s)>>13)&1) +#define T_PLANAR(p) (((p)>>12)&1) +#define T_ENDIAN16(e) (((e)>>11)&1) +#define T_DOSWAP(e) (((e)>>10)&1) +#define T_EXTRA(e) (((e)>>7)&7) +#define T_CHANNELS(c) (((c)>>3)&15) +#define T_BYTES(b) ((b)&7) + + + +// Internal XFORM struct +struct _cmstransform_struct; + +// Full xform +typedef void (* _cmsCOLORCALLBACKFN)(struct _cmstransform_struct *Transform, + LPVOID InputBuffer, + LPVOID OutputBuffer, unsigned int Size); + +// intermediate pass, from WORD[] to WORD[] + +typedef void (* _cmsADJFN)(WORD In[], WORD Out[], LPWMAT3 m, LPWVEC3 b); + +typedef void (* _cmsTRANSFN)(struct _cmstransform_struct *Transform, + WORD In[], WORD Out[]); + +typedef void (* _cmsCNVRT)(WORD In[], WORD Out[]); + +typedef LPBYTE (* _cmsFIXFN)(register struct _cmstransform_struct *info, + register WORD ToUnroll[], + register LPBYTE Buffer); + + + +// Transformation +typedef struct _cmstransform_struct { + + // Keep formats for further reference + DWORD InputFormat, OutputFormat; + + DWORD StrideIn, StrideOut; // Planar support + + int Intent, ProofIntent; + int DoGamutCheck; + + + cmsHPROFILE InputProfile; + cmsHPROFILE OutputProfile; + cmsHPROFILE PreviewProfile; + + icColorSpaceSignature EntryColorSpace; + icColorSpaceSignature ExitColorSpace; + + DWORD dwOriginalFlags; // Flags as specified by user + + WMAT3 m1, m2; // Matrix holding inter PCS operation + WVEC3 of1, of2; // Offset terms + + _cmsCOLORCALLBACKFN xform; + + // Steps in xFORM + + _cmsFIXFN FromInput; + _cmsTRANSFN FromDevice; + _cmsADJFN Stage1; + _cmsADJFN Stage2; + _cmsTRANSFN ToDevice; + _cmsFIXFN ToOutput; + + // LUTs + + LPLUT Device2PCS; + LPLUT PCS2Device; + LPLUT Gamut; // Gamut check + LPLUT Preview; // Preview (Proof) + + LPLUT DeviceLink; // Precalculated grid - device link profile + LPLUT GamutCheck; // Precalculated device -> gamut check + + // Matrix/Shapers + + LPMATSHAPER InMatShaper; + LPMATSHAPER OutMatShaper; + LPMATSHAPER SmeltMatShaper; + + // Phase of Lab/XYZ, Abs/Rel + + int Phase1, Phase2, Phase3; + + // Named color table + + LPcmsNAMEDCOLORLIST NamedColorList; + + // Flag for transform involving v4 profiles + + BOOL lInputV4Lab, lOutputV4Lab; + + + // 1-pixel cache + + WORD CacheIn[MAXCHANNELS]; + WORD CacheOut[MAXCHANNELS]; + + double AdaptationState; // Figure for v4 incomplete state of adaptation + + LCMS_RWLOCK_T rwlock; + + } _cmsTRANSFORM,FAR *_LPcmsTRANSFORM; + + + +// Packing & Unpacking + +_cmsFIXFN cdecl _cmsIdentifyInputFormat(_LPcmsTRANSFORM xform, DWORD dwInput); +_cmsFIXFN cdecl _cmsIdentifyOutputFormat(_LPcmsTRANSFORM xform, DWORD dwOutput); + + +// Conversion + +#define XYZRel 0 +#define LabRel 1 + + +int cdecl cmsChooseCnvrt(int Absolute, + int Phase1, LPcmsCIEXYZ BlackPointIn, + LPcmsCIEXYZ WhitePointIn, + LPcmsCIEXYZ IlluminantIn, + LPMAT3 ChromaticAdaptationMatrixIn, + + int Phase2, LPcmsCIEXYZ BlackPointOut, + LPcmsCIEXYZ WhitePointOut, + LPcmsCIEXYZ IlluminantOut, + LPMAT3 ChromaticAdaptationMatrixOut, + int DoBPC, + double AdaptationState, + _cmsADJFN *fn1, + LPWMAT3 wm, LPWVEC3 wof); + + + +// Clamping & Gamut handling + +BOOL cdecl _cmsEndPointsBySpace(icColorSpaceSignature Space, + WORD **White, WORD **Black, int *nOutputs); + +WORD * cdecl _cmsWhiteBySpace(icColorSpaceSignature Space); + + + +WORD cdecl Clamp_L(Fixed32 in); +WORD cdecl Clamp_ab(Fixed32 in); + +// Detection of black point + +#define LCMS_BPFLAGS_D50_ADAPTED 0x0001 + +int cdecl cmsDetectBlackPoint(LPcmsCIEXYZ BlackPoint, cmsHPROFILE hProfile, int Intent, DWORD dwFlags); + +// choose reasonable resolution +int cdecl _cmsReasonableGridpointsByColorspace(icColorSpaceSignature Colorspace, DWORD dwFlags); + +// Precalculate device link +LPLUT cdecl _cmsPrecalculateDeviceLink(cmsHTRANSFORM h, DWORD dwFlags); + +// Precalculate black preserving device link +LPLUT _cmsPrecalculateBlackPreservingDeviceLink(cmsHTRANSFORM hCMYK2CMYK, DWORD dwFlags); + +// Precalculate gamut check +LPLUT cdecl _cmsPrecalculateGamutCheck(cmsHTRANSFORM h); + +// Hot fixes bad profiles +BOOL cdecl _cmsFixWhiteMisalignment(_LPcmsTRANSFORM p); + +// Marks LUT as 8 bit on input +LPLUT cdecl _cmsBlessLUT8(LPLUT Lut); + +// Compute gamut boundary +LPLUT cdecl _cmsComputeGamutLUT(cmsHPROFILE hProfile, int Intent); + +// Compute softproof +LPLUT cdecl _cmsComputeSoftProofLUT(cmsHPROFILE hProfile, int nIntent); + +// Find a suitable prelinearization tables, matching the given transform +void cdecl _cmsComputePrelinearizationTablesFromXFORM(cmsHTRANSFORM h[], int nTransforms, LPLUT Grid); + + +// Build a tone curve for K->K' if possible (only works on CMYK) +LPGAMMATABLE _cmsBuildKToneCurve(cmsHTRANSFORM hCMYK2CMYK, int nPoints); + +// These are two VITAL macros, from converting between 8 and 16 bit +// representation. + +#define RGB_8_TO_16(rgb) (WORD) ((((WORD) (rgb)) << 8)|(rgb)) +#define RGB_16_TO_8(rgb) (BYTE) ((((rgb) * 65281 + 8388608) >> 24) & 0xFF) + + +#endif // LCMS_APIONLY + + +#define __cms_H + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/winclude/libiptcdata/_stdint.h b/winclude/libiptcdata/_stdint.h new file mode 100755 index 000000000..80ecf419b --- /dev/null +++ b/winclude/libiptcdata/_stdint.h @@ -0,0 +1,2 @@ +/* This file is generated automatically by configure */ +#include diff --git a/winclude/libiptcdata/iptc-data.h b/winclude/libiptcdata/iptc-data.h new file mode 100755 index 000000000..a7ab8efa9 --- /dev/null +++ b/winclude/libiptcdata/iptc-data.h @@ -0,0 +1,106 @@ +/* iptc-data.h + * + * Copyright © 2005 David Moore + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __IPTC_DATA_H__ +#define __IPTC_DATA_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct _IptcData IptcData; +typedef struct _IptcDataPrivate IptcDataPrivate; + +#include +#include +#include +#include +#include + +typedef enum { + IPTC_ENCODING_UNKNOWN = 0, + IPTC_ENCODING_UNSPECIFIED = 1, + IPTC_ENCODING_UTF8 = 2 +} IptcEncoding; + +/* The version of the spec implemented by this library */ +#define IPTC_IIM_VERSION 4 + +struct _IptcData +{ + IptcDataSet **datasets; + unsigned int count; + + IptcDataPrivate *priv; +}; + +/* Lifecycle */ +IptcData *iptc_data_new (void); +IptcData *iptc_data_new_mem (IptcMem *mem); +IptcData *iptc_data_new_from_jpeg (const char *path); +IptcData *iptc_data_new_from_jpeg_file (FILE* infile); +IptcData *iptc_data_new_from_data (const unsigned char *buf, + unsigned int size); +void iptc_data_ref (IptcData *data); +void iptc_data_unref (IptcData *data); +void iptc_data_free (IptcData *data); + +int iptc_data_load (IptcData *data, const unsigned char *buf, + unsigned int size); +int iptc_data_save (IptcData *data, unsigned char **buf, + unsigned int *size); +void iptc_data_free_buf (IptcData *data, unsigned char *buf); + +int iptc_data_add_dataset (IptcData *data, IptcDataSet *ds); +int iptc_data_add_dataset_before (IptcData *data, IptcDataSet *ds, + IptcDataSet *newds); +int iptc_data_add_dataset_after (IptcData *data, IptcDataSet *ds, + IptcDataSet *newds); +int iptc_data_remove_dataset (IptcData *data, IptcDataSet *ds); +IptcDataSet *iptc_data_get_dataset (IptcData *data, IptcRecord record, + IptcTag tag); +IptcDataSet *iptc_data_get_next_dataset (IptcData *data, IptcDataSet *ds, + IptcRecord record, IptcTag tag); + +typedef void (* IptcDataForeachDataSetFunc) (IptcDataSet *dataset, + void *user_data); +void iptc_data_foreach_dataset (IptcData *data, + IptcDataForeachDataSetFunc func, + void *user_data); +void iptc_data_sort (IptcData *data); +IptcEncoding iptc_data_get_encoding (IptcData *data); +int iptc_data_set_encoding_utf8 (IptcData *data); + +int iptc_data_set_version (IptcData *data, unsigned int version); + +int iptc_data_add_dataset_with_value (IptcData *data, IptcRecord record, + IptcTag tag, unsigned int value, IptcValidate validate); +int iptc_data_add_dataset_with_contents (IptcData *data, IptcRecord record, + IptcTag tag, const unsigned char * buf, + unsigned int size, IptcValidate validate); + +void iptc_data_dump (IptcData *data, unsigned int indent); +void iptc_data_log (IptcData *data, IptcLog *log); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __IPTC_DATA_H__ */ diff --git a/winclude/libiptcdata/iptc-dataset.h b/winclude/libiptcdata/iptc-dataset.h new file mode 100755 index 000000000..1ad8abbb6 --- /dev/null +++ b/winclude/libiptcdata/iptc-dataset.h @@ -0,0 +1,92 @@ +/* iptc-dataset.h + * + * Copyright © 2005 David Moore + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __IPTC_DATASET_H__ +#define __IPTC_DATASET_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct _IptcDataSet IptcDataSet; +typedef struct _IptcDataSetPrivate IptcDataSetPrivate; + +typedef enum { + IPTC_DONT_VALIDATE = 0, + IPTC_VALIDATE = 1 +} IptcValidate; + +#include +#include + +struct _IptcDataSet { + IptcRecord record; + IptcTag tag; + const IptcTagInfo * info; + + unsigned char *data; + unsigned int size; + + /* Data containing this dataset */ + IptcData *parent; + + IptcDataSetPrivate *priv; +}; + + +/* Lifecycle */ +IptcDataSet *iptc_dataset_new (void); +IptcDataSet *iptc_dataset_new_mem (IptcMem * mem); +IptcDataSet *iptc_dataset_copy (IptcDataSet *dataset); +void iptc_dataset_ref (IptcDataSet *dataset); +void iptc_dataset_unref (IptcDataSet *dataset); +void iptc_dataset_free (IptcDataSet *dataset); + +void iptc_dataset_set_tag (IptcDataSet *dataset, IptcRecord record, IptcTag tag); +IptcFormat iptc_dataset_get_format (IptcDataSet *dataset); + +int iptc_dataset_get_data (IptcDataSet *dataset, unsigned char * buf, + unsigned int size); +unsigned int iptc_dataset_get_value (IptcDataSet *dataset); +int iptc_dataset_get_date (IptcDataSet *dataset, int *year, int *month, int *day); +int iptc_dataset_get_time (IptcDataSet *dataset, int *hour, int *min, int *sec, + int *tz); + +int iptc_dataset_set_data (IptcDataSet *dataset, const unsigned char * buf, + unsigned int size, IptcValidate validate); +int iptc_dataset_set_value (IptcDataSet *dataset, unsigned int value, + IptcValidate validate); +int iptc_dataset_set_date (IptcDataSet *dataset, int year, int month, int day, + IptcValidate validate); +int iptc_dataset_set_time (IptcDataSet *dataset, int hour, int min, int sec, + int tz, IptcValidate validate); + + +/* For your convenience */ +const char *iptc_dataset_get_as_str (IptcDataSet *dataset, char *buf, + unsigned int size); + +void iptc_dataset_dump (IptcDataSet *dataset, unsigned int indent); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __IPTC_DATASET_H__ */ diff --git a/winclude/libiptcdata/iptc-jpeg.h b/winclude/libiptcdata/iptc-jpeg.h new file mode 100755 index 000000000..cef3806e8 --- /dev/null +++ b/winclude/libiptcdata/iptc-jpeg.h @@ -0,0 +1,45 @@ +/* iptc-jpeg.h + * + * Copyright © 2005 David Moore + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __IPTC_JPEG_H__ +#define __IPTC_JPEG_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include + +int iptc_jpeg_read_ps3 (FILE * infile, unsigned char * buf, unsigned int size); +int iptc_jpeg_ps3_find_iptc (const unsigned char * ps3, + unsigned int ps3_size, unsigned int * iptc_len); + +int iptc_jpeg_ps3_save_iptc (const unsigned char * ps3, unsigned int ps3_size, + const unsigned char * iptc, unsigned int iptc_size, + unsigned char * buf, unsigned int size); +int iptc_jpeg_save_with_ps3 (FILE * infile, FILE * outfile, + const unsigned char * ps3, unsigned int ps3_size); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __IPTC_JPEG_H__ */ diff --git a/winclude/libiptcdata/iptc-log.h b/winclude/libiptcdata/iptc-log.h new file mode 100755 index 000000000..58f4ff255 --- /dev/null +++ b/winclude/libiptcdata/iptc-log.h @@ -0,0 +1,70 @@ +/* iptc-log.h + * + * Copyright © 2005 David Moore + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __IPTC_LOG_H__ +#define __IPTC_LOG_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include + +typedef struct _IptcLog IptcLog; + +IptcLog *iptc_log_new (void); +IptcLog *iptc_log_new_mem (IptcMem *); +void iptc_log_ref (IptcLog *log); +void iptc_log_unref (IptcLog *log); +void iptc_log_free (IptcLog *log); + +typedef enum { + IPTC_LOG_CODE_NONE, + IPTC_LOG_CODE_DEBUG, + IPTC_LOG_CODE_NO_MEMORY, + IPTC_LOG_CODE_CORRUPT_DATA +} IptcLogCode; +const char *iptc_log_code_get_title (IptcLogCode); /* Title for dialog */ +const char *iptc_log_code_get_message (IptcLogCode); /* Message for dialog */ + +typedef void (* IptcLogFunc) (IptcLog *log, IptcLogCode, const char *domain, + const char *format, va_list args, void *data); + +void iptc_log_set_func (IptcLog *log, IptcLogFunc func, void *data); + +void iptc_log (IptcLog *log, IptcLogCode, const char *domain, + const char *format, ...) +#ifdef __GNUC__ + __attribute__((__format__(printf,4,5))) +#endif +; + +void iptc_logv (IptcLog *log, IptcLogCode, const char *domain, + const char *format, va_list args); + +/* For your convenience */ +#define IPTC_LOG_NO_MEMORY(l,d,s) iptc_log (l, IPTC_LOG_CODE_NO_MEMORY, d, "Could not allocate %i byte(s).", s) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __IPTC_LOG_H__ */ diff --git a/winclude/libiptcdata/iptc-mem.h b/winclude/libiptcdata/iptc-mem.h new file mode 100755 index 000000000..8f884fe0d --- /dev/null +++ b/winclude/libiptcdata/iptc-mem.h @@ -0,0 +1,54 @@ +/* iptc-mem.h + * + * Copyright © 2005 David Moore + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __IPTC_MEM_H__ +#define __IPTC_MEM_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Should work like calloc: Needs to return initialized memory. */ +typedef void * (* IptcMemAllocFunc) (IptcLong); + +typedef void * (* IptcMemReallocFunc) (void *, IptcLong); +typedef void (* IptcMemFreeFunc) (void *); + +typedef struct _IptcMem IptcMem; + +IptcMem *iptc_mem_new (IptcMemAllocFunc, IptcMemReallocFunc, + IptcMemFreeFunc); +void iptc_mem_ref (IptcMem *); +void iptc_mem_unref (IptcMem *); + +void *iptc_mem_alloc (IptcMem *, IptcLong); +void *iptc_mem_realloc (IptcMem *, void *, IptcLong); +void iptc_mem_free (IptcMem *, void *); + +/* For your convenience */ +IptcMem *iptc_mem_new_default (void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __IPTC_MEM_H__ */ diff --git a/winclude/libiptcdata/iptc-tag.h b/winclude/libiptcdata/iptc-tag.h new file mode 100755 index 000000000..160673921 --- /dev/null +++ b/winclude/libiptcdata/iptc-tag.h @@ -0,0 +1,171 @@ +/* iptc-tag.h + * + * Copyright © 2001 David Moore + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __IPTC_TAG_H__ +#define __IPTC_TAG_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +typedef enum { + IPTC_RECORD_OBJECT_ENV = 1, + IPTC_RECORD_APP_2 = 2, + IPTC_RECORD_APP_3 = 3, + IPTC_RECORD_APP_4 = 4, + IPTC_RECORD_APP_5 = 5, + IPTC_RECORD_APP_6 = 6, + IPTC_RECORD_PREOBJ_DATA = 7, + IPTC_RECORD_OBJ_DATA = 8, + IPTC_RECORD_POSTOBJ_DATA = 9 +} IptcRecord; + +typedef enum { + IPTC_TAG_MODEL_VERSION = 0, /* Begin record 1 tags */ + IPTC_TAG_DESTINATION = 5, + IPTC_TAG_FILE_FORMAT = 20, + IPTC_TAG_FILE_VERSION = 22, + IPTC_TAG_SERVICE_ID = 30, + IPTC_TAG_ENVELOPE_NUM = 40, + IPTC_TAG_PRODUCT_ID = 50, + IPTC_TAG_ENVELOPE_PRIORITY = 60, + IPTC_TAG_DATE_SENT = 70, + IPTC_TAG_TIME_SENT = 80, + IPTC_TAG_CHARACTER_SET = 90, + IPTC_TAG_UNO = 100, + IPTC_TAG_ARM_ID = 120, + IPTC_TAG_ARM_VERSION = 122, /* End record 1 tags */ + IPTC_TAG_RECORD_VERSION = 0, /* Begin record 2 tags */ + IPTC_TAG_OBJECT_TYPE = 3, + IPTC_TAG_OBJECT_ATTRIBUTE = 4, + IPTC_TAG_OBJECT_NAME = 5, + IPTC_TAG_EDIT_STATUS = 7, + IPTC_TAG_EDITORIAL_UPDATE = 8, + IPTC_TAG_URGENCY = 10, + IPTC_TAG_SUBJECT_REFERENCE = 12, + IPTC_TAG_CATEGORY = 15, + IPTC_TAG_SUPPL_CATEGORY = 20, + IPTC_TAG_FIXTURE_ID = 22, + IPTC_TAG_KEYWORDS = 25, + IPTC_TAG_CONTENT_LOC_CODE = 26, + IPTC_TAG_CONTENT_LOC_NAME = 27, + IPTC_TAG_RELEASE_DATE = 30, + IPTC_TAG_RELEASE_TIME = 35, + IPTC_TAG_EXPIRATION_DATE = 37, + IPTC_TAG_EXPIRATION_TIME = 38, + IPTC_TAG_SPECIAL_INSTRUCTIONS = 40, + IPTC_TAG_ACTION_ADVISED = 42, + IPTC_TAG_REFERENCE_SERVICE = 45, + IPTC_TAG_REFERENCE_DATE = 47, + IPTC_TAG_REFERENCE_NUMBER = 50, + IPTC_TAG_DATE_CREATED = 55, + IPTC_TAG_TIME_CREATED = 60, + IPTC_TAG_DIGITAL_CREATION_DATE = 62, + IPTC_TAG_DIGITAL_CREATION_TIME = 63, + IPTC_TAG_ORIGINATING_PROGRAM = 65, + IPTC_TAG_PROGRAM_VERSION = 70, + IPTC_TAG_OBJECT_CYCLE = 75, + IPTC_TAG_BYLINE = 80, + IPTC_TAG_BYLINE_TITLE = 85, + IPTC_TAG_CITY = 90, + IPTC_TAG_SUBLOCATION = 92, + IPTC_TAG_STATE = 95, + IPTC_TAG_COUNTRY_CODE = 100, + IPTC_TAG_COUNTRY_NAME = 101, + IPTC_TAG_ORIG_TRANS_REF = 103, + IPTC_TAG_HEADLINE = 105, + IPTC_TAG_CREDIT = 110, + IPTC_TAG_SOURCE = 115, + IPTC_TAG_COPYRIGHT_NOTICE = 116, + IPTC_TAG_PICASA_UNKNOWN = 117, + IPTC_TAG_CONTACT = 118, + IPTC_TAG_CAPTION = 120, + IPTC_TAG_WRITER_EDITOR = 122, + IPTC_TAG_RASTERIZED_CAPTION = 125, + IPTC_TAG_IMAGE_TYPE = 130, + IPTC_TAG_IMAGE_ORIENTATION = 131, + IPTC_TAG_LANGUAGE_ID = 135, + IPTC_TAG_AUDIO_TYPE = 150, + IPTC_TAG_AUDIO_SAMPLING_RATE = 151, + IPTC_TAG_AUDIO_SAMPLING_RES = 152, + IPTC_TAG_AUDIO_DURATION = 153, + IPTC_TAG_AUDIO_OUTCUE = 154, + IPTC_TAG_PREVIEW_FORMAT = 200, + IPTC_TAG_PREVIEW_FORMAT_VER = 201, + IPTC_TAG_PREVIEW_DATA = 202, /* End record 2 tags */ + IPTC_TAG_SIZE_MODE = 10, /* Begin record 7 tags */ + IPTC_TAG_MAX_SUBFILE_SIZE = 20, + IPTC_TAG_SIZE_ANNOUNCED = 90, + IPTC_TAG_MAX_OBJECT_SIZE = 95, /* End record 7 tags */ + IPTC_TAG_SUBFILE = 10, /* Record 8 tags */ + IPTC_TAG_CONFIRMED_DATA_SIZE = 10 /* Record 9 tags */ +} IptcTag; + +typedef enum { + IPTC_OPTIONAL = 0, + IPTC_MANDATORY = 1 +} IptcMandatory; + +typedef enum { + IPTC_NOT_REPEATABLE = 0, + IPTC_REPEATABLE = 1 +} IptcRepeatable; + +typedef enum { + IPTC_FORMAT_UNKNOWN, + IPTC_FORMAT_BINARY, + IPTC_FORMAT_BYTE, + IPTC_FORMAT_SHORT, + IPTC_FORMAT_LONG, + IPTC_FORMAT_STRING, + IPTC_FORMAT_NUMERIC_STRING, + IPTC_FORMAT_DATE, + IPTC_FORMAT_TIME +} IptcFormat; + +typedef struct _IptcTagInfo IptcTagInfo; + +struct _IptcTagInfo { + IptcRecord record; + IptcTag tag; + const char *name; + const char *title; + const char *description; + IptcFormat format; + IptcMandatory mandatory; + IptcRepeatable repeatable; + unsigned int minbytes; + unsigned int maxbytes; +}; + +const char *iptc_tag_get_name (IptcRecord record, IptcTag tag); +char *iptc_tag_get_title (IptcRecord record, IptcTag tag); +char *iptc_tag_get_description (IptcRecord record, IptcTag tag); +const IptcTagInfo *iptc_tag_get_info (IptcRecord record, IptcTag tag); +char *iptc_format_get_name (IptcFormat format); + +int iptc_tag_find_by_name (const char * name, IptcRecord * record, IptcTag * tag); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __IPTC_TAG_H__ */ diff --git a/winclude/libiptcdata/iptc-utils.h b/winclude/libiptcdata/iptc-utils.h new file mode 100755 index 000000000..53091a0a2 --- /dev/null +++ b/winclude/libiptcdata/iptc-utils.h @@ -0,0 +1,66 @@ +/* iptc-utils.h + * + * Copyright © 2005 David Moore + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __IPTC_UTILS_H__ +#define __IPTC_UTILS_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include + +typedef enum { + IPTC_BYTE_ORDER_MOTOROLA, + IPTC_BYTE_ORDER_INTEL +} IptcByteOrder; + + +/* If these definitions don't work for you, please let us fix the + * macro generating _stdint.h */ + +typedef char IptcByte; /* 1 byte */ +typedef uint16_t IptcShort; /* 2 bytes */ +typedef uint32_t IptcLong; /* 4 bytes */ +typedef int32_t IptcSLong; /* 4 bytes */ + + +IptcShort iptc_get_short (const unsigned char *b, IptcByteOrder order); +IptcLong iptc_get_long (const unsigned char *b, IptcByteOrder order); +IptcSLong iptc_get_slong (const unsigned char *b, IptcByteOrder order); + +void iptc_set_short (unsigned char *b, IptcByteOrder order, + IptcShort value); +void iptc_set_long (unsigned char *b, IptcByteOrder order, + IptcLong value); +void iptc_set_slong (unsigned char *b, IptcByteOrder order, + IptcSLong value); + +#undef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +/* For compatibility with older versions */ +#define IPTC_TAG_SUBSEC_TIME IPTC_TAG_SUB_SEC_TIME + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __IPTC_UTILS_H__ */ diff --git a/winclude/png.h b/winclude/png.h new file mode 100755 index 000000000..71cfcdd0b --- /dev/null +++ b/winclude/png.h @@ -0,0 +1,3283 @@ +/* png.h - header file for PNG reference library + * + * libpng version 1.2.5 - October 3, 2002 + * Copyright (c) 1998-2002 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * Authors and maintainers: + * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat + * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger + * libpng versions 0.97, January 1998, through 1.2.5 - October 3, 2002: Glenn + * See also "Contributing Authors", below. + * + * Note about libpng version numbers: + * + * Due to various miscommunications, unforeseen code incompatibilities + * and occasional factors outside the authors' control, version numbering + * on the library has not always been consistent and straightforward. + * The following table summarizes matters since version 0.89c, which was + * the first widely used release: + * + * source png.h png.h shared-lib + * version string int version + * ------- ------ ----- ---------- + * 0.89c "1.0 beta 3" 0.89 89 1.0.89 + * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90] + * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95] + * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96] + * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97] + * 0.97c 0.97 97 2.0.97 + * 0.98 0.98 98 2.0.98 + * 0.99 0.99 98 2.0.99 + * 0.99a-m 0.99 99 2.0.99 + * 1.00 1.00 100 2.1.0 [100 should be 10000] + * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000] + * 1.0.1 png.h string is 10001 2.1.0 + * 1.0.1a-e identical to the 10002 from here on, the shared library + * 1.0.2 source version) 10002 is 2.V where V is the source code + * 1.0.2a-b 10003 version, except as noted. + * 1.0.3 10003 + * 1.0.3a-d 10004 + * 1.0.4 10004 + * 1.0.4a-f 10005 + * 1.0.5 (+ 2 patches) 10005 + * 1.0.5a-d 10006 + * 1.0.5e-r 10100 (not source compatible) + * 1.0.5s-v 10006 (not binary compatible) + * 1.0.6 (+ 3 patches) 10006 (still binary incompatible) + * 1.0.6d-f 10007 (still binary incompatible) + * 1.0.6g 10007 + * 1.0.6h 10007 10.6h (testing xy.z so-numbering) + * 1.0.6i 10007 10.6i + * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0) + * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible) + * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible) + * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) + * 1.0.7 1 10007 (still compatible) + * 1.0.8beta1-4 1 10008 2.1.0.8beta1-4 + * 1.0.8rc1 1 10008 2.1.0.8rc1 + * 1.0.8 1 10008 2.1.0.8 + * 1.0.9beta1-6 1 10009 2.1.0.9beta1-6 + * 1.0.9rc1 1 10009 2.1.0.9rc1 + * 1.0.9beta7-10 1 10009 2.1.0.9beta7-10 + * 1.0.9rc2 1 10009 2.1.0.9rc2 + * 1.0.9 1 10009 2.1.0.9 + * 1.0.10beta1 1 10010 2.1.0.10beta1 + * 1.0.10rc1 1 10010 2.1.0.10rc1 + * 1.0.10 1 10010 2.1.0.10 + * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3 + * 1.0.11rc1 1 10011 2.1.0.11rc1 + * 1.0.11 1 10011 2.1.0.11 + * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2 + * 1.0.12rc1 2 10012 2.1.0.12rc1 + * 1.0.12 2 10012 2.1.0.12 + * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned) + * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2 + * 1.2.0beta3-5 3 10200 3.1.2.0beta3-5 + * 1.2.0rc1 3 10200 3.1.2.0rc1 + * 1.2.0 3 10200 3.1.2.0 + * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4 + * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2 + * 1.2.1 3 10201 3.1.2.1 + * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6 + * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1 + * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1 + * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1 + * 1.0.13 10 10013 10.so.0.1.0.13 + * 1.2.2 12 10202 12.so.0.1.2.2 + * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6 + * 1.2.3 12 10203 12.so.0.1.2.3 + * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3 + * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1 + * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1 + * 1.0.14 10 10014 10.so.0.1.0.14 + * 1.2.4 13 10204 12.so.0.1.2.4 + * 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2 + * 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3 + * 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3 + * 1.0.15 10 10015 10.so.0.1.0.15 + * 1.2.5 13 10205 12.so.0.1.2.5 + * + * Henceforth the source version will match the shared-library major + * and minor numbers; the shared-library major version number will be + * used for changes in backward compatibility, as it is intended. The + * PNG_LIBPNG_VER macro, which is not used within libpng but is available + * for applications, is an unsigned integer of the form xyyzz corresponding + * to the source version x.y.z (leading zeros in y and z). Beta versions + * were given the previous public release number plus a letter, until + * version 1.0.6j; from then on they were given the upcoming public + * release number plus "betaNN" or "rcN". + * + * Binary incompatibility exists only when applications make direct access + * to the info_ptr or png_ptr members through png.h, and the compiled + * application is loaded with a different version of the library. + * + * DLLNUM will change each time there are forward or backward changes + * in binary compatibility (e.g., when a new feature is added). + * + * See libpng.txt or libpng.3 for more information. The PNG specification + * is available as RFC 2083 + * and as a W3C Recommendation + */ + +/* + * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: + * + * If you modify libpng you may insert additional notices immediately following + * this sentence. + * + * libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are + * Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are + * distributed according to the same disclaimer and license as libpng-1.0.6 + * with the following individuals added to the list of Contributing Authors + * + * Simon-Pierre Cadieux + * Eric S. Raymond + * Gilles Vollant + * + * and with the following additions to the disclaimer: + * + * There is no warranty against interference with your enjoyment of the + * library or against infringement. There is no warranty that our + * efforts or the library will fulfill any of your particular purposes + * or needs. This library is provided with all faults, and the entire + * risk of satisfactory quality, performance, accuracy, and effort is with + * the user. + * + * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are + * Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson + * Distributed according to the same disclaimer and license as libpng-0.96, + * with the following individuals added to the list of Contributing Authors: + * + * Tom Lane + * Glenn Randers-Pehrson + * Willem van Schaik + * + * libpng versions 0.89, June 1996, through 0.96, May 1997, are + * Copyright (c) 1996, 1997 Andreas Dilger + * Distributed according to the same disclaimer and license as libpng-0.88, + * with the following individuals added to the list of Contributing Authors: + * + * John Bowler + * Kevin Bracey + * Sam Bushell + * Magnus Holmgren + * Greg Roelofs + * Tom Tanner + * + * libpng versions 0.5, May 1995, through 0.88, January 1996, are + * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. + * + * For the purposes of this copyright and license, "Contributing Authors" + * is defined as the following set of individuals: + * + * Andreas Dilger + * Dave Martindale + * Guy Eric Schalnat + * Paul Schmidt + * Tim Wegner + * + * The PNG Reference Library is supplied "AS IS". The Contributing Authors + * and Group 42, Inc. disclaim all warranties, expressed or implied, + * including, without limitation, the warranties of merchantability and of + * fitness for any purpose. The Contributing Authors and Group 42, Inc. + * assume no liability for direct, indirect, incidental, special, exemplary, + * or consequential damages, which may result from the use of the PNG + * Reference Library, even if advised of the possibility of such damage. + * + * Permission is hereby granted to use, copy, modify, and distribute this + * source code, or portions hereof, for any purpose, without fee, subject + * to the following restrictions: + * + * 1. The origin of this source code must not be misrepresented. + * + * 2. Altered versions must be plainly marked as such and + * must not be misrepresented as being the original source. + * + * 3. This Copyright notice may not be removed or altered from + * any source or altered source distribution. + * + * The Contributing Authors and Group 42, Inc. specifically permit, without + * fee, and encourage the use of this source code as a component to + * supporting the PNG file format in commercial products. If you use this + * source code in a product, acknowledgment is not required but would be + * appreciated. + */ + +/* + * A "png_get_copyright" function is available, for convenient use in "about" + * boxes and the like: + * + * printf("%s",png_get_copyright(NULL)); + * + * Also, the PNG logo (in PNG format, of course) is supplied in the + * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). + */ + +/* + * Libpng is OSI Certified Open Source Software. OSI Certified is a + * certification mark of the Open Source Initiative. + */ + +/* + * The contributing authors would like to thank all those who helped + * with testing, bug fixes, and patience. This wouldn't have been + * possible without all of you. + * + * Thanks to Frank J. T. Wojcik for helping with the documentation. + */ + +/* + * Y2K compliance in libpng: + * ========================= + * + * October 3, 2002 + * + * Since the PNG Development group is an ad-hoc body, we can't make + * an official declaration. + * + * This is your unofficial assurance that libpng from version 0.71 and + * upward through 1.2.5 are Y2K compliant. It is my belief that earlier + * versions were also Y2K compliant. + * + * Libpng only has three year fields. One is a 2-byte unsigned integer + * that will hold years up to 65535. The other two hold the date in text + * format, and will hold years up to 9999. + * + * The integer is + * "png_uint_16 year" in png_time_struct. + * + * The strings are + * "png_charp time_buffer" in png_struct and + * "near_time_buffer", which is a local character string in png.c. + * + * There are seven time-related functions: + * png.c: png_convert_to_rfc_1123() in png.c + * (formerly png_convert_to_rfc_1152() in error) + * png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c + * png_convert_from_time_t() in pngwrite.c + * png_get_tIME() in pngget.c + * png_handle_tIME() in pngrutil.c, called in pngread.c + * png_set_tIME() in pngset.c + * png_write_tIME() in pngwutil.c, called in pngwrite.c + * + * All handle dates properly in a Y2K environment. The + * png_convert_from_time_t() function calls gmtime() to convert from system + * clock time, which returns (year - 1900), which we properly convert to + * the full 4-digit year. There is a possibility that applications using + * libpng are not passing 4-digit years into the png_convert_to_rfc_1123() + * function, or that they are incorrectly passing only a 2-digit year + * instead of "year - 1900" into the png_convert_from_struct_tm() function, + * but this is not under our control. The libpng documentation has always + * stated that it works with 4-digit years, and the APIs have been + * documented as such. + * + * The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned + * integer to hold the year, and can hold years as large as 65535. + * + * zlib, upon which libpng depends, is also Y2K compliant. It contains + * no date-related code. + * + * Glenn Randers-Pehrson + * libpng maintainer + * PNG Development Group + */ + +#ifndef PNG_H +#define PNG_H + +/* This is not the place to learn how to use libpng. The file libpng.txt + * describes how to use libpng, and the file example.c summarizes it + * with some code on which to build. This file is useful for looking + * at the actual function definitions and structure components. + */ + +/* Version information for png.h - this should match the version in png.c */ +#define PNG_LIBPNG_VER_STRING "1.2.5" + +#define PNG_LIBPNG_VER_SONUM 0 +#define PNG_LIBPNG_VER_DLLNUM %DLLNUM% + +/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ +#define PNG_LIBPNG_VER_MAJOR 1 +#define PNG_LIBPNG_VER_MINOR 2 +#define PNG_LIBPNG_VER_RELEASE 5 +/* This should match the numeric part of the final component of + * PNG_LIBPNG_VER_STRING, omitting any leading zero: */ + +#define PNG_LIBPNG_VER_BUILD 0 + +#define PNG_LIBPNG_BUILD_ALPHA 1 +#define PNG_LIBPNG_BUILD_BETA 2 +#define PNG_LIBPNG_BUILD_RC 3 +#define PNG_LIBPNG_BUILD_STABLE 4 +#define PNG_LIBPNG_BUILD_TYPEMASK 7 +#define PNG_LIBPNG_BUILD_PATCH 8 /* Can be OR'ed with STABLE only */ +#define PNG_LIBPNG_BUILD_TYPE 4 + +/* Careful here. At one time, Guy wanted to use 082, but that would be octal. + * We must not include leading zeros. + * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only + * version 1.0.0 was mis-numbered 100 instead of 10000). From + * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release */ +#define PNG_LIBPNG_VER 10205 /* 1.2.5 */ + +#ifndef PNG_VERSION_INFO_ONLY + +/* include the compression library's header */ +#include "zlib.h" + +/* include all user configurable info, including optional assembler routines */ +#include "pngconf.h" + +/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* This file is arranged in several sections. The first section contains + * structure and type definitions. The second section contains the external + * library functions, while the third has the internal library functions, + * which applications aren't expected to use directly. + */ + +#ifndef PNG_NO_TYPECAST_NULL +#define int_p_NULL (int *)NULL +#define png_bytep_NULL (png_bytep)NULL +#define png_bytepp_NULL (png_bytepp)NULL +#define png_doublep_NULL (png_doublep)NULL +#define png_error_ptr_NULL (png_error_ptr)NULL +#define png_flush_ptr_NULL (png_flush_ptr)NULL +#define png_free_ptr_NULL (png_free_ptr)NULL +#define png_infopp_NULL (png_infopp)NULL +#define png_malloc_ptr_NULL (png_malloc_ptr)NULL +#define png_read_status_ptr_NULL (png_read_status_ptr)NULL +#define png_rw_ptr_NULL (png_rw_ptr)NULL +#define png_structp_NULL (png_structp)NULL +#define png_uint_16p_NULL (png_uint_16p)NULL +#define png_voidp_NULL (png_voidp)NULL +#define png_write_status_ptr_NULL (png_write_status_ptr)NULL +#else +#define int_p_NULL NULL +#define png_bytep_NULL NULL +#define png_bytepp_NULL NULL +#define png_doublep_NULL NULL +#define png_error_ptr_NULL NULL +#define png_flush_ptr_NULL NULL +#define png_free_ptr_NULL NULL +#define png_infopp_NULL NULL +#define png_malloc_ptr_NULL NULL +#define png_read_status_ptr_NULL NULL +#define png_rw_ptr_NULL NULL +#define png_structp_NULL NULL +#define png_uint_16p_NULL NULL +#define png_voidp_NULL NULL +#define png_write_status_ptr_NULL NULL +#endif + +/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */ +#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN) +/* Version information for C files, stored in png.c. This had better match + * the version above. + */ +#ifdef PNG_USE_GLOBAL_ARRAYS +PNG_EXPORT_VAR (const char) png_libpng_ver[18]; + /* need room for 99.99.99beta99z */ +#else +#define png_libpng_ver png_get_header_ver(NULL) +#endif + +#ifdef PNG_USE_GLOBAL_ARRAYS +/* This was removed in version 1.0.5c */ +/* Structures to facilitate easy interlacing. See png.c for more details */ +PNG_EXPORT_VAR (const int FARDATA) png_pass_start[7]; +PNG_EXPORT_VAR (const int FARDATA) png_pass_inc[7]; +PNG_EXPORT_VAR (const int FARDATA) png_pass_ystart[7]; +PNG_EXPORT_VAR (const int FARDATA) png_pass_yinc[7]; +PNG_EXPORT_VAR (const int FARDATA) png_pass_mask[7]; +PNG_EXPORT_VAR (const int FARDATA) png_pass_dsp_mask[7]; +#ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW +PNG_EXPORT_VAR (const int FARDATA) png_pass_width[7]; +#endif +/* This isn't currently used. If you need it, see png.c for more details. +PNG_EXPORT_VAR (const int FARDATA) png_pass_height[7]; +*/ +#endif + +#endif /* PNG_NO_EXTERN */ + +/* Three color definitions. The order of the red, green, and blue, (and the + * exact size) is not important, although the size of the fields need to + * be png_byte or png_uint_16 (as defined below). + */ +typedef struct png_color_struct +{ + png_byte red; + png_byte green; + png_byte blue; +} png_color; +typedef png_color FAR * png_colorp; +typedef png_color FAR * FAR * png_colorpp; + +typedef struct png_color_16_struct +{ + png_byte index; /* used for palette files */ + png_uint_16 red; /* for use in red green blue files */ + png_uint_16 green; + png_uint_16 blue; + png_uint_16 gray; /* for use in grayscale files */ +} png_color_16; +typedef png_color_16 FAR * png_color_16p; +typedef png_color_16 FAR * FAR * png_color_16pp; + +typedef struct png_color_8_struct +{ + png_byte red; /* for use in red green blue files */ + png_byte green; + png_byte blue; + png_byte gray; /* for use in grayscale files */ + png_byte alpha; /* for alpha channel files */ +} png_color_8; +typedef png_color_8 FAR * png_color_8p; +typedef png_color_8 FAR * FAR * png_color_8pp; + +/* + * The following two structures are used for the in-core representation + * of sPLT chunks. + */ +typedef struct png_sPLT_entry_struct +{ + png_uint_16 red; + png_uint_16 green; + png_uint_16 blue; + png_uint_16 alpha; + png_uint_16 frequency; +} png_sPLT_entry; +typedef png_sPLT_entry FAR * png_sPLT_entryp; +typedef png_sPLT_entry FAR * FAR * png_sPLT_entrypp; + +/* When the depth of the sPLT palette is 8 bits, the color and alpha samples + * occupy the LSB of their respective members, and the MSB of each member + * is zero-filled. The frequency member always occupies the full 16 bits. + */ + +typedef struct png_sPLT_struct +{ + png_charp name; /* palette name */ + png_byte depth; /* depth of palette samples */ + png_sPLT_entryp entries; /* palette entries */ + png_int_32 nentries; /* number of palette entries */ +} png_sPLT_t; +typedef png_sPLT_t FAR * png_sPLT_tp; +typedef png_sPLT_t FAR * FAR * png_sPLT_tpp; + +#ifdef PNG_TEXT_SUPPORTED +/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file, + * and whether that contents is compressed or not. The "key" field + * points to a regular zero-terminated C string. The "text", "lang", and + * "lang_key" fields can be regular C strings, empty strings, or NULL pointers. + * However, the * structure returned by png_get_text() will always contain + * regular zero-terminated C strings (possibly empty), never NULL pointers, + * so they can be safely used in printf() and other string-handling functions. + */ +typedef struct png_text_struct +{ + int compression; /* compression value: + -1: tEXt, none + 0: zTXt, deflate + 1: iTXt, none + 2: iTXt, deflate */ + png_charp key; /* keyword, 1-79 character description of "text" */ + png_charp text; /* comment, may be an empty string (ie "") + or a NULL pointer */ + png_size_t text_length; /* length of the text string */ +#ifdef PNG_iTXt_SUPPORTED + png_size_t itxt_length; /* length of the itxt string */ + png_charp lang; /* language code, 0-79 characters + or a NULL pointer */ + png_charp lang_key; /* keyword translated UTF-8 string, 0 or more + chars or a NULL pointer */ +#endif +} png_text; +typedef png_text FAR * png_textp; +typedef png_text FAR * FAR * png_textpp; +#endif + +/* Supported compression types for text in PNG files (tEXt, and zTXt). + * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */ +#define PNG_TEXT_COMPRESSION_NONE_WR -3 +#define PNG_TEXT_COMPRESSION_zTXt_WR -2 +#define PNG_TEXT_COMPRESSION_NONE -1 +#define PNG_TEXT_COMPRESSION_zTXt 0 +#define PNG_ITXT_COMPRESSION_NONE 1 +#define PNG_ITXT_COMPRESSION_zTXt 2 +#define PNG_TEXT_COMPRESSION_LAST 3 /* Not a valid value */ + +/* png_time is a way to hold the time in an machine independent way. + * Two conversions are provided, both from time_t and struct tm. There + * is no portable way to convert to either of these structures, as far + * as I know. If you know of a portable way, send it to me. As a side + * note - PNG has always been Year 2000 compliant! + */ +typedef struct png_time_struct +{ + png_uint_16 year; /* full year, as in, 1995 */ + png_byte month; /* month of year, 1 - 12 */ + png_byte day; /* day of month, 1 - 31 */ + png_byte hour; /* hour of day, 0 - 23 */ + png_byte minute; /* minute of hour, 0 - 59 */ + png_byte second; /* second of minute, 0 - 60 (for leap seconds) */ +} png_time; +typedef png_time FAR * png_timep; +typedef png_time FAR * FAR * png_timepp; + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +/* png_unknown_chunk is a structure to hold queued chunks for which there is + * no specific support. The idea is that we can use this to queue + * up private chunks for output even though the library doesn't actually + * know about their semantics. + */ +typedef struct png_unknown_chunk_t +{ + png_byte name[5]; + png_byte *data; + png_size_t size; + + /* libpng-using applications should NOT directly modify this byte. */ + png_byte location; /* mode of operation at read time */ +} +png_unknown_chunk; +typedef png_unknown_chunk FAR * png_unknown_chunkp; +typedef png_unknown_chunk FAR * FAR * png_unknown_chunkpp; +#endif + +/* png_info is a structure that holds the information in a PNG file so + * that the application can find out the characteristics of the image. + * If you are reading the file, this structure will tell you what is + * in the PNG file. If you are writing the file, fill in the information + * you want to put into the PNG file, then call png_write_info(). + * The names chosen should be very close to the PNG specification, so + * consult that document for information about the meaning of each field. + * + * With libpng < 0.95, it was only possible to directly set and read the + * the values in the png_info_struct, which meant that the contents and + * order of the values had to remain fixed. With libpng 0.95 and later, + * however, there are now functions that abstract the contents of + * png_info_struct from the application, so this makes it easier to use + * libpng with dynamic libraries, and even makes it possible to use + * libraries that don't have all of the libpng ancillary chunk-handing + * functionality. + * + * In any case, the order of the parameters in png_info_struct should NOT + * be changed for as long as possible to keep compatibility with applications + * that use the old direct-access method with png_info_struct. + * + * The following members may have allocated storage attached that should be + * cleaned up before the structure is discarded: palette, trans, text, + * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile, + * splt_palettes, scal_unit, row_pointers, and unknowns. By default, these + * are automatically freed when the info structure is deallocated, if they were + * allocated internally by libpng. This behavior can be changed by means + * of the png_data_freer() function. + * + * More allocation details: all the chunk-reading functions that + * change these members go through the corresponding png_set_* + * functions. A function to clear these members is available: see + * png_free_data(). The png_set_* functions do not depend on being + * able to point info structure members to any of the storage they are + * passed (they make their own copies), EXCEPT that the png_set_text + * functions use the same storage passed to them in the text_ptr or + * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns + * functions do not make their own copies. + */ +typedef struct png_info_struct +{ + /* the following are necessary for every PNG file */ + png_uint_32 width; /* width of image in pixels (from IHDR) */ + png_uint_32 height; /* height of image in pixels (from IHDR) */ + png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */ + png_uint_32 rowbytes; /* bytes needed to hold an untransformed row */ + png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */ + png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */ + png_uint_16 num_trans; /* number of transparent palette color (tRNS) */ + png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */ + png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */ + /* The following three should have been named *_method not *_type */ + png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */ + png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */ + png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ + + /* The following is informational only on read, and not used on writes. */ + png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */ + png_byte pixel_depth; /* number of bits per pixel */ + png_byte spare_byte; /* to align the data, and for future use */ + png_byte signature[8]; /* magic bytes read by libpng from start of file */ + + /* The rest of the data is optional. If you are reading, check the + * valid field to see if the information in these are valid. If you + * are writing, set the valid field to those chunks you want written, + * and initialize the appropriate fields below. + */ + +#if defined(PNG_gAMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) + /* The gAMA chunk describes the gamma characteristics of the system + * on which the image was created, normally in the range [1.0, 2.5]. + * Data is valid if (valid & PNG_INFO_gAMA) is non-zero. + */ + float gamma; /* gamma value of image, if (valid & PNG_INFO_gAMA) */ +#endif + +#if defined(PNG_sRGB_SUPPORTED) + /* GR-P, 0.96a */ + /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */ + png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */ +#endif + +#if defined(PNG_TEXT_SUPPORTED) + /* The tEXt, and zTXt chunks contain human-readable textual data in + * uncompressed, compressed, and optionally compressed forms, respectively. + * The data in "text" is an array of pointers to uncompressed, + * null-terminated C strings. Each chunk has a keyword that describes the + * textual data contained in that chunk. Keywords are not required to be + * unique, and the text string may be empty. Any number of text chunks may + * be in an image. + */ + int num_text; /* number of comments read/to write */ + int max_text; /* current size of text array */ + png_textp text; /* array of comments read/to write */ +#endif /* PNG_TEXT_SUPPORTED */ + +#if defined(PNG_tIME_SUPPORTED) + /* The tIME chunk holds the last time the displayed image data was + * modified. See the png_time struct for the contents of this struct. + */ + png_time mod_time; +#endif + +#if defined(PNG_sBIT_SUPPORTED) + /* The sBIT chunk specifies the number of significant high-order bits + * in the pixel data. Values are in the range [1, bit_depth], and are + * only specified for the channels in the pixel data. The contents of + * the low-order bits is not specified. Data is valid if + * (valid & PNG_INFO_sBIT) is non-zero. + */ + png_color_8 sig_bit; /* significant bits in color channels */ +#endif + +#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \ +defined(PNG_READ_BACKGROUND_SUPPORTED) + /* The tRNS chunk supplies transparency data for paletted images and + * other image types that don't need a full alpha channel. There are + * "num_trans" transparency values for a paletted image, stored in the + * same order as the palette colors, starting from index 0. Values + * for the data are in the range [0, 255], ranging from fully transparent + * to fully opaque, respectively. For non-paletted images, there is a + * single color specified that should be treated as fully transparent. + * Data is valid if (valid & PNG_INFO_tRNS) is non-zero. + */ + png_bytep trans; /* transparent values for paletted image */ + png_color_16 trans_values; /* transparent color for non-palette image */ +#endif + +#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + /* The bKGD chunk gives the suggested image background color if the + * display program does not have its own background color and the image + * is needs to composited onto a background before display. The colors + * in "background" are normally in the same color space/depth as the + * pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero. + */ + png_color_16 background; +#endif + +#if defined(PNG_oFFs_SUPPORTED) + /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards + * and downwards from the top-left corner of the display, page, or other + * application-specific co-ordinate space. See the PNG_OFFSET_ defines + * below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero. + */ + png_int_32 x_offset; /* x offset on page */ + png_int_32 y_offset; /* y offset on page */ + png_byte offset_unit_type; /* offset units type */ +#endif + +#if defined(PNG_pHYs_SUPPORTED) + /* The pHYs chunk gives the physical pixel density of the image for + * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_ + * defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero. + */ + png_uint_32 x_pixels_per_unit; /* horizontal pixel density */ + png_uint_32 y_pixels_per_unit; /* vertical pixel density */ + png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */ +#endif + +#if defined(PNG_hIST_SUPPORTED) + /* The hIST chunk contains the relative frequency or importance of the + * various palette entries, so that a viewer can intelligently select a + * reduced-color palette, if required. Data is an array of "num_palette" + * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST) + * is non-zero. + */ + png_uint_16p hist; +#endif + +#ifdef PNG_cHRM_SUPPORTED + /* The cHRM chunk describes the CIE color characteristics of the monitor + * on which the PNG was created. This data allows the viewer to do gamut + * mapping of the input image to ensure that the viewer sees the same + * colors in the image as the creator. Values are in the range + * [0.0, 0.8]. Data valid if (valid & PNG_INFO_cHRM) non-zero. + */ +#ifdef PNG_FLOATING_POINT_SUPPORTED + float x_white; + float y_white; + float x_red; + float y_red; + float x_green; + float y_green; + float x_blue; + float y_blue; +#endif +#endif + +#if defined(PNG_pCAL_SUPPORTED) + /* The pCAL chunk describes a transformation between the stored pixel + * values and original physical data values used to create the image. + * The integer range [0, 2^bit_depth - 1] maps to the floating-point + * range given by [pcal_X0, pcal_X1], and are further transformed by a + * (possibly non-linear) transformation function given by "pcal_type" + * and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_ + * defines below, and the PNG-Group's PNG extensions document for a + * complete description of the transformations and how they should be + * implemented, and for a description of the ASCII parameter strings. + * Data values are valid if (valid & PNG_INFO_pCAL) non-zero. + */ + png_charp pcal_purpose; /* pCAL chunk description string */ + png_int_32 pcal_X0; /* minimum value */ + png_int_32 pcal_X1; /* maximum value */ + png_charp pcal_units; /* Latin-1 string giving physical units */ + png_charpp pcal_params; /* ASCII strings containing parameter values */ + png_byte pcal_type; /* equation type (see PNG_EQUATION_ below) */ + png_byte pcal_nparams; /* number of parameters given in pcal_params */ +#endif + +/* New members added in libpng-1.0.6 */ +#ifdef PNG_FREE_ME_SUPPORTED + png_uint_32 free_me; /* flags items libpng is responsible for freeing */ +#endif + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + /* storage for unknown chunks that the library doesn't recognize. */ + png_unknown_chunkp unknown_chunks; + png_size_t unknown_chunks_num; +#endif + +#if defined(PNG_iCCP_SUPPORTED) + /* iCCP chunk data. */ + png_charp iccp_name; /* profile name */ + png_charp iccp_profile; /* International Color Consortium profile data */ + /* Note to maintainer: should be png_bytep */ + png_uint_32 iccp_proflen; /* ICC profile data length */ + png_byte iccp_compression; /* Always zero */ +#endif + +#if defined(PNG_sPLT_SUPPORTED) + /* data on sPLT chunks (there may be more than one). */ + png_sPLT_tp splt_palettes; + png_uint_32 splt_palettes_num; +#endif + +#if defined(PNG_sCAL_SUPPORTED) + /* The sCAL chunk describes the actual physical dimensions of the + * subject matter of the graphic. The chunk contains a unit specification + * a byte value, and two ASCII strings representing floating-point + * values. The values are width and height corresponsing to one pixel + * in the image. This external representation is converted to double + * here. Data values are valid if (valid & PNG_INFO_sCAL) is non-zero. + */ + png_byte scal_unit; /* unit of physical scale */ +#ifdef PNG_FLOATING_POINT_SUPPORTED + double scal_pixel_width; /* width of one pixel */ + double scal_pixel_height; /* height of one pixel */ +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED + png_charp scal_s_width; /* string containing height */ + png_charp scal_s_height; /* string containing width */ +#endif +#endif + +#if defined(PNG_INFO_IMAGE_SUPPORTED) + /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS) non-zero */ + /* Data valid if (valid & PNG_INFO_IDAT) non-zero */ + png_bytepp row_pointers; /* the image bits */ +#endif + +#if defined(PNG_FIXED_POINT_SUPPORTED) && defined(PNG_gAMA_SUPPORTED) + png_fixed_point int_gamma; /* gamma of image, if (valid & PNG_INFO_gAMA) */ +#endif + +#if defined(PNG_cHRM_SUPPORTED) && defined(PNG_FIXED_POINT_SUPPORTED) + png_fixed_point int_x_white; + png_fixed_point int_y_white; + png_fixed_point int_x_red; + png_fixed_point int_y_red; + png_fixed_point int_x_green; + png_fixed_point int_y_green; + png_fixed_point int_x_blue; + png_fixed_point int_y_blue; +#endif + +} png_info; + +typedef png_info FAR * png_infop; +typedef png_info FAR * FAR * png_infopp; + +/* Maximum positive integer used in PNG is (2^31)-1 */ +#define PNG_MAX_UINT ((png_uint_32)0x7fffffffL) + +/* These describe the color_type field in png_info. */ +/* color type masks */ +#define PNG_COLOR_MASK_PALETTE 1 +#define PNG_COLOR_MASK_COLOR 2 +#define PNG_COLOR_MASK_ALPHA 4 + +/* color types. Note that not all combinations are legal */ +#define PNG_COLOR_TYPE_GRAY 0 +#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE) +#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR) +#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA) +#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA) +/* aliases */ +#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA +#define PNG_COLOR_TYPE_GA PNG_COLOR_TYPE_GRAY_ALPHA + +/* This is for compression type. PNG 1.0-1.2 only define the single type. */ +#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */ +#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE + +/* This is for filter type. PNG 1.0-1.2 only define the single type. */ +#define PNG_FILTER_TYPE_BASE 0 /* Single row per-byte filtering */ +#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */ +#define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE + +/* These are for the interlacing type. These values should NOT be changed. */ +#define PNG_INTERLACE_NONE 0 /* Non-interlaced image */ +#define PNG_INTERLACE_ADAM7 1 /* Adam7 interlacing */ +#define PNG_INTERLACE_LAST 2 /* Not a valid value */ + +/* These are for the oFFs chunk. These values should NOT be changed. */ +#define PNG_OFFSET_PIXEL 0 /* Offset in pixels */ +#define PNG_OFFSET_MICROMETER 1 /* Offset in micrometers (1/10^6 meter) */ +#define PNG_OFFSET_LAST 2 /* Not a valid value */ + +/* These are for the pCAL chunk. These values should NOT be changed. */ +#define PNG_EQUATION_LINEAR 0 /* Linear transformation */ +#define PNG_EQUATION_BASE_E 1 /* Exponential base e transform */ +#define PNG_EQUATION_ARBITRARY 2 /* Arbitrary base exponential transform */ +#define PNG_EQUATION_HYPERBOLIC 3 /* Hyperbolic sine transformation */ +#define PNG_EQUATION_LAST 4 /* Not a valid value */ + +/* These are for the sCAL chunk. These values should NOT be changed. */ +#define PNG_SCALE_UNKNOWN 0 /* unknown unit (image scale) */ +#define PNG_SCALE_METER 1 /* meters per pixel */ +#define PNG_SCALE_RADIAN 2 /* radians per pixel */ +#define PNG_SCALE_LAST 3 /* Not a valid value */ + +/* These are for the pHYs chunk. These values should NOT be changed. */ +#define PNG_RESOLUTION_UNKNOWN 0 /* pixels/unknown unit (aspect ratio) */ +#define PNG_RESOLUTION_METER 1 /* pixels/meter */ +#define PNG_RESOLUTION_LAST 2 /* Not a valid value */ + +/* These are for the sRGB chunk. These values should NOT be changed. */ +#define PNG_sRGB_INTENT_PERCEPTUAL 0 +#define PNG_sRGB_INTENT_RELATIVE 1 +#define PNG_sRGB_INTENT_SATURATION 2 +#define PNG_sRGB_INTENT_ABSOLUTE 3 +#define PNG_sRGB_INTENT_LAST 4 /* Not a valid value */ + +/* This is for text chunks */ +#define PNG_KEYWORD_MAX_LENGTH 79 + +/* Maximum number of entries in PLTE/sPLT/tRNS arrays */ +#define PNG_MAX_PALETTE_LENGTH 256 + +/* These determine if an ancillary chunk's data has been successfully read + * from the PNG header, or if the application has filled in the corresponding + * data in the info_struct to be written into the output file. The values + * of the PNG_INFO_ defines should NOT be changed. + */ +#define PNG_INFO_gAMA 0x0001 +#define PNG_INFO_sBIT 0x0002 +#define PNG_INFO_cHRM 0x0004 +#define PNG_INFO_PLTE 0x0008 +#define PNG_INFO_tRNS 0x0010 +#define PNG_INFO_bKGD 0x0020 +#define PNG_INFO_hIST 0x0040 +#define PNG_INFO_pHYs 0x0080 +#define PNG_INFO_oFFs 0x0100 +#define PNG_INFO_tIME 0x0200 +#define PNG_INFO_pCAL 0x0400 +#define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */ +#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */ +#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */ +#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */ +#define PNG_INFO_IDAT 0x8000L /* ESR, 1.0.6 */ + +/* This is used for the transformation routines, as some of them + * change these values for the row. It also should enable using + * the routines for other purposes. + */ +typedef struct png_row_info_struct +{ + png_uint_32 width; /* width of row */ + png_uint_32 rowbytes; /* number of bytes in row */ + png_byte color_type; /* color type of row */ + png_byte bit_depth; /* bit depth of row */ + png_byte channels; /* number of channels (1, 2, 3, or 4) */ + png_byte pixel_depth; /* bits per pixel (depth * channels) */ +} png_row_info; + +typedef png_row_info FAR * png_row_infop; +typedef png_row_info FAR * FAR * png_row_infopp; + +/* These are the function types for the I/O functions and for the functions + * that allow the user to override the default I/O functions with his or her + * own. The png_error_ptr type should match that of user-supplied warning + * and error functions, while the png_rw_ptr type should match that of the + * user read/write data functions. + */ +typedef struct png_struct_def png_struct; +typedef png_struct FAR * png_structp; + +typedef void (PNGAPI *png_error_ptr) PNGARG((png_structp, png_const_charp)); +typedef void (PNGAPI *png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t)); +typedef void (PNGAPI *png_flush_ptr) PNGARG((png_structp)); +typedef void (PNGAPI *png_read_status_ptr) PNGARG((png_structp, png_uint_32, + int)); +typedef void (PNGAPI *png_write_status_ptr) PNGARG((png_structp, png_uint_32, + int)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +typedef void (PNGAPI *png_progressive_info_ptr) PNGARG((png_structp, png_infop)); +typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop)); +typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep, + png_uint_32, int)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +typedef void (PNGAPI *png_user_transform_ptr) PNGARG((png_structp, + png_row_infop, png_bytep)); +#endif + +#if defined(PNG_USER_CHUNKS_SUPPORTED) +typedef int (PNGAPI *png_user_chunk_ptr) PNGARG((png_structp, png_unknown_chunkp)); +#endif +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +typedef void (PNGAPI *png_unknown_chunk_ptr) PNGARG((png_structp)); +#endif + +/* Transform masks for the high-level interface */ +#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */ +#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */ +#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */ +#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */ +#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */ +#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */ +#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */ +#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */ +#define PNG_TRANSFORM_BGR 0x0080 /* read and write */ +#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */ +#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */ +#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */ +#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* WRITE only */ + +/* Flags for MNG supported features */ +#define PNG_FLAG_MNG_EMPTY_PLTE 0x01 +#define PNG_FLAG_MNG_FILTER_64 0x04 +#define PNG_ALL_MNG_FEATURES 0x05 + +typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_size_t)); +typedef void (*png_free_ptr) PNGARG((png_structp, png_voidp)); + +/* The structure that holds the information to read and write PNG files. + * The only people who need to care about what is inside of this are the + * people who will be modifying the library for their own special needs. + * It should NOT be accessed directly by an application, except to store + * the jmp_buf. + */ + +struct png_struct_def +{ +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf jmpbuf; /* used in png_error */ +#endif + png_error_ptr error_fn; /* function for printing errors and aborting */ + png_error_ptr warning_fn; /* function for printing warnings */ + png_voidp error_ptr; /* user supplied struct for error functions */ + png_rw_ptr write_data_fn; /* function for writing output data */ + png_rw_ptr read_data_fn; /* function for reading input data */ + png_voidp io_ptr; /* ptr to application struct for I/O functions */ + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + png_user_transform_ptr read_user_transform_fn; /* user read transform */ +#endif + +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + png_user_transform_ptr write_user_transform_fn; /* user write transform */ +#endif + +/* These were added in libpng-1.0.2 */ +#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + png_voidp user_transform_ptr; /* user supplied struct for user transform */ + png_byte user_transform_depth; /* bit depth of user transformed pixels */ + png_byte user_transform_channels; /* channels in user transformed pixels */ +#endif +#endif + + png_uint_32 mode; /* tells us where we are in the PNG file */ + png_uint_32 flags; /* flags indicating various things to libpng */ + png_uint_32 transformations; /* which transformations to perform */ + + z_stream zstream; /* pointer to decompression structure (below) */ + png_bytep zbuf; /* buffer for zlib */ + png_size_t zbuf_size; /* size of zbuf */ + int zlib_level; /* holds zlib compression level */ + int zlib_method; /* holds zlib compression method */ + int zlib_window_bits; /* holds zlib compression window bits */ + int zlib_mem_level; /* holds zlib compression memory level */ + int zlib_strategy; /* holds zlib compression strategy */ + + png_uint_32 width; /* width of image in pixels */ + png_uint_32 height; /* height of image in pixels */ + png_uint_32 num_rows; /* number of rows in current pass */ + png_uint_32 usr_width; /* width of row at start of write */ + png_uint_32 rowbytes; /* size of row in bytes */ + png_uint_32 irowbytes; /* size of current interlaced row in bytes */ + png_uint_32 iwidth; /* width of current interlaced row in pixels */ + png_uint_32 row_number; /* current row in interlace pass */ + png_bytep prev_row; /* buffer to save previous (unfiltered) row */ + png_bytep row_buf; /* buffer to save current (unfiltered) row */ + png_bytep sub_row; /* buffer to save "sub" row when filtering */ + png_bytep up_row; /* buffer to save "up" row when filtering */ + png_bytep avg_row; /* buffer to save "avg" row when filtering */ + png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */ + png_row_info row_info; /* used for transformation routines */ + + png_uint_32 idat_size; /* current IDAT size for read */ + png_uint_32 crc; /* current chunk CRC value */ + png_colorp palette; /* palette from the input file */ + png_uint_16 num_palette; /* number of color entries in palette */ + png_uint_16 num_trans; /* number of transparency values */ + png_byte chunk_name[5]; /* null-terminated name of current chunk */ + png_byte compression; /* file compression type (always 0) */ + png_byte filter; /* file filter type (always 0) */ + png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ + png_byte pass; /* current interlace pass (0 - 6) */ + png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */ + png_byte color_type; /* color type of file */ + png_byte bit_depth; /* bit depth of file */ + png_byte usr_bit_depth; /* bit depth of users row */ + png_byte pixel_depth; /* number of bits per pixel */ + png_byte channels; /* number of channels in file */ + png_byte usr_channels; /* channels at start of write */ + png_byte sig_bytes; /* magic bytes read/written from start of file */ + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +#ifdef PNG_LEGACY_SUPPORTED + png_byte filler; /* filler byte for pixel expansion */ +#else + png_uint_16 filler; /* filler bytes for pixel expansion */ +#endif +#endif + +#if defined(PNG_bKGD_SUPPORTED) + png_byte background_gamma_type; +# ifdef PNG_FLOATING_POINT_SUPPORTED + float background_gamma; +# endif + png_color_16 background; /* background color in screen gamma space */ +#if defined(PNG_READ_GAMMA_SUPPORTED) + png_color_16 background_1; /* background normalized to gamma 1.0 */ +#endif +#endif /* PNG_bKGD_SUPPORTED */ + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) + png_flush_ptr output_flush_fn;/* Function for flushing output */ + png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */ + png_uint_32 flush_rows; /* number of rows written since last flush */ +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + int gamma_shift; /* number of "insignificant" bits 16-bit gamma */ +#ifdef PNG_FLOATING_POINT_SUPPORTED + float gamma; /* file gamma value */ + float screen_gamma; /* screen gamma value (display_exponent) */ +#endif +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_bytep gamma_table; /* gamma table for 8-bit depth files */ + png_bytep gamma_from_1; /* converts from 1.0 to screen */ + png_bytep gamma_to_1; /* converts from file to 1.0 */ + png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ + png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */ + png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */ +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED) + png_color_8 sig_bit; /* significant bits in each available channel */ +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) + png_color_8 shift; /* shift for significant bit tranformation */ +#endif + +#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \ + || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_bytep trans; /* transparency values for paletted files */ + png_color_16 trans_values; /* transparency values for non-paletted files */ +#endif + + png_read_status_ptr read_row_fn; /* called after each row is decoded */ + png_write_status_ptr write_row_fn; /* called after each row is encoded */ +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + png_progressive_info_ptr info_fn; /* called after header data fully read */ + png_progressive_row_ptr row_fn; /* called after each prog. row is decoded */ + png_progressive_end_ptr end_fn; /* called after image is complete */ + png_bytep save_buffer_ptr; /* current location in save_buffer */ + png_bytep save_buffer; /* buffer for previously read data */ + png_bytep current_buffer_ptr; /* current location in current_buffer */ + png_bytep current_buffer; /* buffer for recently used data */ + png_uint_32 push_length; /* size of current input chunk */ + png_uint_32 skip_length; /* bytes to skip in input data */ + png_size_t save_buffer_size; /* amount of data now in save_buffer */ + png_size_t save_buffer_max; /* total size of save_buffer */ + png_size_t buffer_size; /* total amount of available input data */ + png_size_t current_buffer_size; /* amount of data now in current_buffer */ + int process_mode; /* what push library is currently doing */ + int cur_palette; /* current push library palette index */ + +# if defined(PNG_TEXT_SUPPORTED) + png_size_t current_text_size; /* current size of text input data */ + png_size_t current_text_left; /* how much text left to read in input */ + png_charp current_text; /* current text chunk buffer */ + png_charp current_text_ptr; /* current location in current_text */ +# endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_TEXT_SUPPORTED */ + +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) +/* for the Borland special 64K segment handler */ + png_bytepp offset_table_ptr; + png_bytep offset_table; + png_uint_16 offset_table_number; + png_uint_16 offset_table_count; + png_uint_16 offset_table_count_free; +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) + png_bytep palette_lookup; /* lookup table for dithering */ + png_bytep dither_index; /* index translation for palette files */ +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_hIST_SUPPORTED) + png_uint_16p hist; /* histogram */ +#endif + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + png_byte heuristic_method; /* heuristic for row filter selection */ + png_byte num_prev_filters; /* number of weights for previous rows */ + png_bytep prev_filters; /* filter type(s) of previous row(s) */ + png_uint_16p filter_weights; /* weight(s) for previous line(s) */ + png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */ + png_uint_16p filter_costs; /* relative filter calculation cost */ + png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */ +#endif + +#if defined(PNG_TIME_RFC1123_SUPPORTED) + png_charp time_buffer; /* String to hold RFC 1123 time text */ +#endif + +/* New members added in libpng-1.0.6 */ + +#ifdef PNG_FREE_ME_SUPPORTED + png_uint_32 free_me; /* flags items libpng is responsible for freeing */ +#endif + +#if defined(PNG_USER_CHUNKS_SUPPORTED) + png_voidp user_chunk_ptr; + png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */ +#endif + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + int num_chunk_list; + png_bytep chunk_list; +#endif + +/* New members added in libpng-1.0.3 */ +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + png_byte rgb_to_gray_status; + /* These were changed from png_byte in libpng-1.0.6 */ + png_uint_16 rgb_to_gray_red_coeff; + png_uint_16 rgb_to_gray_green_coeff; + png_uint_16 rgb_to_gray_blue_coeff; +#endif + +/* New member added in libpng-1.0.4 (renamed in 1.0.9) */ +#if defined(PNG_MNG_FEATURES_SUPPORTED) || \ + defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ + defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) +/* changed from png_byte to png_uint_32 at version 1.2.0 */ +#ifdef PNG_1_0_X + png_byte mng_features_permitted; +#else + png_uint_32 mng_features_permitted; +#endif /* PNG_1_0_X */ +#endif + +/* New member added in libpng-1.0.7 */ +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_fixed_point int_gamma; +#endif + +/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */ +#if defined(PNG_MNG_FEATURES_SUPPORTED) + png_byte filter_type; +#endif + +#if defined(PNG_1_0_X) || (defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD)) +/* New member added in libpng-1.0.10, ifdef'ed out in 1.2.0 */ + png_uint_32 row_buf_size; +#endif + +/* New members added in libpng-1.2.0 */ +#if !defined(PNG_1_0_X) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) + png_byte mmx_bitdepth_threshold; + png_uint_32 mmx_rowbytes_threshold; + png_uint_32 asm_flags; +#endif + +/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */ +#ifdef PNG_USER_MEM_SUPPORTED + png_voidp mem_ptr; /* user supplied struct for mem functions */ + png_malloc_ptr malloc_fn; /* function for allocating memory */ + png_free_ptr free_fn; /* function for freeing memory */ +#endif + +/* New member added in libpng-1.0.13 and 1.2.0 */ + png_bytep big_row_buf; /* buffer to save current (unfiltered) row */ + +#if defined(PNG_READ_DITHER_SUPPORTED) +/* The following three members were added at version 1.0.14 and 1.2.4 */ + png_bytep dither_sort; /* working sort array */ + png_bytep index_to_palette; /* where the original index currently is */ + /* in the palette */ + png_bytep palette_to_index; /* which original index points to this */ + /* palette color */ +#endif + +}; + + +/* This prevents a compiler error in png.c if png.c and png.h are both at + version 1.2.5 + */ +typedef png_structp version_1_2_5; + +typedef png_struct FAR * FAR * png_structpp; + +/* Here are the function definitions most commonly used. This is not + * the place to find out how to use libpng. See libpng.txt for the + * full explanation, see example.c for the summary. This just provides + * a simple one line description of the use of each function. + */ + +/* Returns the version number of the library */ +extern PNG_EXPORT(png_uint_32,png_access_version_number) PNGARG((void)); + +/* Tell lib we have already handled the first magic bytes. + * Handling more than 8 bytes from the beginning of the file is an error. + */ +extern PNG_EXPORT(void,png_set_sig_bytes) PNGARG((png_structp png_ptr, + int num_bytes)); + +/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a + * PNG file. Returns zero if the supplied bytes match the 8-byte PNG + * signature, and non-zero otherwise. Having num_to_check == 0 or + * start > 7 will always fail (ie return non-zero). + */ +extern PNG_EXPORT(int,png_sig_cmp) PNGARG((png_bytep sig, png_size_t start, + png_size_t num_to_check)); + +/* Simple signature checking function. This is the same as calling + * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n). + */ +extern PNG_EXPORT(int,png_check_sig) PNGARG((png_bytep sig, int num)); + +/* Allocate and initialize png_ptr struct for reading, and any other memory. */ +extern PNG_EXPORT(png_structp,png_create_read_struct) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn)); + +/* Allocate and initialize png_ptr struct for writing, and any other memory */ +extern PNG_EXPORT(png_structp,png_create_write_struct) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn)); + +extern PNG_EXPORT(png_uint_32,png_get_compression_buffer_size) + PNGARG((png_structp png_ptr)); + +extern PNG_EXPORT(void,png_set_compression_buffer_size) + PNGARG((png_structp png_ptr, png_uint_32 size)); + +/* Reset the compression stream */ +extern PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr)); + +/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ +#ifdef PNG_USER_MEM_SUPPORTED +extern PNG_EXPORT(png_structp,png_create_read_struct_2) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +extern PNG_EXPORT(png_structp,png_create_write_struct_2) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +#endif + +/* Write a PNG chunk - size, type, (optional) data, CRC. */ +extern PNG_EXPORT(void,png_write_chunk) PNGARG((png_structp png_ptr, + png_bytep chunk_name, png_bytep data, png_size_t length)); + +/* Write the start of a PNG chunk - length and chunk name. */ +extern PNG_EXPORT(void,png_write_chunk_start) PNGARG((png_structp png_ptr, + png_bytep chunk_name, png_uint_32 length)); + +/* Write the data of a PNG chunk started with png_write_chunk_start(). */ +extern PNG_EXPORT(void,png_write_chunk_data) PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +/* Finish a chunk started with png_write_chunk_start() (includes CRC). */ +extern PNG_EXPORT(void,png_write_chunk_end) PNGARG((png_structp png_ptr)); + +/* Allocate and initialize the info structure */ +extern PNG_EXPORT(png_infop,png_create_info_struct) + PNGARG((png_structp png_ptr)); + +/* Initialize the info structure (old interface - DEPRECATED) */ +extern PNG_EXPORT(void,png_info_init) PNGARG((png_infop info_ptr)); +#undef png_info_init +#define png_info_init(info_ptr) png_info_init_3(&info_ptr, sizeof(png_info)); +extern PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr, + png_size_t png_info_struct_size)); + +/* Writes all the PNG information before the image. */ +extern PNG_EXPORT(void,png_write_info_before_PLTE) PNGARG((png_structp png_ptr, + png_infop info_ptr)); +extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +/* read the information before the actual image data. */ +extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#if defined(PNG_TIME_RFC1123_SUPPORTED) +extern PNG_EXPORT(png_charp,png_convert_to_rfc1123) + PNGARG((png_structp png_ptr, png_timep ptime)); +#endif + +#if !defined(_WIN32_WCE) +/* "time.h" functions are not supported on WindowsCE */ +#if defined(PNG_WRITE_tIME_SUPPORTED) +/* convert from a struct tm to png_time */ +extern PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime, + struct tm FAR * ttime)); + +/* convert from time_t to png_time. Uses gmtime() */ +extern PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime, + time_t ttime)); +#endif /* PNG_WRITE_tIME_SUPPORTED */ +#endif /* _WIN32_WCE */ + +#if defined(PNG_READ_EXPAND_SUPPORTED) +/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ +extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(void,png_set_gray_1_2_4_to_8) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(void,png_set_tRNS_to_alpha) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +/* Use blue, green, red order for pixels. */ +extern PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) +/* Expand the grayscale to 24-bit RGB if necessary. */ +extern PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +/* Reduce RGB to grayscale. */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr, + int error_action, double red, double green )); +#endif +extern PNG_EXPORT(void,png_set_rgb_to_gray_fixed) PNGARG((png_structp png_ptr, + int error_action, png_fixed_point red, png_fixed_point green )); +extern PNG_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_structp + png_ptr)); +#endif + +extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth, + png_colorp palette)); + +#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +extern PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +/* Add a filler byte to 24-bit RGB images. */ +extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr, + png_uint_32 filler, int flags)); +/* The values of the PNG_FILLER_ defines should NOT be changed */ +#define PNG_FILLER_BEFORE 0 +#define PNG_FILLER_AFTER 1 +#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */ + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +/* Swap bytes in 16-bit depth files. */ +extern PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) +/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */ +extern PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED) +/* Swap packing order of pixels in bytes. */ +extern PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) +/* Converts files to legal bit depths. */ +extern PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr, + png_color_8p true_bits)); +#endif + +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ + defined(PNG_WRITE_INTERLACING_SUPPORTED) +/* Have the code handle the interlacing. Returns the number of passes. */ +extern PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +/* Invert monochrome files */ +extern PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) +/* Handle alpha and tRNS by replacing with a background color. */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr, + png_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma)); +#endif +#define PNG_BACKGROUND_GAMMA_UNKNOWN 0 +#define PNG_BACKGROUND_GAMMA_SCREEN 1 +#define PNG_BACKGROUND_GAMMA_FILE 2 +#define PNG_BACKGROUND_GAMMA_UNIQUE 3 +#endif + +#if defined(PNG_READ_16_TO_8_SUPPORTED) +/* strip the second byte of information from a 16-bit depth file. */ +extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) +/* Turn on dithering, and reduce the palette to the number of colors available. */ +extern PNG_EXPORT(void,png_set_dither) PNGARG((png_structp png_ptr, + png_colorp palette, int num_palette, int maximum_colors, + png_uint_16p histogram, int full_dither)); +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) +/* Handle gamma correction. Screen_gamma=(display_exponent) */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr, + double screen_gamma, double default_file_gamma)); +#endif +#endif + +#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ + defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) +/* Permit or disallow empty PLTE (0: not permitted, 1: permitted) */ +/* Deprecated and will be removed. Use png_permit_mng_features() instead. */ +extern PNG_EXPORT(void,png_permit_empty_plte) PNGARG((png_structp png_ptr, + int empty_plte_permitted)); +#endif + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +/* Set how many lines between output flushes - 0 for no flushing */ +extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows)); +/* Flush the current PNG output buffer */ +extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr)); +#endif + +/* optional update palette with requested transformations */ +extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr)); + +/* optional call to update the users info structure */ +extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +/* read one or more rows of image data. */ +extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr, + png_bytepp row, png_bytepp display_row, png_uint_32 num_rows)); + +/* read a row of data. */ +extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr, + png_bytep row, + png_bytep display_row)); + +/* read the whole image into memory at once. */ +extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr, + png_bytepp image)); + +/* write a row of image data */ +extern PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr, + png_bytep row)); + +/* write a few rows of image data */ +extern PNG_EXPORT(void,png_write_rows) PNGARG((png_structp png_ptr, + png_bytepp row, png_uint_32 num_rows)); + +/* write the image data */ +extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr, + png_bytepp image)); + +/* writes the end of the PNG file. */ +extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +/* read the end of the PNG file. */ +extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +/* free any memory associated with the png_info_struct */ +extern PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr, + png_infopp info_ptr_ptr)); + +/* free any memory associated with the png_struct and the png_info_structs */ +extern PNG_EXPORT(void,png_destroy_read_struct) PNGARG((png_structpp + png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)); + +/* free all memory used by the read (old method - NOT DLL EXPORTED) */ +extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr, + png_infop end_info_ptr)); + +/* free any memory associated with the png_struct and the png_info_structs */ +extern PNG_EXPORT(void,png_destroy_write_struct) + PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)); + +/* free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */ +extern void png_write_destroy PNGARG((png_structp png_ptr)); + +/* set the libpng method of handling chunk CRC errors */ +extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr, + int crit_action, int ancil_action)); + +/* Values for png_set_crc_action() to say how to handle CRC errors in + * ancillary and critical chunks, and whether to use the data contained + * therein. Note that it is impossible to "discard" data in a critical + * chunk. For versions prior to 0.90, the action was always error/quit, + * whereas in version 0.90 and later, the action for CRC errors in ancillary + * chunks is warn/discard. These values should NOT be changed. + * + * value action:critical action:ancillary + */ +#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */ +#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */ +#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */ +#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */ +#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */ +#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */ + +/* These functions give the user control over the scan-line filtering in + * libpng and the compression methods used by zlib. These functions are + * mainly useful for testing, as the defaults should work with most users. + * Those users who are tight on memory or want faster performance at the + * expense of compression can modify them. See the compression library + * header file (zlib.h) for an explination of the compression functions. + */ + +/* set the filtering method(s) used by libpng. Currently, the only valid + * value for "method" is 0. + */ +extern PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int method, + int filters)); + +/* Flags for png_set_filter() to say which filters to use. The flags + * are chosen so that they don't conflict with real filter types + * below, in case they are supplied instead of the #defined constants. + * These values should NOT be changed. + */ +#define PNG_NO_FILTERS 0x00 +#define PNG_FILTER_NONE 0x08 +#define PNG_FILTER_SUB 0x10 +#define PNG_FILTER_UP 0x20 +#define PNG_FILTER_AVG 0x40 +#define PNG_FILTER_PAETH 0x80 +#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \ + PNG_FILTER_AVG | PNG_FILTER_PAETH) + +/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now. + * These defines should NOT be changed. + */ +#define PNG_FILTER_VALUE_NONE 0 +#define PNG_FILTER_VALUE_SUB 1 +#define PNG_FILTER_VALUE_UP 2 +#define PNG_FILTER_VALUE_AVG 3 +#define PNG_FILTER_VALUE_PAETH 4 +#define PNG_FILTER_VALUE_LAST 5 + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* EXPERIMENTAL */ +/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_ + * defines, either the default (minimum-sum-of-absolute-differences), or + * the experimental method (weighted-minimum-sum-of-absolute-differences). + * + * Weights are factors >= 1.0, indicating how important it is to keep the + * filter type consistent between rows. Larger numbers mean the current + * filter is that many times as likely to be the same as the "num_weights" + * previous filters. This is cumulative for each previous row with a weight. + * There needs to be "num_weights" values in "filter_weights", or it can be + * NULL if the weights aren't being specified. Weights have no influence on + * the selection of the first row filter. Well chosen weights can (in theory) + * improve the compression for a given image. + * + * Costs are factors >= 1.0 indicating the relative decoding costs of a + * filter type. Higher costs indicate more decoding expense, and are + * therefore less likely to be selected over a filter with lower computational + * costs. There needs to be a value in "filter_costs" for each valid filter + * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't + * setting the costs. Costs try to improve the speed of decompression without + * unduly increasing the compressed image size. + * + * A negative weight or cost indicates the default value is to be used, and + * values in the range [0.0, 1.0) indicate the value is to remain unchanged. + * The default values for both weights and costs are currently 1.0, but may + * change if good general weighting/cost heuristics can be found. If both + * the weights and costs are set to 1.0, this degenerates the WEIGHTED method + * to the UNWEIGHTED method, but with added encoding time/computation. + */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr, + int heuristic_method, int num_weights, png_doublep filter_weights, + png_doublep filter_costs)); +#endif +#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ + +/* Heuristic used for row filter selection. These defines should NOT be + * changed. + */ +#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */ +#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */ +#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */ +#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */ + +/* Set the library compression level. Currently, valid values range from + * 0 - 9, corresponding directly to the zlib compression levels 0 - 9 + * (0 - no compression, 9 - "maximal" compression). Note that tests have + * shown that zlib compression levels 3-6 usually perform as well as level 9 + * for PNG images, and do considerably fewer caclulations. In the future, + * these values may not correspond directly to the zlib compression levels. + */ +extern PNG_EXPORT(void,png_set_compression_level) PNGARG((png_structp png_ptr, + int level)); + +extern PNG_EXPORT(void,png_set_compression_mem_level) + PNGARG((png_structp png_ptr, int mem_level)); + +extern PNG_EXPORT(void,png_set_compression_strategy) + PNGARG((png_structp png_ptr, int strategy)); + +extern PNG_EXPORT(void,png_set_compression_window_bits) + PNGARG((png_structp png_ptr, int window_bits)); + +extern PNG_EXPORT(void,png_set_compression_method) PNGARG((png_structp png_ptr, + int method)); + +/* These next functions are called for input/output, memory, and error + * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, + * and call standard C I/O routines such as fread(), fwrite(), and + * fprintf(). These functions can be made to use other I/O routines + * at run time for those applications that need to handle I/O in a + * different manner by calling png_set_???_fn(). See libpng.txt for + * more information. + */ + +#if !defined(PNG_NO_STDIO) +/* Initialize the input/output for the PNG file to the default functions. */ +extern PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, png_FILE_p fp)); +#endif + +/* Replace the (error and abort), and warning functions with user + * supplied functions. If no messages are to be printed you must still + * write and use replacement functions. The replacement error_fn should + * still do a longjmp to the last setjmp location if you are using this + * method of error handling. If error_fn or warning_fn is NULL, the + * default function will be used. + */ + +extern PNG_EXPORT(void,png_set_error_fn) PNGARG((png_structp png_ptr, + png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn)); + +/* Return the user pointer associated with the error functions */ +extern PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr)); + +/* Replace the default data output functions with a user supplied one(s). + * If buffered output is not used, then output_flush_fn can be set to NULL. + * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time + * output_flush_fn will be ignored (and thus can be NULL). + */ +extern PNG_EXPORT(void,png_set_write_fn) PNGARG((png_structp png_ptr, + png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); + +/* Replace the default data input function with a user supplied one. */ +extern PNG_EXPORT(void,png_set_read_fn) PNGARG((png_structp png_ptr, + png_voidp io_ptr, png_rw_ptr read_data_fn)); + +/* Return the user pointer associated with the I/O functions */ +extern PNG_EXPORT(png_voidp,png_get_io_ptr) PNGARG((png_structp png_ptr)); + +extern PNG_EXPORT(void,png_set_read_status_fn) PNGARG((png_structp png_ptr, + png_read_status_ptr read_row_fn)); + +extern PNG_EXPORT(void,png_set_write_status_fn) PNGARG((png_structp png_ptr, + png_write_status_ptr write_row_fn)); + +#ifdef PNG_USER_MEM_SUPPORTED +/* Replace the default memory allocation functions with user supplied one(s). */ +extern PNG_EXPORT(void,png_set_mem_fn) PNGARG((png_structp png_ptr, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +/* Return the user pointer associated with the memory functions */ +extern PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp + png_ptr, png_user_transform_ptr read_user_transform_fn)); +#endif + +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +extern PNG_EXPORT(void,png_set_write_user_transform_fn) PNGARG((png_structp + png_ptr, png_user_transform_ptr write_user_transform_fn)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +extern PNG_EXPORT(void,png_set_user_transform_info) PNGARG((png_structp + png_ptr, png_voidp user_transform_ptr, int user_transform_depth, + int user_transform_channels)); +/* Return the user pointer associated with the user transform functions */ +extern PNG_EXPORT(png_voidp,png_get_user_transform_ptr) + PNGARG((png_structp png_ptr)); +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +extern PNG_EXPORT(void,png_set_read_user_chunk_fn) PNGARG((png_structp png_ptr, + png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); +extern PNG_EXPORT(png_voidp,png_get_user_chunk_ptr) PNGARG((png_structp + png_ptr)); +#endif + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +/* Sets the function callbacks for the push reader, and a pointer to a + * user-defined structure available to the callback functions. + */ +extern PNG_EXPORT(void,png_set_progressive_read_fn) PNGARG((png_structp png_ptr, + png_voidp progressive_ptr, + png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, + png_progressive_end_ptr end_fn)); + +/* returns the user pointer associated with the push read functions */ +extern PNG_EXPORT(png_voidp,png_get_progressive_ptr) + PNGARG((png_structp png_ptr)); + +/* function to be called when data becomes available */ +extern PNG_EXPORT(void,png_process_data) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytep buffer, png_size_t buffer_size)); + +/* function that combines rows. Not very much different than the + * png_combine_row() call. Is this even used????? + */ +extern PNG_EXPORT(void,png_progressive_combine_row) PNGARG((png_structp png_ptr, + png_bytep old_row, png_bytep new_row)); +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +extern PNG_EXPORT(png_voidp,png_malloc) PNGARG((png_structp png_ptr, + png_uint_32 size)); + +#if defined(PNG_1_0_X) +# define png_malloc_warn png_malloc +#else +/* Added at libpng version 1.2.4 */ +extern PNG_EXPORT(png_voidp,png_malloc_warn) PNGARG((png_structp png_ptr, + png_uint_32 size)); +#endif + +/* frees a pointer allocated by png_malloc() */ +extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr)); + +#if defined(PNG_1_0_X) +/* Function to allocate memory for zlib. */ +extern PNG_EXPORT(voidpf,png_zalloc) PNGARG((voidpf png_ptr, uInt items, + uInt size)); + +/* Function to free memory for zlib */ +extern PNG_EXPORT(void,png_zfree) PNGARG((voidpf png_ptr, voidpf ptr)); +#endif + +/* Free data that was allocated internally */ +extern PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 free_me, int num)); +#ifdef PNG_FREE_ME_SUPPORTED +/* Reassign responsibility for freeing existing data, whether allocated + * by libpng or by the application */ +extern PNG_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr, + png_infop info_ptr, int freer, png_uint_32 mask)); +#endif +/* assignments for png_data_freer */ +#define PNG_DESTROY_WILL_FREE_DATA 1 +#define PNG_SET_WILL_FREE_DATA 1 +#define PNG_USER_WILL_FREE_DATA 2 +/* Flags for png_ptr->free_me and info_ptr->free_me */ +#define PNG_FREE_HIST 0x0008 +#define PNG_FREE_ICCP 0x0010 +#define PNG_FREE_SPLT 0x0020 +#define PNG_FREE_ROWS 0x0040 +#define PNG_FREE_PCAL 0x0080 +#define PNG_FREE_SCAL 0x0100 +#define PNG_FREE_UNKN 0x0200 +#define PNG_FREE_LIST 0x0400 +#define PNG_FREE_PLTE 0x1000 +#define PNG_FREE_TRNS 0x2000 +#define PNG_FREE_TEXT 0x4000 +#define PNG_FREE_ALL 0x7fff +#define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ + +#ifdef PNG_USER_MEM_SUPPORTED +extern PNG_EXPORT(png_voidp,png_malloc_default) PNGARG((png_structp png_ptr, + png_uint_32 size)); +extern PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr, + png_voidp ptr)); +#endif + +extern PNG_EXPORT(png_voidp,png_memcpy_check) PNGARG((png_structp png_ptr, + png_voidp s1, png_voidp s2, png_uint_32 size)); + +extern PNG_EXPORT(png_voidp,png_memset_check) PNGARG((png_structp png_ptr, + png_voidp s1, int value, png_uint_32 size)); + +#if defined(USE_FAR_KEYWORD) /* memory model conversion function */ +extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr, + int check)); +#endif /* USE_FAR_KEYWORD */ + +/* Fatal error in PNG image of libpng - can't continue */ +extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr, + png_const_charp error_message)); + +/* The same, but the chunk name is prepended to the error string. */ +extern PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr, + png_const_charp error_message)); + +/* Non-fatal error in libpng. Can continue, but may have a problem. */ +extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr, + png_const_charp warning_message)); + +/* Non-fatal error in libpng, chunk name is prepended to message. */ +extern PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr, + png_const_charp warning_message)); + +/* The png_set_ functions are for storing values in the png_info_struct. + * Similarly, the png_get_ calls are used to read values from the + * png_info_struct, either storing the parameters in the passed variables, or + * setting pointers into the png_info_struct where the data is stored. The + * png_get_ functions return a non-zero value if the data was available + * in info_ptr, or return zero and do not change any of the parameters if the + * data was not available. + * + * These functions should be used instead of directly accessing png_info + * to avoid problems with future changes in the size and internal layout of + * png_info_struct. + */ +/* Returns "flag" if chunk data is valid in info_ptr. */ +extern PNG_EXPORT(png_uint_32,png_get_valid) PNGARG((png_structp png_ptr, +png_infop info_ptr, png_uint_32 flag)); + +/* Returns number of bytes needed to hold a transformed row. */ +extern PNG_EXPORT(png_uint_32,png_get_rowbytes) PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#if defined(PNG_INFO_IMAGE_SUPPORTED) +/* Returns row_pointers, which is an array of pointers to scanlines that was +returned from png_read_png(). */ +extern PNG_EXPORT(png_bytepp,png_get_rows) PNGARG((png_structp png_ptr, +png_infop info_ptr)); +/* Set row_pointers, which is an array of pointers to scanlines for use +by png_write_png(). */ +extern PNG_EXPORT(void,png_set_rows) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytepp row_pointers)); +#endif + +/* Returns number of color channels in image. */ +extern PNG_EXPORT(png_byte,png_get_channels) PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#ifdef PNG_EASY_ACCESS_SUPPORTED +/* Returns image width in pixels. */ +extern PNG_EXPORT(png_uint_32, png_get_image_width) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image height in pixels. */ +extern PNG_EXPORT(png_uint_32, png_get_image_height) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image bit_depth. */ +extern PNG_EXPORT(png_byte, png_get_bit_depth) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image color_type. */ +extern PNG_EXPORT(png_byte, png_get_color_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image filter_type. */ +extern PNG_EXPORT(png_byte, png_get_filter_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image interlace_type. */ +extern PNG_EXPORT(png_byte, png_get_interlace_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image compression_type. */ +extern PNG_EXPORT(png_byte, png_get_compression_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image resolution in pixels per meter, from pHYs chunk data. */ +extern PNG_EXPORT(png_uint_32, png_get_pixels_per_meter) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns pixel aspect ratio, computed from pHYs chunk data. */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(float, png_get_pixel_aspect_ratio) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +#endif + +/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ +extern PNG_EXPORT(png_int_32, png_get_x_offset_pixels) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_int_32, png_get_y_offset_pixels) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_int_32, png_get_x_offset_microns) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_int_32, png_get_y_offset_microns) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +#endif /* PNG_EASY_ACCESS_SUPPORTED */ + +/* Returns pointer to signature string read from PNG header */ +extern PNG_EXPORT(png_bytep,png_get_signature) PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#if defined(PNG_bKGD_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_16p *background)); +#endif + +#if defined(PNG_bKGD_SUPPORTED) +extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_16p background)); +#endif + +#if defined(PNG_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((png_structp png_ptr, + png_infop info_ptr, double *white_x, double *white_y, double *red_x, + double *red_y, double *green_x, double *green_y, double *blue_x, + double *blue_y)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_cHRM_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point *int_white_x, png_fixed_point + *int_white_y, png_fixed_point *int_red_x, png_fixed_point *int_red_y, + png_fixed_point *int_green_x, png_fixed_point *int_green_y, png_fixed_point + *int_blue_x, png_fixed_point *int_blue_y)); +#endif +#endif + +#if defined(PNG_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_cHRM) PNGARG((png_structp png_ptr, + png_infop info_ptr, double white_x, double white_y, double red_x, + double red_y, double green_x, double green_y, double blue_x, double blue_y)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_cHRM_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point int_white_x, png_fixed_point int_white_y, + png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point + int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)); +#endif +#endif + +#if defined(PNG_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr, + png_infop info_ptr, double *file_gamma)); +#endif +extern PNG_EXPORT(png_uint_32,png_get_gAMA_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point *int_file_gamma)); +#endif + +#if defined(PNG_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr, + png_infop info_ptr, double file_gamma)); +#endif +extern PNG_EXPORT(void,png_set_gAMA_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point int_file_gamma)); +#endif + +#if defined(PNG_hIST_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_16p *hist)); +#endif + +#if defined(PNG_hIST_SUPPORTED) +extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_16p hist)); +#endif + +extern PNG_EXPORT(png_uint_32,png_get_IHDR) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 *width, png_uint_32 *height, + int *bit_depth, int *color_type, int *interlace_method, + int *compression_method, int *filter_method)); + +extern PNG_EXPORT(void,png_set_IHDR) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_method, int compression_method, + int filter_method)); + +#if defined(PNG_oFFs_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y, + int *unit_type)); +#endif + +#if defined(PNG_oFFs_SUPPORTED) +extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y, + int unit_type)); +#endif + +#if defined(PNG_pCAL_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1, + int *type, int *nparams, png_charp *units, png_charpp *params)); +#endif + +#if defined(PNG_pCAL_SUPPORTED) +extern PNG_EXPORT(void,png_set_pCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1, + int type, int nparams, png_charp units, png_charpp params)); +#endif + +#if defined(PNG_pHYs_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); +#endif + +#if defined(PNG_pHYs_SUPPORTED) +extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type)); +#endif + +extern PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_colorp *palette, int *num_palette)); + +extern PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_colorp palette, int num_palette)); + +#if defined(PNG_sBIT_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_8p *sig_bit)); +#endif + +#if defined(PNG_sBIT_SUPPORTED) +extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_8p sig_bit)); +#endif + +#if defined(PNG_sRGB_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr, + png_infop info_ptr, int *intent)); +#endif + +#if defined(PNG_sRGB_SUPPORTED) +extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr, + png_infop info_ptr, int intent)); +extern PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr, + png_infop info_ptr, int intent)); +#endif + +#if defined(PNG_iCCP_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_iCCP) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charpp name, int *compression_type, + png_charpp profile, png_uint_32 *proflen)); + /* Note to maintainer: profile should be png_bytepp */ +#endif + +#if defined(PNG_iCCP_SUPPORTED) +extern PNG_EXPORT(void,png_set_iCCP) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charp name, int compression_type, + png_charp profile, png_uint_32 proflen)); + /* Note to maintainer: profile should be png_bytep */ +#endif + +#if defined(PNG_sPLT_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_sPLT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_sPLT_tpp entries)); +#endif + +#if defined(PNG_sPLT_SUPPORTED) +extern PNG_EXPORT(void,png_set_sPLT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_sPLT_tp entries, int nentries)); +#endif + +#if defined(PNG_TEXT_SUPPORTED) +/* png_get_text also returns the number of text chunks in *num_text */ +extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_textp *text_ptr, int *num_text)); +#endif + +/* + * Note while png_set_text() will accept a structure whose text, + * language, and translated keywords are NULL pointers, the structure + * returned by png_get_text will always contain regular + * zero-terminated C strings. They might be empty strings but + * they will never be NULL pointers. + */ + +#if defined(PNG_TEXT_SUPPORTED) +extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_textp text_ptr, int num_text)); +#endif + +#if defined(PNG_tIME_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_timep *mod_time)); +#endif + +#if defined(PNG_tIME_SUPPORTED) +extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_timep mod_time)); +#endif + +#if defined(PNG_tRNS_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytep *trans, int *num_trans, + png_color_16p *trans_values)); +#endif + +#if defined(PNG_tRNS_SUPPORTED) +extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytep trans, int num_trans, + png_color_16p trans_values)); +#endif + +#if defined(PNG_tRNS_SUPPORTED) +#endif + +#if defined(PNG_sCAL_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_sCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, int *unit, double *width, double *height)); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_sCAL_s) PNGARG((png_structp png_ptr, + png_infop info_ptr, int *unit, png_charpp swidth, png_charpp sheight)); +#endif +#endif +#endif /* PNG_sCAL_SUPPORTED */ + +#if defined(PNG_sCAL_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, int unit, double width, double height)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_sCAL_s) PNGARG((png_structp png_ptr, + png_infop info_ptr, int unit, png_charp swidth, png_charp sheight)); +#endif +#endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */ + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +/* provide a list of chunks and how they are to be handled, if the built-in + handling or default unknown chunk handling is not desired. Any chunks not + listed will be handled in the default manner. The IHDR and IEND chunks + must not be listed. + keep = 0: follow default behavour + = 1: do not keep + = 2: keep only if safe-to-copy + = 3: keep even if unsafe-to-copy +*/ +extern PNG_EXPORT(void, png_set_keep_unknown_chunks) PNGARG((png_structp + png_ptr, int keep, png_bytep chunk_list, int num_chunks)); +extern PNG_EXPORT(void, png_set_unknown_chunks) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)); +extern PNG_EXPORT(void, png_set_unknown_chunk_location) + PNGARG((png_structp png_ptr, png_infop info_ptr, int chunk, int location)); +extern PNG_EXPORT(png_uint_32,png_get_unknown_chunks) PNGARG((png_structp + png_ptr, png_infop info_ptr, png_unknown_chunkpp entries)); +#endif +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +PNG_EXPORT(int,png_handle_as_unknown) PNGARG((png_structp png_ptr, png_bytep + chunk_name)); +#endif + +/* Png_free_data() will turn off the "valid" flag for anything it frees. + If you need to turn it off for a chunk that your application has freed, + you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); */ +extern PNG_EXPORT(void, png_set_invalid) PNGARG((png_structp png_ptr, + png_infop info_ptr, int mask)); + +#if defined(PNG_INFO_IMAGE_SUPPORTED) +/* The "params" pointer is currently not used and is for future expansion. */ +extern PNG_EXPORT(void, png_read_png) PNGARG((png_structp png_ptr, + png_infop info_ptr, + int transforms, + png_voidp params)); +extern PNG_EXPORT(void, png_write_png) PNGARG((png_structp png_ptr, + png_infop info_ptr, + int transforms, + png_voidp params)); +#endif + +/* Define PNG_DEBUG at compile time for debugging information. Higher + * numbers for PNG_DEBUG mean more debugging information. This has + * only been added since version 0.95 so it is not implemented throughout + * libpng yet, but more support will be added as needed. + */ +#ifdef PNG_DEBUG +#if (PNG_DEBUG > 0) +#if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER) +#include +#if (PNG_DEBUG > 1) +#define png_debug(l,m) _RPT0(_CRT_WARN,m) +#define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m,p1) +#define png_debug2(l,m,p1,p2) _RPT2(_CRT_WARN,m,p1,p2) +#endif +#else /* PNG_DEBUG_FILE || !_MSC_VER */ +#ifndef PNG_DEBUG_FILE +#define PNG_DEBUG_FILE stderr +#endif /* PNG_DEBUG_FILE */ +#if (PNG_DEBUG > 1) +#define png_debug(l,m) \ +{ \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \ +} +#define png_debug1(l,m,p1) \ +{ \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \ +} +#define png_debug2(l,m,p1,p2) \ +{ \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \ +} +#endif /* (PNG_DEBUG > 1) */ +#endif /* _MSC_VER */ +#endif /* (PNG_DEBUG > 0) */ +#endif /* PNG_DEBUG */ +#ifndef png_debug +#define png_debug(l, m) +#endif +#ifndef png_debug1 +#define png_debug1(l, m, p1) +#endif +#ifndef png_debug2 +#define png_debug2(l, m, p1, p2) +#endif + +extern PNG_EXPORT(png_bytep,png_sig_bytes) PNGARG((void)); + +extern PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_structp png_ptr)); + +#ifdef PNG_MNG_FEATURES_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp + png_ptr, png_uint_32 mng_features_permitted)); +#endif + +/* Added to version 1.2.0 */ +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +#define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED 0x01 /* not user-settable */ +#define PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU 0x02 /* not user-settable */ +#define PNG_ASM_FLAG_MMX_READ_COMBINE_ROW 0x04 +#define PNG_ASM_FLAG_MMX_READ_INTERLACE 0x08 +#define PNG_ASM_FLAG_MMX_READ_FILTER_SUB 0x10 +#define PNG_ASM_FLAG_MMX_READ_FILTER_UP 0x20 +#define PNG_ASM_FLAG_MMX_READ_FILTER_AVG 0x40 +#define PNG_ASM_FLAG_MMX_READ_FILTER_PAETH 0x80 +#define PNG_ASM_FLAGS_INITIALIZED 0x80000000 /* not user-settable */ + +#define PNG_MMX_READ_FLAGS ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ + | PNG_ASM_FLAG_MMX_READ_INTERLACE \ + | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ + | PNG_ASM_FLAG_MMX_READ_FILTER_UP \ + | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ + | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ) +#define PNG_MMX_WRITE_FLAGS ( 0 ) + +#define PNG_MMX_FLAGS ( PNG_ASM_FLAG_MMX_SUPPORT_COMPILED \ + | PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU \ + | PNG_MMX_READ_FLAGS \ + | PNG_MMX_WRITE_FLAGS ) + +#define PNG_SELECT_READ 1 +#define PNG_SELECT_WRITE 2 + + +#if !defined(PNG_1_0_X) +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_mmx_flagmask) + PNGARG((int flag_select, int *compilerID)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_asm_flagmask) + PNGARG((int flag_select)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_asm_flags) + PNGARG((png_structp png_ptr)); + +/* pngget.c */ +extern PNG_EXPORT(png_byte,png_get_mmx_bitdepth_threshold) + PNGARG((png_structp png_ptr)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_mmx_rowbytes_threshold) + PNGARG((png_structp png_ptr)); + +/* pngset.c */ +extern PNG_EXPORT(void,png_set_asm_flags) + PNGARG((png_structp png_ptr, png_uint_32 asm_flags)); + +/* pngset.c */ +extern PNG_EXPORT(void,png_set_mmx_thresholds) + PNGARG((png_structp png_ptr, png_byte mmx_bitdepth_threshold, + png_uint_32 mmx_rowbytes_threshold)); + +#endif /* PNG_1_0_X */ +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + +#if !defined(PNG_1_0_X) +/* png.c, pnggccrd.c, or pngvcrd.c */ +extern PNG_EXPORT(int,png_mmx_support) PNGARG((void)); + +/* Strip the prepended error numbers ("#nnn ") from error and warning + * messages before passing them to the error or warning handler. */ +#ifdef PNG_ERROR_NUMBERS_SUPPORTED +extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp + png_ptr, png_uint_32 strip_mode)); +#endif +#endif /* PNG_1_0_X */ + +/* Maintainer: Put new public prototypes here ^, in libpng.3, and project defs */ + +#define PNG_HEADER_VERSION_STRING \ + " libpng version 1.2.5 - October 3, 2002 (header)\n" + +#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED +/* With these routines we avoid an integer divide, which will be slower on + * most machines. However, it does take more operations than the corresponding + * divide method, so it may be slower on a few RISC systems. There are two + * shifts (by 8 or 16 bits) and an addition, versus a single integer divide. + * + * Note that the rounding factors are NOT supposed to be the same! 128 and + * 32768 are correct for the NODIV code; 127 and 32767 are correct for the + * standard method. + * + * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ] + */ + + /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */ + +# define png_composite(composite, fg, alpha, bg) \ + { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) * (png_uint_16)(alpha) \ + + (png_uint_16)(bg)*(png_uint_16)(255 - \ + (png_uint_16)(alpha)) + (png_uint_16)128); \ + (composite) = (png_byte)((temp + (temp >> 8)) >> 8); } + +# define png_composite_16(composite, fg, alpha, bg) \ + { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) * (png_uint_32)(alpha) \ + + (png_uint_32)(bg)*(png_uint_32)(65535L - \ + (png_uint_32)(alpha)) + (png_uint_32)32768L); \ + (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); } + +#else /* standard method using integer division */ + +# define png_composite(composite, fg, alpha, bg) \ + (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \ + (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ + (png_uint_16)127) / 255) + +# define png_composite_16(composite, fg, alpha, bg) \ + (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \ + (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) + \ + (png_uint_32)32767) / (png_uint_32)65535L) + +#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */ + +/* These next functions are used internally in the code. They generally + * shouldn't be used unless you are writing code to add or replace some + * functionality in libpng. More information about most functions can + * be found in the files where the functions are located. + */ + +#if defined(PNG_INTERNAL) + +/* Various modes of operation. Note that after an init, mode is set to + * zero automatically when the structure is created. + */ +#define PNG_HAVE_IHDR 0x01 +#define PNG_HAVE_PLTE 0x02 +#define PNG_HAVE_IDAT 0x04 +#define PNG_AFTER_IDAT 0x08 +#define PNG_HAVE_IEND 0x10 +#define PNG_HAVE_gAMA 0x20 +#define PNG_HAVE_cHRM 0x40 +#define PNG_HAVE_sRGB 0x80 +#define PNG_HAVE_CHUNK_HEADER 0x100 +#define PNG_WROTE_tIME 0x200 +#define PNG_WROTE_INFO_BEFORE_PLTE 0x400 +#define PNG_BACKGROUND_IS_GRAY 0x800 +#define PNG_HAVE_PNG_SIGNATURE 0x1000 + +/* flags for the transformations the PNG library does on the image data */ +#define PNG_BGR 0x0001 +#define PNG_INTERLACE 0x0002 +#define PNG_PACK 0x0004 +#define PNG_SHIFT 0x0008 +#define PNG_SWAP_BYTES 0x0010 +#define PNG_INVERT_MONO 0x0020 +#define PNG_DITHER 0x0040 +#define PNG_BACKGROUND 0x0080 +#define PNG_BACKGROUND_EXPAND 0x0100 + /* 0x0200 unused */ +#define PNG_16_TO_8 0x0400 +#define PNG_RGBA 0x0800 +#define PNG_EXPAND 0x1000 +#define PNG_GAMMA 0x2000 +#define PNG_GRAY_TO_RGB 0x4000 +#define PNG_FILLER 0x8000L +#define PNG_PACKSWAP 0x10000L +#define PNG_SWAP_ALPHA 0x20000L +#define PNG_STRIP_ALPHA 0x40000L +#define PNG_INVERT_ALPHA 0x80000L +#define PNG_USER_TRANSFORM 0x100000L +#define PNG_RGB_TO_GRAY_ERR 0x200000L +#define PNG_RGB_TO_GRAY_WARN 0x400000L +#define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */ + +/* flags for png_create_struct */ +#define PNG_STRUCT_PNG 0x0001 +#define PNG_STRUCT_INFO 0x0002 + +/* Scaling factor for filter heuristic weighting calculations */ +#define PNG_WEIGHT_SHIFT 8 +#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT)) +#define PNG_COST_SHIFT 3 +#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT)) + +/* flags for the png_ptr->flags rather than declaring a byte for each one */ +#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001 +#define PNG_FLAG_ZLIB_CUSTOM_LEVEL 0x0002 +#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL 0x0004 +#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS 0x0008 +#define PNG_FLAG_ZLIB_CUSTOM_METHOD 0x0010 +#define PNG_FLAG_ZLIB_FINISHED 0x0020 +#define PNG_FLAG_ROW_INIT 0x0040 +#define PNG_FLAG_FILLER_AFTER 0x0080 +#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100 +#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200 +#define PNG_FLAG_CRC_CRITICAL_USE 0x0400 +#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800 +#define PNG_FLAG_FREE_PLTE 0x1000 +#define PNG_FLAG_FREE_TRNS 0x2000 +#define PNG_FLAG_FREE_HIST 0x4000 +#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000L +#define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000L +#define PNG_FLAG_LIBRARY_MISMATCH 0x20000L +#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L +#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L +#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L + +/* For use in png_set_keep_unknown, png_handle_as_unknown */ +#define HANDLE_CHUNK_AS_DEFAULT 0 +#define HANDLE_CHUNK_NEVER 1 +#define HANDLE_CHUNK_IF_SAFE 2 +#define HANDLE_CHUNK_ALWAYS 3 + +#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \ + PNG_FLAG_CRC_ANCILLARY_NOWARN) + +#define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \ + PNG_FLAG_CRC_CRITICAL_IGNORE) + +#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \ + PNG_FLAG_CRC_CRITICAL_MASK) + +/* save typing and make code easier to understand */ +#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \ + abs((int)((c1).green) - (int)((c2).green)) + \ + abs((int)((c1).blue) - (int)((c2).blue))) + +/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */ +#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN) +/* place to hold the signature string for a PNG file. */ +#ifdef PNG_USE_GLOBAL_ARRAYS + PNG_EXPORT_VAR (const png_byte FARDATA) png_sig[8]; +#else +#define png_sig png_sig_bytes(NULL) +#endif +#endif /* PNG_NO_EXTERN */ + +/* Constant strings for known chunk types. If you need to add a chunk, + * define the name here, and add an invocation of the macro in png.c and + * wherever it's needed. + */ +#define PNG_IHDR const png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'} +#define PNG_IDAT const png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'} +#define PNG_IEND const png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'} +#define PNG_PLTE const png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'} +#define PNG_bKGD const png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'} +#define PNG_cHRM const png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'} +#define PNG_gAMA const png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'} +#define PNG_hIST const png_byte png_hIST[5] = {104, 73, 83, 84, '\0'} +#define PNG_iCCP const png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'} +#define PNG_iTXt const png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'} +#define PNG_oFFs const png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'} +#define PNG_pCAL const png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'} +#define PNG_sCAL const png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'} +#define PNG_pHYs const png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'} +#define PNG_sBIT const png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'} +#define PNG_sPLT const png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'} +#define PNG_sRGB const png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'} +#define PNG_tEXt const png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'} +#define PNG_tIME const png_byte png_tIME[5] = {116, 73, 77, 69, '\0'} +#define PNG_tRNS const png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'} +#define PNG_zTXt const png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'} + +#ifdef PNG_USE_GLOBAL_ARRAYS +PNG_EXPORT_VAR (const png_byte FARDATA) png_IHDR[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_IDAT[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_IEND[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_PLTE[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_bKGD[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_cHRM[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_gAMA[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_hIST[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_iCCP[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_iTXt[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_oFFs[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_pCAL[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_sCAL[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_pHYs[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_sBIT[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_sPLT[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_sRGB[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_tEXt[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_tIME[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_tRNS[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_zTXt[5]; +#endif /* PNG_USE_GLOBAL_ARRAYS */ + + +/* Inline macros to do direct reads of bytes from the input buffer. These + * require that you are using an architecture that uses PNG byte ordering + * (MSB first) and supports unaligned data storage. I think that PowerPC + * in big-endian mode and 680x0 are the only ones that will support this. + * The x86 line of processors definitely do not. The png_get_int_32() + * routine also assumes we are using two's complement format for negative + * values, which is almost certainly true. + */ +#if defined(PNG_READ_BIG_ENDIAN_SUPPORTED) +# if defined(PNG_pCAL_SUPPORTED) || defined(PNG_oFFs_SUPPORTED) +# define png_get_int_32(buf) ( *((png_int_32p) (buf))) +# endif +# define png_get_uint_32(buf) ( *((png_uint_32p) (buf))) +# define png_get_uint_16(buf) ( *((png_uint_16p) (buf))) +#else +# if defined(PNG_pCAL_SUPPORTED) || defined(PNG_oFFs_SUPPORTED) +PNG_EXTERN png_int_32 png_get_int_32 PNGARG((png_bytep buf)); +# endif +PNG_EXTERN png_uint_32 png_get_uint_32 PNGARG((png_bytep buf)); +PNG_EXTERN png_uint_16 png_get_uint_16 PNGARG((png_bytep buf)); +#endif /* !PNG_READ_BIG_ENDIAN_SUPPORTED */ + +/* Initialize png_ptr struct for reading, and allocate any other memory. + * (old interface - DEPRECATED - use png_create_read_struct instead). + */ +extern PNG_EXPORT(void,png_read_init) PNGARG((png_structp png_ptr)); +#undef png_read_init +#define png_read_init(png_ptr) png_read_init_3(&png_ptr, \ + PNG_LIBPNG_VER_STRING, sizeof(png_struct)); +extern PNG_EXPORT(void,png_read_init_3) PNGARG((png_structpp ptr_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size)); +extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t + png_info_size)); + +/* Initialize png_ptr struct for writing, and allocate any other memory. + * (old interface - DEPRECATED - use png_create_write_struct instead). + */ +extern PNG_EXPORT(void,png_write_init) PNGARG((png_structp png_ptr)); +#undef png_write_init +#define png_write_init(png_ptr) png_write_init_3(&png_ptr, \ + PNG_LIBPNG_VER_STRING, sizeof(png_struct)); +extern PNG_EXPORT(void,png_write_init_3) PNGARG((png_structpp ptr_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size)); +extern PNG_EXPORT(void,png_write_init_2) PNGARG((png_structp png_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t + png_info_size)); + +/* Allocate memory for an internal libpng struct */ +PNG_EXTERN png_voidp png_create_struct PNGARG((int type)); + +/* Free memory from internal libpng struct */ +PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr)); + +PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr + malloc_fn, png_voidp mem_ptr)); +PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr, + png_free_ptr free_fn, png_voidp mem_ptr)); + +/* Free any memory that info_ptr points to and reset struct. */ +PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#ifndef PNG_1_0_X +/* Function to allocate memory for zlib. */ +PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size)); + +/* Function to free memory for zlib */ +PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)); + +/* Next four functions are used internally as callbacks. PNGAPI is required + * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3. */ + +PNG_EXTERN void PNGAPI png_default_read_data PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void PNGAPI png_push_fill_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t length)); +#endif + +PNG_EXTERN void PNGAPI png_default_write_data PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +#if !defined(PNG_NO_STDIO) +PNG_EXTERN void PNGAPI png_default_flush PNGARG((png_structp png_ptr)); +#endif +#endif +#else /* PNG_1_0_X */ +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void png_push_fill_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t length)); +#endif +#endif /* PNG_1_0_X */ + +/* Reset the CRC variable */ +PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr)); + +/* Write the "data" buffer to whatever output you are using. */ +PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data, + png_size_t length)); + +/* Read data from whatever input you are using into the "data" buffer */ +PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data, + png_size_t length)); + +/* Read bytes into buf, and update png_ptr->crc */ +PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf, + png_size_t length)); + +/* Decompress data in a chunk that uses compression */ +#if defined(PNG_zTXt_SUPPORTED) || defined(PNG_iTXt_SUPPORTED) || \ + defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) +PNG_EXTERN png_charp png_decompress_chunk PNGARG((png_structp png_ptr, + int comp_type, png_charp chunkdata, png_size_t chunklength, + png_size_t prefix_length, png_size_t *data_length)); +#endif + +/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */ +PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip)); + +/* Read the CRC from the file and compare it to the libpng calculated CRC */ +PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr)); + +/* Calculate the CRC over a section of data. Note that we are only + * passing a maximum of 64K on systems that have this as a memory limit, + * since this is the maximum buffer size we can specify. + */ +PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr, + png_size_t length)); + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +PNG_EXTERN void png_flush PNGARG((png_structp png_ptr)); +#endif + + +/* Place a 32-bit number into a buffer in PNG byte order (big-endian). + * The only currently known PNG chunks that use signed numbers are + * the ancillary extension chunks, oFFs and pCAL. + */ +PNG_EXTERN void png_save_uint_32 PNGARG((png_bytep buf, png_uint_32 i)); + +#if defined(PNG_WRITE_pCAL_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED) +PNG_EXTERN void png_save_int_32 PNGARG((png_bytep buf, png_int_32 i)); +#endif + +/* Place a 16-bit number into a buffer in PNG byte order. + * The parameter is declared unsigned int, not png_uint_16, + * just to avoid potential problems on pre-ANSI C compilers. + */ +PNG_EXTERN void png_save_uint_16 PNGARG((png_bytep buf, unsigned int i)); + +/* simple function to write the signature */ +PNG_EXTERN void png_write_sig PNGARG((png_structp png_ptr)); + +/* write various chunks */ + +/* Write the IHDR chunk, and update the png_struct with the necessary + * information. + */ +PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width, + png_uint_32 height, + int bit_depth, int color_type, int compression_method, int filter_method, + int interlace_method)); + +PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette, + png_uint_32 num_pal)); + +PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data, + png_size_t length)); + +PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr)); + +#if defined(PNG_WRITE_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr, png_fixed_point + file_gamma)); +#endif +#endif + +#if defined(PNG_WRITE_sBIT_SUPPORTED) +PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit, + int color_type)); +#endif + +#if defined(PNG_WRITE_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr, + double white_x, double white_y, + double red_x, double red_y, double green_x, double green_y, + double blue_x, double blue_y)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr, + png_fixed_point int_white_x, png_fixed_point int_white_y, + png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point + int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)); +#endif +#endif + +#if defined(PNG_WRITE_sRGB_SUPPORTED) +PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr, + int intent)); +#endif + +#if defined(PNG_WRITE_iCCP_SUPPORTED) +PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr, + png_charp name, int compression_type, + png_charp profile, int proflen)); + /* Note to maintainer: profile should be png_bytep */ +#endif + +#if defined(PNG_WRITE_sPLT_SUPPORTED) +PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr, + png_sPLT_tp palette)); +#endif + +#if defined(PNG_WRITE_tRNS_SUPPORTED) +PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans, + png_color_16p values, int number, int color_type)); +#endif + +#if defined(PNG_WRITE_bKGD_SUPPORTED) +PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr, + png_color_16p values, int color_type)); +#endif + +#if defined(PNG_WRITE_hIST_SUPPORTED) +PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist, + int num_hist)); +#endif + +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ + defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) +PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr, + png_charp key, png_charpp new_key)); +#endif + +#if defined(PNG_WRITE_tEXt_SUPPORTED) +PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key, + png_charp text, png_size_t text_len)); +#endif + +#if defined(PNG_WRITE_zTXt_SUPPORTED) +PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key, + png_charp text, png_size_t text_len, int compression)); +#endif + +#if defined(PNG_WRITE_iTXt_SUPPORTED) +PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr, + int compression, png_charp key, png_charp lang, png_charp lang_key, + png_charp text)); +#endif + +#if defined(PNG_TEXT_SUPPORTED) /* Added at version 1.0.14 and 1.2.4 */ +PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr, + png_infop info_ptr, png_textp text_ptr, int num_text)); +#endif + +#if defined(PNG_WRITE_oFFs_SUPPORTED) +PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr, + png_int_32 x_offset, png_int_32 y_offset, int unit_type)); +#endif + +#if defined(PNG_WRITE_pCAL_SUPPORTED) +PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose, + png_int_32 X0, png_int_32 X1, int type, int nparams, + png_charp units, png_charpp params)); +#endif + +#if defined(PNG_WRITE_pHYs_SUPPORTED) +PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr, + png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, + int unit_type)); +#endif + +#if defined(PNG_WRITE_tIME_SUPPORTED) +PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr, + png_timep mod_time)); +#endif + +#if defined(PNG_WRITE_sCAL_SUPPORTED) +#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO) +PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr, + int unit, double width, double height)); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr, + int unit, png_charp width, png_charp height)); +#endif +#endif +#endif + +/* Called when finished processing a row of data */ +PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr)); + +/* Internal use only. Called before first row of data */ +PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr)); + +#if defined(PNG_READ_GAMMA_SUPPORTED) +PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr)); +#endif + +/* combine a row of data, dealing with alpha, etc. if requested */ +PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row, + int mask)); + +#if defined(PNG_READ_INTERLACING_SUPPORTED) +/* expand an interlaced row */ +/* OLD pre-1.0.9 interface: +PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info, + png_bytep row, int pass, png_uint_32 transformations)); + */ +PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr)); +#endif + +/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */ + +#if defined(PNG_WRITE_INTERLACING_SUPPORTED) +/* grab pixels out of a row for an interlaced pass */ +PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info, + png_bytep row, int pass)); +#endif + +/* unfilter a row */ +PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr, + png_row_infop row_info, png_bytep row, png_bytep prev_row, int filter)); + +/* Choose the best filter to use and filter the row data */ +PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr, + png_row_infop row_info)); + +/* Write out the filtered row. */ +PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr, + png_bytep filtered_row)); +/* finish a row while reading, dealing with interlacing passes, etc. */ +PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr)); + +/* initialize the row buffers, etc. */ +PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr)); +/* optional call to update the users info structure */ +PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +/* these are the functions that do the transformations */ +#if defined(PNG_READ_FILLER_SUPPORTED) +PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info, + png_bytep row, png_uint_32 filler, png_uint_32 flags)); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ + defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info, + png_bytep row, png_uint_32 flags)); +#endif + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED) +PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, png_row_infop + row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) +PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) +PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) +PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row, + png_color_8p sig_bits)); +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_16_TO_8_SUPPORTED) +PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) +PNG_EXTERN void png_do_dither PNGARG((png_row_infop row_info, + png_bytep row, png_bytep palette_lookup, png_bytep dither_lookup)); + +# if defined(PNG_CORRECT_PALETTE_SUPPORTED) +PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr, + png_colorp palette, int num_palette)); +# endif +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_WRITE_PACK_SUPPORTED) +PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info, + png_bytep row, png_uint_32 bit_depth)); +#endif + +#if defined(PNG_WRITE_SHIFT_SUPPORTED) +PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, png_bytep row, + png_color_8p bit_depth)); +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) +#if defined(PNG_READ_GAMMA_SUPPORTED) +PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row, + png_color_16p trans_values, png_color_16p background, + png_color_16p background_1, + png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1, + png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1, + png_uint_16pp gamma_16_to_1, int gamma_shift)); +#else +PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row, + png_color_16p trans_values, png_color_16p background)); +#endif +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) +PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row, + png_bytep gamma_table, png_uint_16pp gamma_16_table, + int gamma_shift)); +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) +PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info, + png_bytep row, png_colorp palette, png_bytep trans, int num_trans)); +PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info, + png_bytep row, png_color_16p trans_value)); +#endif + +/* The following decodes the appropriate chunks, and does error correction, + * then calls the appropriate callback for the chunk if it is valid. + */ + +/* decode the IHDR chunk */ +PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); + +#if defined(PNG_READ_bKGD_SUPPORTED) +PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_cHRM_SUPPORTED) +PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_gAMA_SUPPORTED) +PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_hIST_SUPPORTED) +PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_iCCP_SUPPORTED) +extern void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif /* PNG_READ_iCCP_SUPPORTED */ + +#if defined(PNG_READ_iTXt_SUPPORTED) +PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_oFFs_SUPPORTED) +PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_pCAL_SUPPORTED) +PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_pHYs_SUPPORTED) +PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_sBIT_SUPPORTED) +PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_sCAL_SUPPORTED) +PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_sPLT_SUPPORTED) +extern void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif /* PNG_READ_sPLT_SUPPORTED */ + +#if defined(PNG_READ_sRGB_SUPPORTED) +PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_tEXt_SUPPORTED) +PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_tIME_SUPPORTED) +PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_tRNS_SUPPORTED) +PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_zTXt_SUPPORTED) +PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); + +PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr, + png_bytep chunk_name)); + +/* handle the transformations for reading and writing */ +PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr)); + +PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr, + png_uint_32 length)); +PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t buffer_length)); +PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t buffer_length)); +PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row)); +PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr)); +#if defined(PNG_READ_tEXt_SUPPORTED) +PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) +PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) +PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif + +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +#ifdef PNG_MNG_FEATURES_SUPPORTED +PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info, + png_bytep row)); +PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +/* png.c */ /* PRIVATE */ +PNG_EXTERN void png_init_mmx_flags PNGARG((png_structp png_ptr)); +#endif +/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */ + +#endif /* PNG_INTERNAL */ + +#ifdef __cplusplus +} +#endif + +#endif /* PNG_VERSION_INFO_ONLY */ +/* do not put anything past this line */ +#endif /* PNG_H */ diff --git a/winclude/pngasmrd.h b/winclude/pngasmrd.h new file mode 100755 index 000000000..ca4c12bcc --- /dev/null +++ b/winclude/pngasmrd.h @@ -0,0 +1,11 @@ +/* pngasmrd.h - assembler version of utilities to read a PNG file + * + * libpng 1.2.5 - October 3, 2002 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 2002 Glenn Randers-Pehrson + * + */ + +/* This file is obsolete in libpng-1.0.9 and later; its contents now appear + * at the end of pngconf.h. + */ diff --git a/winclude/pngconf.h b/winclude/pngconf.h new file mode 100755 index 000000000..e17202968 --- /dev/null +++ b/winclude/pngconf.h @@ -0,0 +1,1348 @@ +/* pngconf.h - machine configurable file for libpng + * + * libpng 1.2.5 - October 3, 2002 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2002 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + */ + +/* Any machine specific code is near the front of this file, so if you + * are configuring libpng for a machine, you may want to read the section + * starting here down to where it starts to typedef png_color, png_text, + * and png_info. + */ + +#ifndef PNGCONF_H +#define PNGCONF_H + +/* This is the size of the compression buffer, and thus the size of + * an IDAT chunk. Make this whatever size you feel is best for your + * machine. One of these will be allocated per png_struct. When this + * is full, it writes the data to the disk, and does some other + * calculations. Making this an extremely small size will slow + * the library down, but you may want to experiment to determine + * where it becomes significant, if you are concerned with memory + * usage. Note that zlib allocates at least 32Kb also. For readers, + * this describes the size of the buffer available to read the data in. + * Unless this gets smaller than the size of a row (compressed), + * it should not make much difference how big this is. + */ + +#ifndef PNG_ZBUF_SIZE +# define PNG_ZBUF_SIZE 8192 +#endif + +/* Enable if you want a write-only libpng */ + +#ifndef PNG_NO_READ_SUPPORTED +# define PNG_READ_SUPPORTED +#endif + +/* Enable if you want a read-only libpng */ + +#ifndef PNG_NO_WRITE_SUPPORTED +# define PNG_WRITE_SUPPORTED +#endif + +/* Enabled by default in 1.2.0. You can disable this if you don't need to + support PNGs that are embedded in MNG datastreams */ +#if !defined(PNG_1_0_X) && !defined(PNG_NO_MNG_FEATURES) +# ifndef PNG_MNG_FEATURES_SUPPORTED +# define PNG_MNG_FEATURES_SUPPORTED +# endif +#endif + +#ifndef PNG_NO_FLOATING_POINT_SUPPORTED +# ifndef PNG_FLOATING_POINT_SUPPORTED +# define PNG_FLOATING_POINT_SUPPORTED +# endif +#endif + +/* If you are running on a machine where you cannot allocate more + * than 64K of memory at once, uncomment this. While libpng will not + * normally need that much memory in a chunk (unless you load up a very + * large file), zlib needs to know how big of a chunk it can use, and + * libpng thus makes sure to check any memory allocation to verify it + * will fit into memory. +#define PNG_MAX_MALLOC_64K + */ +#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) +# define PNG_MAX_MALLOC_64K +#endif + +/* Special munging to support doing things the 'cygwin' way: + * 'Normal' png-on-win32 defines/defaults: + * PNG_BUILD_DLL -- building dll + * PNG_USE_DLL -- building an application, linking to dll + * (no define) -- building static library, or building an + * application and linking to the static lib + * 'Cygwin' defines/defaults: + * PNG_BUILD_DLL -- (ignored) building the dll + * (no define) -- (ignored) building an application, linking to the dll + * PNG_STATIC -- (ignored) building the static lib, or building an + * application that links to the static lib. + * ALL_STATIC -- (ignored) building various static libs, or building an + * application that links to the static libs. + * Thus, + * a cygwin user should define either PNG_BUILD_DLL or PNG_STATIC, and + * this bit of #ifdefs will define the 'correct' config variables based on + * that. If a cygwin user *wants* to define 'PNG_USE_DLL' that's okay, but + * unnecessary. + * + * Also, the precedence order is: + * ALL_STATIC (since we can't #undef something outside our namespace) + * PNG_BUILD_DLL + * PNG_STATIC + * (nothing) == PNG_USE_DLL + * + * CYGWIN (2002-01-20): The preceding is now obsolete. With the advent + * of auto-import in binutils, we no longer need to worry about + * __declspec(dllexport) / __declspec(dllimport) and friends. Therefore, + * we don't need to worry about PNG_STATIC or ALL_STATIC when it comes + * to __declspec() stuff. However, we DO need to worry about + * PNG_BUILD_DLL and PNG_STATIC because those change some defaults + * such as CONSOLE_IO and whether GLOBAL_ARRAYS are allowed. + */ +#if defined(__CYGWIN__) +# if defined(ALL_STATIC) +# if defined(PNG_BUILD_DLL) +# undef PNG_BUILD_DLL +# endif +# if defined(PNG_USE_DLL) +# undef PNG_USE_DLL +# endif +# if defined(PNG_DLL) +# undef PNG_DLL +# endif +# if !defined(PNG_STATIC) +# define PNG_STATIC +# endif +# else +# if defined (PNG_BUILD_DLL) +# if defined(PNG_STATIC) +# undef PNG_STATIC +# endif +# if defined(PNG_USE_DLL) +# undef PNG_USE_DLL +# endif +# if !defined(PNG_DLL) +# define PNG_DLL +# endif +# else +# if defined(PNG_STATIC) +# if defined(PNG_USE_DLL) +# undef PNG_USE_DLL +# endif +# if defined(PNG_DLL) +# undef PNG_DLL +# endif +# else +# if !defined(PNG_USE_DLL) +# define PNG_USE_DLL +# endif +# if !defined(PNG_DLL) +# define PNG_DLL +# endif +# endif +# endif +# endif +#endif + +/* This protects us against compilers that run on a windowing system + * and thus don't have or would rather us not use the stdio types: + * stdin, stdout, and stderr. The only one currently used is stderr + * in png_error() and png_warning(). #defining PNG_NO_CONSOLE_IO will + * prevent these from being compiled and used. #defining PNG_NO_STDIO + * will also prevent these, plus will prevent the entire set of stdio + * macros and functions (FILE *, printf, etc.) from being compiled and used, + * unless (PNG_DEBUG > 0) has been #defined. + * + * #define PNG_NO_CONSOLE_IO + * #define PNG_NO_STDIO + */ + +#if defined(_WIN32_WCE) +# include + /* Console I/O functions are not supported on WindowsCE */ +# define PNG_NO_CONSOLE_IO +# ifdef PNG_DEBUG +# undef PNG_DEBUG +# endif +#endif + +#ifdef PNG_BUILD_DLL +# ifndef PNG_CONSOLE_IO_SUPPORTED +# ifndef PNG_NO_CONSOLE_IO +# define PNG_NO_CONSOLE_IO +# endif +# endif +#endif + +# ifdef PNG_NO_STDIO +# ifndef PNG_NO_CONSOLE_IO +# define PNG_NO_CONSOLE_IO +# endif +# ifdef PNG_DEBUG +# if (PNG_DEBUG > 0) +# include +# endif +# endif +# else +# if !defined(_WIN32_WCE) +/* "stdio.h" functions are not supported on WindowsCE */ +# include +# endif +# endif + +/* This macro protects us against machines that don't have function + * prototypes (ie K&R style headers). If your compiler does not handle + * function prototypes, define this macro and use the included ansi2knr. + * I've always been able to use _NO_PROTO as the indicator, but you may + * need to drag the empty declaration out in front of here, or change the + * ifdef to suit your own needs. + */ +#ifndef PNGARG + +#ifdef OF /* zlib prototype munger */ +# define PNGARG(arglist) OF(arglist) +#else + +#ifdef _NO_PROTO +# define PNGARG(arglist) () +# ifndef PNG_TYPECAST_NULL +# define PNG_TYPECAST_NULL +# endif +#else +# define PNGARG(arglist) arglist +#endif /* _NO_PROTO */ + +#endif /* OF */ + +#endif /* PNGARG */ + +/* Try to determine if we are compiling on a Mac. Note that testing for + * just __MWERKS__ is not good enough, because the Codewarrior is now used + * on non-Mac platforms. + */ +#ifndef MACOS +# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ + defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) +# define MACOS +# endif +#endif + +/* enough people need this for various reasons to include it here */ +#if !defined(MACOS) && !defined(RISCOS) && !defined(_WIN32_WCE) +# include +#endif + +#if !defined(PNG_SETJMP_NOT_SUPPORTED) && !defined(PNG_NO_SETJMP_SUPPORTED) +# define PNG_SETJMP_SUPPORTED +#endif + +#ifdef PNG_SETJMP_SUPPORTED +/* This is an attempt to force a single setjmp behaviour on Linux. If + * the X config stuff didn't define _BSD_SOURCE we wouldn't need this. + */ + +# ifdef __linux__ +# ifdef _BSD_SOURCE +# define PNG_SAVE_BSD_SOURCE +# undef _BSD_SOURCE +# endif +# ifdef _SETJMP_H + __png.h__ already includes setjmp.h; + __dont__ include it again.; +# endif +# endif /* __linux__ */ + + /* include setjmp.h for error handling */ +# include + +# ifdef __linux__ +# ifdef PNG_SAVE_BSD_SOURCE +# define _BSD_SOURCE +# undef PNG_SAVE_BSD_SOURCE +# endif +# endif /* __linux__ */ +#endif /* PNG_SETJMP_SUPPORTED */ + +#ifdef BSD +# include +#else +# include +#endif + +/* Other defines for things like memory and the like can go here. */ +#ifdef PNG_INTERNAL + +#include + +/* The functions exported by PNG_EXTERN are PNG_INTERNAL functions, which + * aren't usually used outside the library (as far as I know), so it is + * debatable if they should be exported at all. In the future, when it is + * possible to have run-time registry of chunk-handling functions, some of + * these will be made available again. +#define PNG_EXTERN extern + */ +#define PNG_EXTERN + +/* Other defines specific to compilers can go here. Try to keep + * them inside an appropriate ifdef/endif pair for portability. + */ + +#if defined(PNG_FLOATING_POINT_SUPPORTED) +# if defined(MACOS) + /* We need to check that hasn't already been included earlier + * as it seems it doesn't agree with , yet we should really use + * if possible. + */ +# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__) +# include +# endif +# else +# include +# endif +# if defined(_AMIGA) && defined(__SASC) && defined(_M68881) + /* Amiga SAS/C: We must include builtin FPU functions when compiling using + * MATH=68881 + */ +# include +# endif +#endif + +/* Codewarrior on NT has linking problems without this. */ +#if (defined(__MWERKS__) && defined(WIN32)) || defined(__STDC__) +# define PNG_ALWAYS_EXTERN +#endif + +/* For some reason, Borland C++ defines memcmp, etc. in mem.h, not + * stdlib.h like it should (I think). Or perhaps this is a C++ + * "feature"? + */ +#ifdef __TURBOC__ +# include +# include "alloc.h" +#endif + +#if defined(_MSC_VER) && (defined(WIN32) || defined(_Windows) || \ + defined(_WINDOWS) || defined(_WIN32) || defined(__WIN32__)) +# include +#endif + +/* This controls how fine the dithering gets. As this allocates + * a largish chunk of memory (32K), those who are not as concerned + * with dithering quality can decrease some or all of these. + */ +#ifndef PNG_DITHER_RED_BITS +# define PNG_DITHER_RED_BITS 5 +#endif +#ifndef PNG_DITHER_GREEN_BITS +# define PNG_DITHER_GREEN_BITS 5 +#endif +#ifndef PNG_DITHER_BLUE_BITS +# define PNG_DITHER_BLUE_BITS 5 +#endif + +/* This controls how fine the gamma correction becomes when you + * are only interested in 8 bits anyway. Increasing this value + * results in more memory being used, and more pow() functions + * being called to fill in the gamma tables. Don't set this value + * less then 8, and even that may not work (I haven't tested it). + */ + +#ifndef PNG_MAX_GAMMA_8 +# define PNG_MAX_GAMMA_8 11 +#endif + +/* This controls how much a difference in gamma we can tolerate before + * we actually start doing gamma conversion. + */ +#ifndef PNG_GAMMA_THRESHOLD +# define PNG_GAMMA_THRESHOLD 0.05 +#endif + +#endif /* PNG_INTERNAL */ + +/* The following uses const char * instead of char * for error + * and warning message functions, so some compilers won't complain. + * If you do not want to use const, define PNG_NO_CONST here. + */ + +#ifndef PNG_NO_CONST +# define PNG_CONST const +#else +# define PNG_CONST +#endif + +/* The following defines give you the ability to remove code from the + * library that you will not be using. I wish I could figure out how to + * automate this, but I can't do that without making it seriously hard + * on the users. So if you are not using an ability, change the #define + * to and #undef, and that part of the library will not be compiled. If + * your linker can't find a function, you may want to make sure the + * ability is defined here. Some of these depend upon some others being + * defined. I haven't figured out all the interactions here, so you may + * have to experiment awhile to get everything to compile. If you are + * creating or using a shared library, you probably shouldn't touch this, + * as it will affect the size of the structures, and this will cause bad + * things to happen if the library and/or application ever change. + */ + +/* Any features you will not be using can be undef'ed here */ + +/* GR-P, 0.96a: Set "*TRANSFORMS_SUPPORTED as default but allow user + * to turn it off with "*TRANSFORMS_NOT_SUPPORTED" or *PNG_NO_*_TRANSFORMS + * on the compile line, then pick and choose which ones to define without + * having to edit this file. It is safe to use the *TRANSFORMS_NOT_SUPPORTED + * if you only want to have a png-compliant reader/writer but don't need + * any of the extra transformations. This saves about 80 kbytes in a + * typical installation of the library. (PNG_NO_* form added in version + * 1.0.1c, for consistency) + */ + +/* The size of the png_text structure changed in libpng-1.0.6 when + * iTXt is supported. It is turned off by default, to support old apps + * that malloc the png_text structure instead of calling png_set_text() + * and letting libpng malloc it. It will be turned on by default in + * libpng-1.3.0. + */ + +#ifndef PNG_iTXt_SUPPORTED +# if !defined(PNG_READ_iTXt_SUPPORTED) && !defined(PNG_NO_READ_iTXt) +# define PNG_NO_READ_iTXt +# endif +# if !defined(PNG_WRITE_iTXt_SUPPORTED) && !defined(PNG_NO_WRITE_iTXt) +# define PNG_NO_WRITE_iTXt +# endif +#endif + +/* The following support, added after version 1.0.0, can be turned off here en + * masse by defining PNG_LEGACY_SUPPORTED in case you need binary compatibility + * with old applications that require the length of png_struct and png_info + * to remain unchanged. + */ + +#ifdef PNG_LEGACY_SUPPORTED +# define PNG_NO_FREE_ME +# define PNG_NO_READ_UNKNOWN_CHUNKS +# define PNG_NO_WRITE_UNKNOWN_CHUNKS +# define PNG_NO_READ_USER_CHUNKS +# define PNG_NO_READ_iCCP +# define PNG_NO_WRITE_iCCP +# define PNG_NO_READ_iTXt +# define PNG_NO_WRITE_iTXt +# define PNG_NO_READ_sCAL +# define PNG_NO_WRITE_sCAL +# define PNG_NO_READ_sPLT +# define PNG_NO_WRITE_sPLT +# define PNG_NO_INFO_IMAGE +# define PNG_NO_READ_RGB_TO_GRAY +# define PNG_NO_READ_USER_TRANSFORM +# define PNG_NO_WRITE_USER_TRANSFORM +# define PNG_NO_USER_MEM +# define PNG_NO_READ_EMPTY_PLTE +# define PNG_NO_MNG_FEATURES +# define PNG_NO_FIXED_POINT_SUPPORTED +#endif + +/* Ignore attempt to turn off both floating and fixed point support */ +#if !defined(PNG_FLOATING_POINT_SUPPORTED) || \ + !defined(PNG_NO_FIXED_POINT_SUPPORTED) +# define PNG_FIXED_POINT_SUPPORTED +#endif + +#ifndef PNG_NO_FREE_ME +# define PNG_FREE_ME_SUPPORTED +#endif + +#if defined(PNG_READ_SUPPORTED) + +#if !defined(PNG_READ_TRANSFORMS_NOT_SUPPORTED) && \ + !defined(PNG_NO_READ_TRANSFORMS) +# define PNG_READ_TRANSFORMS_SUPPORTED +#endif + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +# ifndef PNG_NO_READ_EXPAND +# define PNG_READ_EXPAND_SUPPORTED +# endif +# ifndef PNG_NO_READ_SHIFT +# define PNG_READ_SHIFT_SUPPORTED +# endif +# ifndef PNG_NO_READ_PACK +# define PNG_READ_PACK_SUPPORTED +# endif +# ifndef PNG_NO_READ_BGR +# define PNG_READ_BGR_SUPPORTED +# endif +# ifndef PNG_NO_READ_SWAP +# define PNG_READ_SWAP_SUPPORTED +# endif +# ifndef PNG_NO_READ_PACKSWAP +# define PNG_READ_PACKSWAP_SUPPORTED +# endif +# ifndef PNG_NO_READ_INVERT +# define PNG_READ_INVERT_SUPPORTED +# endif +# ifndef PNG_NO_READ_DITHER +# define PNG_READ_DITHER_SUPPORTED +# endif +# ifndef PNG_NO_READ_BACKGROUND +# define PNG_READ_BACKGROUND_SUPPORTED +# endif +# ifndef PNG_NO_READ_16_TO_8 +# define PNG_READ_16_TO_8_SUPPORTED +# endif +# ifndef PNG_NO_READ_FILLER +# define PNG_READ_FILLER_SUPPORTED +# endif +# ifndef PNG_NO_READ_GAMMA +# define PNG_READ_GAMMA_SUPPORTED +# endif +# ifndef PNG_NO_READ_GRAY_TO_RGB +# define PNG_READ_GRAY_TO_RGB_SUPPORTED +# endif +# ifndef PNG_NO_READ_SWAP_ALPHA +# define PNG_READ_SWAP_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_READ_INVERT_ALPHA +# define PNG_READ_INVERT_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_READ_STRIP_ALPHA +# define PNG_READ_STRIP_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_READ_USER_TRANSFORM +# define PNG_READ_USER_TRANSFORM_SUPPORTED +# endif +# ifndef PNG_NO_READ_RGB_TO_GRAY +# define PNG_READ_RGB_TO_GRAY_SUPPORTED +# endif +#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ + +#if !defined(PNG_NO_PROGRESSIVE_READ) && \ + !defined(PNG_PROGRESSIVE_READ_NOT_SUPPORTED) /* if you don't do progressive */ +# define PNG_PROGRESSIVE_READ_SUPPORTED /* reading. This is not talking */ +#endif /* about interlacing capability! You'll */ + /* still have interlacing unless you change the following line: */ + +#define PNG_READ_INTERLACING_SUPPORTED /* required for PNG-compliant decoders */ + +#ifndef PNG_NO_READ_COMPOSITE_NODIV +# ifndef PNG_NO_READ_COMPOSITED_NODIV /* libpng-1.0.x misspelling */ +# define PNG_READ_COMPOSITE_NODIV_SUPPORTED /* well tested on Intel, SGI */ +# endif +#endif + +/* Deprecated, will be removed from version 2.0.0. + Use PNG_MNG_FEATURES_SUPPORTED instead. */ +#ifndef PNG_NO_READ_EMPTY_PLTE +# define PNG_READ_EMPTY_PLTE_SUPPORTED +#endif + +#endif /* PNG_READ_SUPPORTED */ + +#if defined(PNG_WRITE_SUPPORTED) + +# if !defined(PNG_WRITE_TRANSFORMS_NOT_SUPPORTED) && \ + !defined(PNG_NO_WRITE_TRANSFORMS) +# define PNG_WRITE_TRANSFORMS_SUPPORTED +#endif + +#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED +# ifndef PNG_NO_WRITE_SHIFT +# define PNG_WRITE_SHIFT_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_PACK +# define PNG_WRITE_PACK_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_BGR +# define PNG_WRITE_BGR_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_SWAP +# define PNG_WRITE_SWAP_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_PACKSWAP +# define PNG_WRITE_PACKSWAP_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_INVERT +# define PNG_WRITE_INVERT_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_FILLER +# define PNG_WRITE_FILLER_SUPPORTED /* same as WRITE_STRIP_ALPHA */ +# endif +# ifndef PNG_NO_WRITE_SWAP_ALPHA +# define PNG_WRITE_SWAP_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_INVERT_ALPHA +# define PNG_WRITE_INVERT_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_USER_TRANSFORM +# define PNG_WRITE_USER_TRANSFORM_SUPPORTED +# endif +#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */ + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +# ifndef PNG_NO_USER_TRANSFORM_PTR +# define PNG_USER_TRANSFORM_PTR_SUPPORTED +# endif +#endif + +#define PNG_WRITE_INTERLACING_SUPPORTED /* not required for PNG-compliant + encoders, but can cause trouble + if left undefined */ + +#if !defined(PNG_NO_WRITE_WEIGHTED_FILTER) && \ + defined(PNG_FLOATING_POINT_SUPPORTED) +# define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED +#endif + +#ifndef PNG_1_0_X +#ifndef PNG_NO_ERROR_NUMBERS +#define PNG_ERROR_NUMBERS_SUPPORTED +#endif +#endif /* PNG_1_0_X */ + +#ifndef PNG_NO_WRITE_FLUSH +# define PNG_WRITE_FLUSH_SUPPORTED +#endif + +/* Deprecated, see PNG_MNG_FEATURES_SUPPORTED, above */ +#ifndef PNG_NO_WRITE_EMPTY_PLTE +# define PNG_WRITE_EMPTY_PLTE_SUPPORTED +#endif + +#endif /* PNG_WRITE_SUPPORTED */ + +#ifndef PNG_NO_STDIO +# define PNG_TIME_RFC1123_SUPPORTED +#endif + +/* This adds extra functions in pngget.c for accessing data from the + * info pointer (added in version 0.99) + * png_get_image_width() + * png_get_image_height() + * png_get_bit_depth() + * png_get_color_type() + * png_get_compression_type() + * png_get_filter_type() + * png_get_interlace_type() + * png_get_pixel_aspect_ratio() + * png_get_pixels_per_meter() + * png_get_x_offset_pixels() + * png_get_y_offset_pixels() + * png_get_x_offset_microns() + * png_get_y_offset_microns() + */ +#if !defined(PNG_NO_EASY_ACCESS) && !defined(PNG_EASY_ACCESS_SUPPORTED) +# define PNG_EASY_ACCESS_SUPPORTED +#endif + +/* PNG_ASSEMBLER_CODE was enabled by default in version 1.2.0 + even when PNG_USE_PNGVCRD or PNG_USE_PNGGCCRD is not defined */ +#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_ASSEMBLER_CODE) +# ifndef PNG_ASSEMBLER_CODE_SUPPORTED +# define PNG_ASSEMBLER_CODE_SUPPORTED +# endif +# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) +# define PNG_MMX_CODE_SUPPORTED +# endif +#endif + +/* If you are sure that you don't need thread safety and you are compiling + with PNG_USE_PNGCCRD for an MMX application, you can define this for + faster execution. See pnggccrd.c. +#define PNG_THREAD_UNSAFE_OK +*/ + +#if !defined(PNG_1_0_X) +#if !defined(PNG_NO_USER_MEM) && !defined(PNG_USER_MEM_SUPPORTED) +# define PNG_USER_MEM_SUPPORTED +#endif +#endif /* PNG_1_0_X */ + +/* These are currently experimental features, define them if you want */ + +/* very little testing */ +/* +#ifdef PNG_READ_SUPPORTED +# ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED +# define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED +# endif +#endif +*/ + +/* This is only for PowerPC big-endian and 680x0 systems */ +/* some testing */ +/* +#ifdef PNG_READ_SUPPORTED +# ifndef PNG_PNG_READ_BIG_ENDIAN_SUPPORTED +# define PNG_READ_BIG_ENDIAN_SUPPORTED +# endif +#endif +*/ + +/* Buggy compilers (e.g., gcc 2.7.2.2) need this */ +/* +#define PNG_NO_POINTER_INDEXING +*/ + +/* These functions are turned off by default, as they will be phased out. */ +/* +#define PNG_USELESS_TESTS_SUPPORTED +#define PNG_CORRECT_PALETTE_SUPPORTED +*/ + +/* Any chunks you are not interested in, you can undef here. The + * ones that allocate memory may be expecially important (hIST, + * tEXt, zTXt, tRNS, pCAL). Others will just save time and make png_info + * a bit smaller. + */ + +#if defined(PNG_READ_SUPPORTED) && \ + !defined(PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \ + !defined(PNG_NO_READ_ANCILLARY_CHUNKS) +# define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED +#endif + +#if defined(PNG_WRITE_SUPPORTED) && \ + !defined(PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \ + !defined(PNG_NO_WRITE_ANCILLARY_CHUNKS) +# define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED +#endif + +#ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED + +#ifdef PNG_NO_READ_TEXT +# define PNG_NO_READ_iTXt +# define PNG_NO_READ_tEXt +# define PNG_NO_READ_zTXt +#endif +#ifndef PNG_NO_READ_bKGD +# define PNG_READ_bKGD_SUPPORTED +# define PNG_bKGD_SUPPORTED +#endif +#ifndef PNG_NO_READ_cHRM +# define PNG_READ_cHRM_SUPPORTED +# define PNG_cHRM_SUPPORTED +#endif +#ifndef PNG_NO_READ_gAMA +# define PNG_READ_gAMA_SUPPORTED +# define PNG_gAMA_SUPPORTED +#endif +#ifndef PNG_NO_READ_hIST +# define PNG_READ_hIST_SUPPORTED +# define PNG_hIST_SUPPORTED +#endif +#ifndef PNG_NO_READ_iCCP +# define PNG_READ_iCCP_SUPPORTED +# define PNG_iCCP_SUPPORTED +#endif +#ifndef PNG_NO_READ_iTXt +# ifndef PNG_READ_iTXt_SUPPORTED +# define PNG_READ_iTXt_SUPPORTED +# endif +# ifndef PNG_iTXt_SUPPORTED +# define PNG_iTXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_READ_oFFs +# define PNG_READ_oFFs_SUPPORTED +# define PNG_oFFs_SUPPORTED +#endif +#ifndef PNG_NO_READ_pCAL +# define PNG_READ_pCAL_SUPPORTED +# define PNG_pCAL_SUPPORTED +#endif +#ifndef PNG_NO_READ_sCAL +# define PNG_READ_sCAL_SUPPORTED +# define PNG_sCAL_SUPPORTED +#endif +#ifndef PNG_NO_READ_pHYs +# define PNG_READ_pHYs_SUPPORTED +# define PNG_pHYs_SUPPORTED +#endif +#ifndef PNG_NO_READ_sBIT +# define PNG_READ_sBIT_SUPPORTED +# define PNG_sBIT_SUPPORTED +#endif +#ifndef PNG_NO_READ_sPLT +# define PNG_READ_sPLT_SUPPORTED +# define PNG_sPLT_SUPPORTED +#endif +#ifndef PNG_NO_READ_sRGB +# define PNG_READ_sRGB_SUPPORTED +# define PNG_sRGB_SUPPORTED +#endif +#ifndef PNG_NO_READ_tEXt +# define PNG_READ_tEXt_SUPPORTED +# define PNG_tEXt_SUPPORTED +#endif +#ifndef PNG_NO_READ_tIME +# define PNG_READ_tIME_SUPPORTED +# define PNG_tIME_SUPPORTED +#endif +#ifndef PNG_NO_READ_tRNS +# define PNG_READ_tRNS_SUPPORTED +# define PNG_tRNS_SUPPORTED +#endif +#ifndef PNG_NO_READ_zTXt +# define PNG_READ_zTXt_SUPPORTED +# define PNG_zTXt_SUPPORTED +#endif +#ifndef PNG_NO_READ_UNKNOWN_CHUNKS +# define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED +# define PNG_UNKNOWN_CHUNKS_SUPPORTED +# endif +# ifndef PNG_NO_HANDLE_AS_UNKNOWN +# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# endif +#endif +#if !defined(PNG_NO_READ_USER_CHUNKS) && \ + defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) +# define PNG_READ_USER_CHUNKS_SUPPORTED +# define PNG_USER_CHUNKS_SUPPORTED +# ifdef PNG_NO_READ_UNKNOWN_CHUNKS +# undef PNG_NO_READ_UNKNOWN_CHUNKS +# endif +# ifdef PNG_NO_HANDLE_AS_UNKNOWN +# undef PNG_NO_HANDLE_AS_UNKNOWN +# endif +#endif +#ifndef PNG_NO_READ_OPT_PLTE +# define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the */ +#endif /* optional PLTE chunk in RGB and RGBA images */ +#if defined(PNG_READ_iTXt_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) || \ + defined(PNG_READ_zTXt_SUPPORTED) +# define PNG_READ_TEXT_SUPPORTED +# define PNG_TEXT_SUPPORTED +#endif + +#endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */ + +#ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED + +#ifdef PNG_NO_WRITE_TEXT +# define PNG_NO_WRITE_iTXt +# define PNG_NO_WRITE_tEXt +# define PNG_NO_WRITE_zTXt +#endif +#ifndef PNG_NO_WRITE_bKGD +# define PNG_WRITE_bKGD_SUPPORTED +# ifndef PNG_bKGD_SUPPORTED +# define PNG_bKGD_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_cHRM +# define PNG_WRITE_cHRM_SUPPORTED +# ifndef PNG_cHRM_SUPPORTED +# define PNG_cHRM_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_gAMA +# define PNG_WRITE_gAMA_SUPPORTED +# ifndef PNG_gAMA_SUPPORTED +# define PNG_gAMA_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_hIST +# define PNG_WRITE_hIST_SUPPORTED +# ifndef PNG_hIST_SUPPORTED +# define PNG_hIST_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_iCCP +# define PNG_WRITE_iCCP_SUPPORTED +# ifndef PNG_iCCP_SUPPORTED +# define PNG_iCCP_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_iTXt +# ifndef PNG_WRITE_iTXt_SUPPORTED +# define PNG_WRITE_iTXt_SUPPORTED +# endif +# ifndef PNG_iTXt_SUPPORTED +# define PNG_iTXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_oFFs +# define PNG_WRITE_oFFs_SUPPORTED +# ifndef PNG_oFFs_SUPPORTED +# define PNG_oFFs_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_pCAL +# define PNG_WRITE_pCAL_SUPPORTED +# ifndef PNG_pCAL_SUPPORTED +# define PNG_pCAL_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sCAL +# define PNG_WRITE_sCAL_SUPPORTED +# ifndef PNG_sCAL_SUPPORTED +# define PNG_sCAL_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_pHYs +# define PNG_WRITE_pHYs_SUPPORTED +# ifndef PNG_pHYs_SUPPORTED +# define PNG_pHYs_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sBIT +# define PNG_WRITE_sBIT_SUPPORTED +# ifndef PNG_sBIT_SUPPORTED +# define PNG_sBIT_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sPLT +# define PNG_WRITE_sPLT_SUPPORTED +# ifndef PNG_sPLT_SUPPORTED +# define PNG_sPLT_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sRGB +# define PNG_WRITE_sRGB_SUPPORTED +# ifndef PNG_sRGB_SUPPORTED +# define PNG_sRGB_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_tEXt +# define PNG_WRITE_tEXt_SUPPORTED +# ifndef PNG_tEXt_SUPPORTED +# define PNG_tEXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_tIME +# define PNG_WRITE_tIME_SUPPORTED +# ifndef PNG_tIME_SUPPORTED +# define PNG_tIME_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_tRNS +# define PNG_WRITE_tRNS_SUPPORTED +# ifndef PNG_tRNS_SUPPORTED +# define PNG_tRNS_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_zTXt +# define PNG_WRITE_zTXt_SUPPORTED +# ifndef PNG_zTXt_SUPPORTED +# define PNG_zTXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_UNKNOWN_CHUNKS +# define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED +# define PNG_UNKNOWN_CHUNKS_SUPPORTED +# endif +# ifndef PNG_NO_HANDLE_AS_UNKNOWN +# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# endif +# endif +#endif +#if defined(PNG_WRITE_iTXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \ + defined(PNG_WRITE_zTXt_SUPPORTED) +# define PNG_WRITE_TEXT_SUPPORTED +# ifndef PNG_TEXT_SUPPORTED +# define PNG_TEXT_SUPPORTED +# endif +#endif + +#endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */ + +/* Turn this off to disable png_read_png() and + * png_write_png() and leave the row_pointers member + * out of the info structure. + */ +#ifndef PNG_NO_INFO_IMAGE +# define PNG_INFO_IMAGE_SUPPORTED +#endif + +/* need the time information for reading tIME chunks */ +#if defined(PNG_tIME_SUPPORTED) +# if !defined(_WIN32_WCE) + /* "time.h" functions are not supported on WindowsCE */ +# include +# endif +#endif + +/* Some typedefs to get us started. These should be safe on most of the + * common platforms. The typedefs should be at least as large as the + * numbers suggest (a png_uint_32 must be at least 32 bits long), but they + * don't have to be exactly that size. Some compilers dislike passing + * unsigned shorts as function parameters, so you may be better off using + * unsigned int for png_uint_16. Likewise, for 64-bit systems, you may + * want to have unsigned int for png_uint_32 instead of unsigned long. + */ + +typedef unsigned long png_uint_32; +typedef long png_int_32; +typedef unsigned short png_uint_16; +typedef short png_int_16; +typedef unsigned char png_byte; + +/* This is usually size_t. It is typedef'ed just in case you need it to + change (I'm not sure if you will or not, so I thought I'd be safe) */ +typedef size_t png_size_t; + +/* The following is needed for medium model support. It cannot be in the + * PNG_INTERNAL section. Needs modification for other compilers besides + * MSC. Model independent support declares all arrays and pointers to be + * large using the far keyword. The zlib version used must also support + * model independent data. As of version zlib 1.0.4, the necessary changes + * have been made in zlib. The USE_FAR_KEYWORD define triggers other + * changes that are needed. (Tim Wegner) + */ + +/* Separate compiler dependencies (problem here is that zlib.h always + defines FAR. (SJT) */ +#ifdef __BORLANDC__ +# if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__) +# define LDATA 1 +# else +# define LDATA 0 +# endif + /* GRR: why is Cygwin in here? Cygwin is not Borland C... */ +# if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__) +# define PNG_MAX_MALLOC_64K +# if (LDATA != 1) +# ifndef FAR +# define FAR __far +# endif +# define USE_FAR_KEYWORD +# endif /* LDATA != 1 */ + /* Possibly useful for moving data out of default segment. + * Uncomment it if you want. Could also define FARDATA as + * const if your compiler supports it. (SJT) +# define FARDATA FAR + */ +# endif /* __WIN32__, __FLAT__, __CYGWIN__ */ +#endif /* __BORLANDC__ */ + + +/* Suggest testing for specific compiler first before testing for + * FAR. The Watcom compiler defines both __MEDIUM__ and M_I86MM, + * making reliance oncertain keywords suspect. (SJT) + */ + +/* MSC Medium model */ +#if defined(FAR) +# if defined(M_I86MM) +# define USE_FAR_KEYWORD +# define FARDATA FAR +# include +# endif +#endif + +/* SJT: default case */ +#ifndef FAR +# define FAR +#endif + +/* At this point FAR is always defined */ +#ifndef FARDATA +# define FARDATA +#endif + +/* Typedef for floating-point numbers that are converted + to fixed-point with a multiple of 100,000, e.g., int_gamma */ +typedef png_int_32 png_fixed_point; + +/* Add typedefs for pointers */ +typedef void FAR * png_voidp; +typedef png_byte FAR * png_bytep; +typedef png_uint_32 FAR * png_uint_32p; +typedef png_int_32 FAR * png_int_32p; +typedef png_uint_16 FAR * png_uint_16p; +typedef png_int_16 FAR * png_int_16p; +typedef PNG_CONST char FAR * png_const_charp; +typedef char FAR * png_charp; +typedef png_fixed_point FAR * png_fixed_point_p; + +#ifndef PNG_NO_STDIO +#if defined(_WIN32_WCE) +typedef HANDLE png_FILE_p; +#else +typedef FILE * png_FILE_p; +#endif +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double FAR * png_doublep; +#endif + +/* Pointers to pointers; i.e. arrays */ +typedef png_byte FAR * FAR * png_bytepp; +typedef png_uint_32 FAR * FAR * png_uint_32pp; +typedef png_int_32 FAR * FAR * png_int_32pp; +typedef png_uint_16 FAR * FAR * png_uint_16pp; +typedef png_int_16 FAR * FAR * png_int_16pp; +typedef PNG_CONST char FAR * FAR * png_const_charpp; +typedef char FAR * FAR * png_charpp; +typedef png_fixed_point FAR * FAR * png_fixed_point_pp; +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double FAR * FAR * png_doublepp; +#endif + +/* Pointers to pointers to pointers; i.e., pointer to array */ +typedef char FAR * FAR * FAR * png_charppp; + +/* libpng typedefs for types in zlib. If zlib changes + * or another compression library is used, then change these. + * Eliminates need to change all the source files. + */ +typedef charf * png_zcharp; +typedef charf * FAR * png_zcharpp; +typedef z_stream FAR * png_zstreamp; + +/* + * Define PNG_BUILD_DLL if the module being built is a Windows + * LIBPNG DLL. + * + * Define PNG_USE_DLL if you want to *link* to the Windows LIBPNG DLL. + * It is equivalent to Microsoft predefined macro _DLL that is + * automatically defined when you compile using the share + * version of the CRT (C Run-Time library) + * + * The cygwin mods make this behavior a little different: + * Define PNG_BUILD_DLL if you are building a dll for use with cygwin + * Define PNG_STATIC if you are building a static library for use with cygwin, + * -or- if you are building an application that you want to link to the + * static library. + * PNG_USE_DLL is defined by default (no user action needed) unless one of + * the other flags is defined. + */ + +#if !defined(PNG_DLL) && (defined(PNG_BUILD_DLL) || defined(PNG_USE_DLL)) +# define PNG_DLL +#endif +/* If CYGWIN, then disallow GLOBAL ARRAYS unless building a static lib. + * When building a static lib, default to no GLOBAL ARRAYS, but allow + * command-line override + */ +#if defined(__CYGWIN__) +# if !defined(PNG_STATIC) +# if defined(PNG_USE_GLOBAL_ARRAYS) +# undef PNG_USE_GLOBAL_ARRAYS +# endif +# if !defined(PNG_USE_LOCAL_ARRAYS) +# define PNG_USE_LOCAL_ARRAYS +# endif +# else +# if defined(PNG_USE_LOCAL_ARRAYS) || defined(PNG_NO_GLOBAL_ARRAYS) +# if defined(PNG_USE_GLOBAL_ARRAYS) +# undef PNG_USE_GLOBAL_ARRAYS +# endif +# endif +# endif +# if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS) +# define PNG_USE_LOCAL_ARRAYS +# endif +#endif + +/* Do not use global arrays (helps with building DLL's) + * They are no longer used in libpng itself, since version 1.0.5c, + * but might be required for some pre-1.0.5c applications. + */ +#if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS) +# if defined(PNG_NO_GLOBAL_ARRAYS) || (defined(__GNUC__) && defined(PNG_DLL)) +# define PNG_USE_LOCAL_ARRAYS +# else +# define PNG_USE_GLOBAL_ARRAYS +# endif +#endif + +#if defined(__CYGWIN__) +# undef PNGAPI +# define PNGAPI __cdecl +# undef PNG_IMPEXP +# define PNG_IMPEXP +#endif + +/* If you define PNGAPI, e.g., with compiler option "-DPNGAPI=__stdcall", + * you may get warnings regarding the linkage of png_zalloc and png_zfree. + * Don't ignore those warnings; you must also reset the default calling + * convention in your compiler to match your PNGAPI, and you must build + * zlib and your applications the same way you build libpng. + */ + +#ifndef PNGAPI + +#if defined(__MINGW32__) && !defined(PNG_MODULEDEF) +# ifndef PNG_NO_MODULEDEF +# define PNG_NO_MODULEDEF +# endif +#endif + +#if !defined(PNG_IMPEXP) && defined(PNG_BUILD_DLL) && !defined(PNG_NO_MODULEDEF) +# define PNG_IMPEXP +#endif + +#if defined(PNG_DLL) || defined(_DLL) || defined(__DLL__ ) || \ + (( defined(_Windows) || defined(_WINDOWS) || \ + defined(WIN32) || defined(_WIN32) || defined(__WIN32__) )) + +# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800)) +# define PNGAPI __cdecl +# else +# define PNGAPI _cdecl +# endif + +# if !defined(PNG_IMPEXP) && (!defined(PNG_DLL) || \ + 0 /* WINCOMPILER_WITH_NO_SUPPORT_FOR_DECLIMPEXP */) +# define PNG_IMPEXP +# endif + +# if !defined(PNG_IMPEXP) + +# define PNG_EXPORT_TYPE1(type,symbol) PNG_IMPEXP type PNGAPI symbol +# define PNG_EXPORT_TYPE2(type,symbol) type PNG_IMPEXP PNGAPI symbol + + /* Borland/Microsoft */ +# if defined(_MSC_VER) || defined(__BORLANDC__) +# if (_MSC_VER >= 800) || (__BORLANDC__ >= 0x500) +# define PNG_EXPORT PNG_EXPORT_TYPE1 +# else +# define PNG_EXPORT PNG_EXPORT_TYPE2 +# if defined(PNG_BUILD_DLL) +# define PNG_IMPEXP __export +# else +# define PNG_IMPEXP /*__import */ /* doesn't exist AFAIK in + VC++ */ +# endif /* Exists in Borland C++ for + C++ classes (== huge) */ +# endif +# endif + +# if !defined(PNG_IMPEXP) +# if defined(PNG_BUILD_DLL) +# define PNG_IMPEXP __declspec(dllexport) +# else +# define PNG_IMPEXP __declspec(dllimport) +# endif +# endif +# endif /* PNG_IMPEXP */ +#else /* !(DLL || non-cygwin WINDOWS) */ +# if (defined(__IBMC__) || defined(IBMCPP__)) && defined(__OS2__) +# define PNGAPI _System +# define PNG_IMPEXP +# else +# if 0 /* ... other platforms, with other meanings */ +# else +# define PNGAPI +# define PNG_IMPEXP +# endif +# endif +#endif +#endif + +#ifndef PNGAPI +# define PNGAPI +#endif +#ifndef PNG_IMPEXP +# define PNG_IMPEXP +#endif + +#ifndef PNG_EXPORT +# define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol +#endif + +#ifdef PNG_USE_GLOBAL_ARRAYS +# ifndef PNG_EXPORT_VAR +# define PNG_EXPORT_VAR(type) extern PNG_IMPEXP type +# endif +#endif + +/* User may want to use these so they are not in PNG_INTERNAL. Any library + * functions that are passed far data must be model independent. + */ + +#ifndef PNG_ABORT +# define PNG_ABORT() abort() +#endif + +#ifdef PNG_SETJMP_SUPPORTED +# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) +#else +# define png_jmpbuf(png_ptr) \ + (LIBPNG_WAS_COMPILED_WITH__PNG_SETJMP_NOT_SUPPORTED) +#endif + +#if defined(USE_FAR_KEYWORD) /* memory model independent fns */ +/* use this to make far-to-near assignments */ +# define CHECK 1 +# define NOCHECK 0 +# define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK)) +# define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK)) +# define png_strcpy _fstrcpy +# define png_strlen _fstrlen +# define png_memcmp _fmemcmp /* SJT: added */ +# define png_memcpy _fmemcpy +# define png_memset _fmemset +#else /* use the usual functions */ +# define CVT_PTR(ptr) (ptr) +# define CVT_PTR_NOCHECK(ptr) (ptr) +# define png_strcpy strcpy +# define png_strlen strlen +# define png_memcmp memcmp /* SJT: added */ +# define png_memcpy memcpy +# define png_memset memset +#endif +/* End of memory model independent support */ + +/* Just a little check that someone hasn't tried to define something + * contradictory. + */ +#if (PNG_ZBUF_SIZE > 65536) && defined(PNG_MAX_MALLOC_64K) +# undef PNG_ZBUF_SIZE +# define PNG_ZBUF_SIZE 65536 +#endif + +#ifdef PNG_READ_SUPPORTED +/* Prior to libpng-1.0.9, this block was in pngasmrd.h */ +#if defined(PNG_INTERNAL) + +/* These are the default thresholds before the MMX code kicks in; if either + * rowbytes or bitdepth is below the threshold, plain C code is used. These + * can be overridden at runtime via the png_set_mmx_thresholds() call in + * libpng 1.2.0 and later. The values below were chosen by Intel. + */ + +#ifndef PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT +# define PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT 128 /* >= */ +#endif +#ifndef PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT +# define PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT 9 /* >= */ +#endif + +/* Set this in the makefile for VC++ on Pentium, not here. */ +/* Platform must be Pentium. Makefile must assemble and load pngvcrd.c . + * MMX will be detected at run time and used if present. + */ +#ifdef PNG_USE_PNGVCRD +# define PNG_HAVE_ASSEMBLER_COMBINE_ROW +# define PNG_HAVE_ASSEMBLER_READ_INTERLACE +# define PNG_HAVE_ASSEMBLER_READ_FILTER_ROW +#endif + +/* Set this in the makefile for gcc/as on Pentium, not here. */ +/* Platform must be Pentium. Makefile must assemble and load pnggccrd.c . + * MMX will be detected at run time and used if present. + */ +#ifdef PNG_USE_PNGGCCRD +# define PNG_HAVE_ASSEMBLER_COMBINE_ROW +# define PNG_HAVE_ASSEMBLER_READ_INTERLACE +# define PNG_HAVE_ASSEMBLER_READ_FILTER_ROW +#endif +/* - see pnggccrd.c for info about what is currently enabled */ + +#endif /* PNG_INTERNAL */ +#endif /* PNG_READ_SUPPORTED */ + +#endif /* PNGCONF_H */ + diff --git a/winclude/tiff.h b/winclude/tiff.h new file mode 100755 index 000000000..6330795b6 --- /dev/null +++ b/winclude/tiff.h @@ -0,0 +1,647 @@ +/* $Id: tiff.h,v 1.42 2005/12/23 15:10:45 dron Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _TIFF_ +#define _TIFF_ + +#include "tiffconf.h" + +/* + * Tag Image File Format (TIFF) + * + * Based on Rev 6.0 from: + * Developer's Desk + * Aldus Corporation + * 411 First Ave. South + * Suite 200 + * Seattle, WA 98104 + * 206-622-5500 + * + * (http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf) + * + * For Big TIFF design notes see the following link + * http://gdal.maptools.org/twiki/bin/view/libtiff/BigTIFFDesign + */ +#define TIFF_VERSION 42 +#define TIFF_BIGTIFF_VERSION 43 + +#define TIFF_BIGENDIAN 0x4d4d +#define TIFF_LITTLEENDIAN 0x4949 +#define MDI_LITTLEENDIAN 0x5045 +#define MDI_BIGENDIAN 0x4550 +/* + * Intrinsic data types required by the file format: + * + * 8-bit quantities int8/uint8 + * 16-bit quantities int16/uint16 + * 32-bit quantities int32/uint32 + * strings unsigned char* + */ + +#ifndef HAVE_INT8 +typedef signed char int8; /* NB: non-ANSI compilers may not grok */ +#endif +typedef unsigned char uint8; +#ifndef HAVE_INT16 +typedef short int16; +#endif +typedef unsigned short uint16; /* sizeof (uint16) must == 2 */ +#if SIZEOF_INT == 4 +#ifndef HAVE_INT32 +typedef int int32; +#endif +typedef unsigned int uint32; /* sizeof (uint32) must == 4 */ +#elif SIZEOF_LONG == 4 +#ifndef HAVE_INT32 +typedef long int32; +#endif +typedef unsigned long uint32; /* sizeof (uint32) must == 4 */ +#endif + +/* For TIFFReassignTagToIgnore */ +enum TIFFIgnoreSense /* IGNORE tag table */ +{ + TIS_STORE, + TIS_EXTRACT, + TIS_EMPTY +}; + +/* + * TIFF header. + */ +typedef struct { + uint16 tiff_magic; /* magic number (defines byte order) */ +#define TIFF_MAGIC_SIZE 2 + uint16 tiff_version; /* TIFF version number */ +#define TIFF_VERSION_SIZE 2 + uint32 tiff_diroff; /* byte offset to first directory */ +#define TIFF_DIROFFSET_SIZE 4 +} TIFFHeader; + + +/* + * TIFF Image File Directories are comprised of a table of field + * descriptors of the form shown below. The table is sorted in + * ascending order by tag. The values associated with each entry are + * disjoint and may appear anywhere in the file (so long as they are + * placed on a word boundary). + * + * If the value is 4 bytes or less, then it is placed in the offset + * field to save space. If the value is less than 4 bytes, it is + * left-justified in the offset field. + */ +typedef struct { + uint16 tdir_tag; /* see below */ + uint16 tdir_type; /* data type; see below */ + uint32 tdir_count; /* number of items; length in spec */ + uint32 tdir_offset; /* byte offset to field data */ +} TIFFDirEntry; + +/* + * NB: In the comments below, + * - items marked with a + are obsoleted by revision 5.0, + * - items marked with a ! are introduced in revision 6.0. + * - items marked with a % are introduced post revision 6.0. + * - items marked with a $ are obsoleted by revision 6.0. + * - items marked with a & are introduced by Adobe DNG specification. + */ + +/* + * Tag data type information. + * + * Note: RATIONALs are the ratio of two 32-bit integer values. + */ +typedef enum { + TIFF_NOTYPE = 0, /* placeholder */ + TIFF_BYTE = 1, /* 8-bit unsigned integer */ + TIFF_ASCII = 2, /* 8-bit bytes w/ last byte null */ + TIFF_SHORT = 3, /* 16-bit unsigned integer */ + TIFF_LONG = 4, /* 32-bit unsigned integer */ + TIFF_RATIONAL = 5, /* 64-bit unsigned fraction */ + TIFF_SBYTE = 6, /* !8-bit signed integer */ + TIFF_UNDEFINED = 7, /* !8-bit untyped data */ + TIFF_SSHORT = 8, /* !16-bit signed integer */ + TIFF_SLONG = 9, /* !32-bit signed integer */ + TIFF_SRATIONAL = 10, /* !64-bit signed fraction */ + TIFF_FLOAT = 11, /* !32-bit IEEE floating point */ + TIFF_DOUBLE = 12, /* !64-bit IEEE floating point */ + TIFF_IFD = 13 /* %32-bit unsigned integer (offset) */ +} TIFFDataType; + +/* + * TIFF Tag Definitions. + */ +#define TIFFTAG_SUBFILETYPE 254 /* subfile data descriptor */ +#define FILETYPE_REDUCEDIMAGE 0x1 /* reduced resolution version */ +#define FILETYPE_PAGE 0x2 /* one page of many */ +#define FILETYPE_MASK 0x4 /* transparency mask */ +#define TIFFTAG_OSUBFILETYPE 255 /* +kind of data in subfile */ +#define OFILETYPE_IMAGE 1 /* full resolution image data */ +#define OFILETYPE_REDUCEDIMAGE 2 /* reduced size image data */ +#define OFILETYPE_PAGE 3 /* one page of many */ +#define TIFFTAG_IMAGEWIDTH 256 /* image width in pixels */ +#define TIFFTAG_IMAGELENGTH 257 /* image height in pixels */ +#define TIFFTAG_BITSPERSAMPLE 258 /* bits per channel (sample) */ +#define TIFFTAG_COMPRESSION 259 /* data compression technique */ +#define COMPRESSION_NONE 1 /* dump mode */ +#define COMPRESSION_CCITTRLE 2 /* CCITT modified Huffman RLE */ +#define COMPRESSION_CCITTFAX3 3 /* CCITT Group 3 fax encoding */ +#define COMPRESSION_CCITT_T4 3 /* CCITT T.4 (TIFF 6 name) */ +#define COMPRESSION_CCITTFAX4 4 /* CCITT Group 4 fax encoding */ +#define COMPRESSION_CCITT_T6 4 /* CCITT T.6 (TIFF 6 name) */ +#define COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */ +#define COMPRESSION_OJPEG 6 /* !6.0 JPEG */ +#define COMPRESSION_JPEG 7 /* %JPEG DCT compression */ +#define COMPRESSION_NEXT 32766 /* NeXT 2-bit RLE */ +#define COMPRESSION_CCITTRLEW 32771 /* #1 w/ word alignment */ +#define COMPRESSION_PACKBITS 32773 /* Macintosh RLE */ +#define COMPRESSION_THUNDERSCAN 32809 /* ThunderScan RLE */ +/* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT */ +#define COMPRESSION_DCS 32947 /* Kodak DCS encoding */ +#define COMPRESSION_JBIG 34661 /* ISO JBIG */ +#define COMPRESSION_SGILOG 34676 /* SGI Log Luminance RLE */ +#define COMPRESSION_SGILOG24 34677 /* SGI Log 24-bit packed */ +#define COMPRESSION_JP2000 34712 /* Leadtools JPEG2000 */ +#define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */ +#define PHOTOMETRIC_MINISWHITE 0 /* min value is white */ +#define PHOTOMETRIC_MINISBLACK 1 /* min value is black */ +#define PHOTOMETRIC_RGB 2 /* RGB color model */ +#define PHOTOMETRIC_PALETTE 3 /* color map indexed */ +#define PHOTOMETRIC_MASK 4 /* $holdout mask */ +#define PHOTOMETRIC_SEPARATED 5 /* !color separations */ +#define PHOTOMETRIC_YCBCR 6 /* !CCIR 601 */ +#define PHOTOMETRIC_CIELAB 8 /* !1976 CIE L*a*b* */ +#define PHOTOMETRIC_ICCLAB 9 /* ICC L*a*b* [Adobe TIFF Technote 4] */ +#define PHOTOMETRIC_ITULAB 10 /* ITU L*a*b* */ +#define PHOTOMETRIC_LOGL 32844 /* CIE Log2(L) */ +#define PHOTOMETRIC_LOGLUV 32845 /* CIE Log2(L) (u',v') */ +#define TIFFTAG_THRESHHOLDING 263 /* +thresholding used on data */ +#define THRESHHOLD_BILEVEL 1 /* b&w art scan */ +#define THRESHHOLD_HALFTONE 2 /* or dithered scan */ +#define THRESHHOLD_ERRORDIFFUSE 3 /* usually floyd-steinberg */ +#define TIFFTAG_CELLWIDTH 264 /* +dithering matrix width */ +#define TIFFTAG_CELLLENGTH 265 /* +dithering matrix height */ +#define TIFFTAG_FILLORDER 266 /* data order within a byte */ +#define FILLORDER_MSB2LSB 1 /* most significant -> least */ +#define FILLORDER_LSB2MSB 2 /* least significant -> most */ +#define TIFFTAG_DOCUMENTNAME 269 /* name of doc. image is from */ +#define TIFFTAG_IMAGEDESCRIPTION 270 /* info about image */ +#define TIFFTAG_MAKE 271 /* scanner manufacturer name */ +#define TIFFTAG_MODEL 272 /* scanner model name/number */ +#define TIFFTAG_STRIPOFFSETS 273 /* offsets to data strips */ +#define TIFFTAG_ORIENTATION 274 /* +image orientation */ +#define ORIENTATION_TOPLEFT 1 /* row 0 top, col 0 lhs */ +#define ORIENTATION_TOPRIGHT 2 /* row 0 top, col 0 rhs */ +#define ORIENTATION_BOTRIGHT 3 /* row 0 bottom, col 0 rhs */ +#define ORIENTATION_BOTLEFT 4 /* row 0 bottom, col 0 lhs */ +#define ORIENTATION_LEFTTOP 5 /* row 0 lhs, col 0 top */ +#define ORIENTATION_RIGHTTOP 6 /* row 0 rhs, col 0 top */ +#define ORIENTATION_RIGHTBOT 7 /* row 0 rhs, col 0 bottom */ +#define ORIENTATION_LEFTBOT 8 /* row 0 lhs, col 0 bottom */ +#define TIFFTAG_SAMPLESPERPIXEL 277 /* samples per pixel */ +#define TIFFTAG_ROWSPERSTRIP 278 /* rows per strip of data */ +#define TIFFTAG_STRIPBYTECOUNTS 279 /* bytes counts for strips */ +#define TIFFTAG_MINSAMPLEVALUE 280 /* +minimum sample value */ +#define TIFFTAG_MAXSAMPLEVALUE 281 /* +maximum sample value */ +#define TIFFTAG_XRESOLUTION 282 /* pixels/resolution in x */ +#define TIFFTAG_YRESOLUTION 283 /* pixels/resolution in y */ +#define TIFFTAG_PLANARCONFIG 284 /* storage organization */ +#define PLANARCONFIG_CONTIG 1 /* single image plane */ +#define PLANARCONFIG_SEPARATE 2 /* separate planes of data */ +#define TIFFTAG_PAGENAME 285 /* page name image is from */ +#define TIFFTAG_XPOSITION 286 /* x page offset of image lhs */ +#define TIFFTAG_YPOSITION 287 /* y page offset of image lhs */ +#define TIFFTAG_FREEOFFSETS 288 /* +byte offset to free block */ +#define TIFFTAG_FREEBYTECOUNTS 289 /* +sizes of free blocks */ +#define TIFFTAG_GRAYRESPONSEUNIT 290 /* $gray scale curve accuracy */ +#define GRAYRESPONSEUNIT_10S 1 /* tenths of a unit */ +#define GRAYRESPONSEUNIT_100S 2 /* hundredths of a unit */ +#define GRAYRESPONSEUNIT_1000S 3 /* thousandths of a unit */ +#define GRAYRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ +#define GRAYRESPONSEUNIT_100000S 5 /* hundred-thousandths */ +#define TIFFTAG_GRAYRESPONSECURVE 291 /* $gray scale response curve */ +#define TIFFTAG_GROUP3OPTIONS 292 /* 32 flag bits */ +#define TIFFTAG_T4OPTIONS 292 /* TIFF 6.0 proper name alias */ +#define GROUP3OPT_2DENCODING 0x1 /* 2-dimensional coding */ +#define GROUP3OPT_UNCOMPRESSED 0x2 /* data not compressed */ +#define GROUP3OPT_FILLBITS 0x4 /* fill to byte boundary */ +#define TIFFTAG_GROUP4OPTIONS 293 /* 32 flag bits */ +#define TIFFTAG_T6OPTIONS 293 /* TIFF 6.0 proper name */ +#define GROUP4OPT_UNCOMPRESSED 0x2 /* data not compressed */ +#define TIFFTAG_RESOLUTIONUNIT 296 /* units of resolutions */ +#define RESUNIT_NONE 1 /* no meaningful units */ +#define RESUNIT_INCH 2 /* english */ +#define RESUNIT_CENTIMETER 3 /* metric */ +#define TIFFTAG_PAGENUMBER 297 /* page numbers of multi-page */ +#define TIFFTAG_COLORRESPONSEUNIT 300 /* $color curve accuracy */ +#define COLORRESPONSEUNIT_10S 1 /* tenths of a unit */ +#define COLORRESPONSEUNIT_100S 2 /* hundredths of a unit */ +#define COLORRESPONSEUNIT_1000S 3 /* thousandths of a unit */ +#define COLORRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ +#define COLORRESPONSEUNIT_100000S 5 /* hundred-thousandths */ +#define TIFFTAG_TRANSFERFUNCTION 301 /* !colorimetry info */ +#define TIFFTAG_SOFTWARE 305 /* name & release */ +#define TIFFTAG_DATETIME 306 /* creation date and time */ +#define TIFFTAG_ARTIST 315 /* creator of image */ +#define TIFFTAG_HOSTCOMPUTER 316 /* machine where created */ +#define TIFFTAG_PREDICTOR 317 /* prediction scheme w/ LZW */ +#define PREDICTOR_NONE 1 /* no prediction scheme used */ +#define PREDICTOR_HORIZONTAL 2 /* horizontal differencing */ +#define PREDICTOR_FLOATINGPOINT 3 /* floating point predictor */ +#define TIFFTAG_WHITEPOINT 318 /* image white point */ +#define TIFFTAG_PRIMARYCHROMATICITIES 319 /* !primary chromaticities */ +#define TIFFTAG_COLORMAP 320 /* RGB map for pallette image */ +#define TIFFTAG_HALFTONEHINTS 321 /* !highlight+shadow info */ +#define TIFFTAG_TILEWIDTH 322 /* !tile width in pixels */ +#define TIFFTAG_TILELENGTH 323 /* !tile height in pixels */ +#define TIFFTAG_TILEOFFSETS 324 /* !offsets to data tiles */ +#define TIFFTAG_TILEBYTECOUNTS 325 /* !byte counts for tiles */ +#define TIFFTAG_BADFAXLINES 326 /* lines w/ wrong pixel count */ +#define TIFFTAG_CLEANFAXDATA 327 /* regenerated line info */ +#define CLEANFAXDATA_CLEAN 0 /* no errors detected */ +#define CLEANFAXDATA_REGENERATED 1 /* receiver regenerated lines */ +#define CLEANFAXDATA_UNCLEAN 2 /* uncorrected errors exist */ +#define TIFFTAG_CONSECUTIVEBADFAXLINES 328 /* max consecutive bad lines */ +#define TIFFTAG_SUBIFD 330 /* subimage descriptors */ +#define TIFFTAG_INKSET 332 /* !inks in separated image */ +#define INKSET_CMYK 1 /* !cyan-magenta-yellow-black color */ +#define INKSET_MULTIINK 2 /* !multi-ink or hi-fi color */ +#define TIFFTAG_INKNAMES 333 /* !ascii names of inks */ +#define TIFFTAG_NUMBEROFINKS 334 /* !number of inks */ +#define TIFFTAG_DOTRANGE 336 /* !0% and 100% dot codes */ +#define TIFFTAG_TARGETPRINTER 337 /* !separation target */ +#define TIFFTAG_EXTRASAMPLES 338 /* !info about extra samples */ +#define EXTRASAMPLE_UNSPECIFIED 0 /* !unspecified data */ +#define EXTRASAMPLE_ASSOCALPHA 1 /* !associated alpha data */ +#define EXTRASAMPLE_UNASSALPHA 2 /* !unassociated alpha data */ +#define TIFFTAG_SAMPLEFORMAT 339 /* !data sample format */ +#define SAMPLEFORMAT_UINT 1 /* !unsigned integer data */ +#define SAMPLEFORMAT_INT 2 /* !signed integer data */ +#define SAMPLEFORMAT_IEEEFP 3 /* !IEEE floating point data */ +#define SAMPLEFORMAT_VOID 4 /* !untyped data */ +#define SAMPLEFORMAT_COMPLEXINT 5 /* !complex signed int */ +#define SAMPLEFORMAT_COMPLEXIEEEFP 6 /* !complex ieee floating */ +#define TIFFTAG_SMINSAMPLEVALUE 340 /* !variable MinSampleValue */ +#define TIFFTAG_SMAXSAMPLEVALUE 341 /* !variable MaxSampleValue */ +#define TIFFTAG_CLIPPATH 343 /* %ClipPath + [Adobe TIFF technote 2] */ +#define TIFFTAG_XCLIPPATHUNITS 344 /* %XClipPathUnits + [Adobe TIFF technote 2] */ +#define TIFFTAG_YCLIPPATHUNITS 345 /* %YClipPathUnits + [Adobe TIFF technote 2] */ +#define TIFFTAG_INDEXED 346 /* %Indexed + [Adobe TIFF Technote 3] */ +#define TIFFTAG_JPEGTABLES 347 /* %JPEG table stream */ +#define TIFFTAG_OPIPROXY 351 /* %OPI Proxy [Adobe TIFF technote] */ +/* + * Tags 512-521 are obsoleted by Technical Note #2 which specifies a + * revised JPEG-in-TIFF scheme. + */ +#define TIFFTAG_JPEGPROC 512 /* !JPEG processing algorithm */ +#define JPEGPROC_BASELINE 1 /* !baseline sequential */ +#define JPEGPROC_LOSSLESS 14 /* !Huffman coded lossless */ +#define TIFFTAG_JPEGIFOFFSET 513 /* !pointer to SOI marker */ +#define TIFFTAG_JPEGIFBYTECOUNT 514 /* !JFIF stream length */ +#define TIFFTAG_JPEGRESTARTINTERVAL 515 /* !restart interval length */ +#define TIFFTAG_JPEGLOSSLESSPREDICTORS 517 /* !lossless proc predictor */ +#define TIFFTAG_JPEGPOINTTRANSFORM 518 /* !lossless point transform */ +#define TIFFTAG_JPEGQTABLES 519 /* !Q matrice offsets */ +#define TIFFTAG_JPEGDCTABLES 520 /* !DCT table offsets */ +#define TIFFTAG_JPEGACTABLES 521 /* !AC coefficient offsets */ +#define TIFFTAG_YCBCRCOEFFICIENTS 529 /* !RGB -> YCbCr transform */ +#define TIFFTAG_YCBCRSUBSAMPLING 530 /* !YCbCr subsampling factors */ +#define TIFFTAG_YCBCRPOSITIONING 531 /* !subsample positioning */ +#define YCBCRPOSITION_CENTERED 1 /* !as in PostScript Level 2 */ +#define YCBCRPOSITION_COSITED 2 /* !as in CCIR 601-1 */ +#define TIFFTAG_REFERENCEBLACKWHITE 532 /* !colorimetry info */ +#define TIFFTAG_XMLPACKET 700 /* %XML packet + [Adobe XMP Specification, + January 2004 */ +#define TIFFTAG_OPIIMAGEID 32781 /* %OPI ImageID + [Adobe TIFF technote] */ +/* tags 32952-32956 are private tags registered to Island Graphics */ +#define TIFFTAG_REFPTS 32953 /* image reference points */ +#define TIFFTAG_REGIONTACKPOINT 32954 /* region-xform tack point */ +#define TIFFTAG_REGIONWARPCORNERS 32955 /* warp quadrilateral */ +#define TIFFTAG_REGIONAFFINE 32956 /* affine transformation mat */ +/* tags 32995-32999 are private tags registered to SGI */ +#define TIFFTAG_MATTEING 32995 /* $use ExtraSamples */ +#define TIFFTAG_DATATYPE 32996 /* $use SampleFormat */ +#define TIFFTAG_IMAGEDEPTH 32997 /* z depth of image */ +#define TIFFTAG_TILEDEPTH 32998 /* z depth/data tile */ +/* tags 33300-33309 are private tags registered to Pixar */ +/* + * TIFFTAG_PIXAR_IMAGEFULLWIDTH and TIFFTAG_PIXAR_IMAGEFULLLENGTH + * are set when an image has been cropped out of a larger image. + * They reflect the size of the original uncropped image. + * The TIFFTAG_XPOSITION and TIFFTAG_YPOSITION can be used + * to determine the position of the smaller image in the larger one. + */ +#define TIFFTAG_PIXAR_IMAGEFULLWIDTH 33300 /* full image size in x */ +#define TIFFTAG_PIXAR_IMAGEFULLLENGTH 33301 /* full image size in y */ + /* Tags 33302-33306 are used to identify special image modes and data + * used by Pixar's texture formats. + */ +#define TIFFTAG_PIXAR_TEXTUREFORMAT 33302 /* texture map format */ +#define TIFFTAG_PIXAR_WRAPMODES 33303 /* s & t wrap modes */ +#define TIFFTAG_PIXAR_FOVCOT 33304 /* cotan(fov) for env. maps */ +#define TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN 33305 +#define TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA 33306 +/* tag 33405 is a private tag registered to Eastman Kodak */ +#define TIFFTAG_WRITERSERIALNUMBER 33405 /* device serial number */ +/* tag 33432 is listed in the 6.0 spec w/ unknown ownership */ +#define TIFFTAG_COPYRIGHT 33432 /* copyright string */ +/* IPTC TAG from RichTIFF specifications */ +#define TIFFTAG_RICHTIFFIPTC 33723 +/* 34016-34029 are reserved for ANSI IT8 TIFF/IT */ +#define TIFFTAG_STONITS 37439 /* Sample value to Nits */ +/* tag 34929 is a private tag registered to FedEx */ +#define TIFFTAG_FEDEX_EDR 34929 /* unknown use */ +#define TIFFTAG_INTEROPERABILITYIFD 40965 /* Pointer to Interoperability private directory */ +/* Adobe Digital Negative (DNG) format tags */ +#define TIFFTAG_DNGVERSION 50706 /* &DNG version number */ +#define TIFFTAG_DNGBACKWARDVERSION 50707 /* &DNG compatibility version */ +#define TIFFTAG_UNIQUECAMERAMODEL 50708 /* &name for the camera model */ +#define TIFFTAG_LOCALIZEDCAMERAMODEL 50709 /* &localized camera model + name */ +#define TIFFTAG_CFAPLANECOLOR 50710 /* &CFAPattern->LinearRaw space + mapping */ +#define TIFFTAG_CFALAYOUT 50711 /* &spatial layout of the CFA */ +#define TIFFTAG_LINEARIZATIONTABLE 50712 /* &lookup table description */ +#define TIFFTAG_BLACKLEVELREPEATDIM 50713 /* &repeat pattern size for + the BlackLevel tag */ +#define TIFFTAG_BLACKLEVEL 50714 /* &zero light encoding level */ +#define TIFFTAG_BLACKLEVELDELTAH 50715 /* &zero light encoding level + differences (columns) */ +#define TIFFTAG_BLACKLEVELDELTAV 50716 /* &zero light encoding level + differences (rows) */ +#define TIFFTAG_WHITELEVEL 50717 /* &fully saturated encoding + level */ +#define TIFFTAG_DEFAULTSCALE 50718 /* &default scale factors */ +#define TIFFTAG_DEFAULTCROPORIGIN 50719 /* &origin of the final image + area */ +#define TIFFTAG_DEFAULTCROPSIZE 50720 /* &size of the final image + area */ +#define TIFFTAG_COLORMATRIX1 50721 /* &XYZ->reference color space + transformation matrix 1 */ +#define TIFFTAG_COLORMATRIX2 50722 /* &XYZ->reference color space + transformation matrix 2 */ +#define TIFFTAG_CAMERACALIBRATION1 50723 /* &calibration matrix 1 */ +#define TIFFTAG_CAMERACALIBRATION2 50724 /* &calibration matrix 2 */ +#define TIFFTAG_REDUCTIONMATRIX1 50725 /* &dimensionality reduction + matrix 1 */ +#define TIFFTAG_REDUCTIONMATRIX2 50726 /* &dimensionality reduction + matrix 2 */ +#define TIFFTAG_ANALOGBALANCE 50727 /* &gain applied the stored raw + values*/ +#define TIFFTAG_ASSHOTNEUTRAL 50728 /* &selected white balance in + linear reference space */ +#define TIFFTAG_ASSHOTWHITEXY 50729 /* &selected white balance in + x-y chromaticity + coordinates */ +#define TIFFTAG_BASELINEEXPOSURE 50730 /* &how much to move the zero + point */ +#define TIFFTAG_BASELINENOISE 50731 /* &relative noise level */ +#define TIFFTAG_BASELINESHARPNESS 50732 /* &relative amount of + sharpening */ +#define TIFFTAG_BAYERGREENSPLIT 50733 /* &how closely the values of + the green pixels in the + blue/green rows track the + values of the green pixels + in the red/green rows */ +#define TIFFTAG_LINEARRESPONSELIMIT 50734 /* &non-linear encoding range */ +#define TIFFTAG_CAMERASERIALNUMBER 50735 /* &camera's serial number */ +#define TIFFTAG_LENSINFO 50736 /* info about the lens */ +#define TIFFTAG_CHROMABLURRADIUS 50737 /* &chroma blur radius */ +#define TIFFTAG_ANTIALIASSTRENGTH 50738 /* &relative strength of the + camera's anti-alias filter */ +#define TIFFTAG_SHADOWSCALE 50739 /* &used by Adobe Camera Raw */ +#define TIFFTAG_DNGPRIVATEDATA 50740 /* &manufacturer's private data */ +#define TIFFTAG_MAKERNOTESAFETY 50741 /* &whether the EXIF MakerNote + tag is safe to preserve + along with the rest of the + EXIF data */ +#define TIFFTAG_CALIBRATIONILLUMINANT1 50778 /* &illuminant 1 */ +#define TIFFTAG_CALIBRATIONILLUMINANT2 50779 /* &illuminant 2 */ +#define TIFFTAG_BESTQUALITYSCALE 50780 /* &best quality multiplier */ +#define TIFFTAG_RAWDATAUNIQUEID 50781 /* &unique identifier for + the raw image data */ +#define TIFFTAG_ORIGINALRAWFILENAME 50827 /* &file name of the original + raw file */ +#define TIFFTAG_ORIGINALRAWFILEDATA 50828 /* &contents of the original + raw file */ +#define TIFFTAG_ACTIVEAREA 50829 /* &active (non-masked) pixels + of the sensor */ +#define TIFFTAG_MASKEDAREAS 50830 /* &list of coordinates + of fully masked pixels */ +#define TIFFTAG_ASSHOTICCPROFILE 50831 /* &these two tags used to */ +#define TIFFTAG_ASSHOTPREPROFILEMATRIX 50832 /* map cameras's color space + into ICC profile space */ +#define TIFFTAG_CURRENTICCPROFILE 50833 /* & */ +#define TIFFTAG_CURRENTPREPROFILEMATRIX 50834 /* & */ +/* tag 65535 is an undefined tag used by Eastman Kodak */ +#define TIFFTAG_DCSHUESHIFTVALUES 65535 /* hue shift correction data */ + +/* + * The following are ``pseudo tags'' that can be used to control + * codec-specific functionality. These tags are not written to file. + * Note that these values start at 0xffff+1 so that they'll never + * collide with Aldus-assigned tags. + * + * If you want your private pseudo tags ``registered'' (i.e. added to + * this file), please post a bug report via the tracking system at + * http://www.remotesensing.org/libtiff/bugs.html with the appropriate + * C definitions to add. + */ +#define TIFFTAG_FAXMODE 65536 /* Group 3/4 format control */ +#define FAXMODE_CLASSIC 0x0000 /* default, include RTC */ +#define FAXMODE_NORTC 0x0001 /* no RTC at end of data */ +#define FAXMODE_NOEOL 0x0002 /* no EOL code at end of row */ +#define FAXMODE_BYTEALIGN 0x0004 /* byte align row */ +#define FAXMODE_WORDALIGN 0x0008 /* word align row */ +#define FAXMODE_CLASSF FAXMODE_NORTC /* TIFF Class F */ +#define TIFFTAG_JPEGQUALITY 65537 /* Compression quality level */ +/* Note: quality level is on the IJG 0-100 scale. Default value is 75 */ +#define TIFFTAG_JPEGCOLORMODE 65538 /* Auto RGB<=>YCbCr convert? */ +#define JPEGCOLORMODE_RAW 0x0000 /* no conversion (default) */ +#define JPEGCOLORMODE_RGB 0x0001 /* do auto conversion */ +#define TIFFTAG_JPEGTABLESMODE 65539 /* What to put in JPEGTables */ +#define JPEGTABLESMODE_QUANT 0x0001 /* include quantization tbls */ +#define JPEGTABLESMODE_HUFF 0x0002 /* include Huffman tbls */ +/* Note: default is JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF */ +#define TIFFTAG_FAXFILLFUNC 65540 /* G3/G4 fill function */ +#define TIFFTAG_PIXARLOGDATAFMT 65549 /* PixarLogCodec I/O data sz */ +#define PIXARLOGDATAFMT_8BIT 0 /* regular u_char samples */ +#define PIXARLOGDATAFMT_8BITABGR 1 /* ABGR-order u_chars */ +#define PIXARLOGDATAFMT_11BITLOG 2 /* 11-bit log-encoded (raw) */ +#define PIXARLOGDATAFMT_12BITPICIO 3 /* as per PICIO (1.0==2048) */ +#define PIXARLOGDATAFMT_16BIT 4 /* signed short samples */ +#define PIXARLOGDATAFMT_FLOAT 5 /* IEEE float samples */ +/* 65550-65556 are allocated to Oceana Matrix */ +#define TIFFTAG_DCSIMAGERTYPE 65550 /* imager model & filter */ +#define DCSIMAGERMODEL_M3 0 /* M3 chip (1280 x 1024) */ +#define DCSIMAGERMODEL_M5 1 /* M5 chip (1536 x 1024) */ +#define DCSIMAGERMODEL_M6 2 /* M6 chip (3072 x 2048) */ +#define DCSIMAGERFILTER_IR 0 /* infrared filter */ +#define DCSIMAGERFILTER_MONO 1 /* monochrome filter */ +#define DCSIMAGERFILTER_CFA 2 /* color filter array */ +#define DCSIMAGERFILTER_OTHER 3 /* other filter */ +#define TIFFTAG_DCSINTERPMODE 65551 /* interpolation mode */ +#define DCSINTERPMODE_NORMAL 0x0 /* whole image, default */ +#define DCSINTERPMODE_PREVIEW 0x1 /* preview of image (384x256) */ +#define TIFFTAG_DCSBALANCEARRAY 65552 /* color balance values */ +#define TIFFTAG_DCSCORRECTMATRIX 65553 /* color correction values */ +#define TIFFTAG_DCSGAMMA 65554 /* gamma value */ +#define TIFFTAG_DCSTOESHOULDERPTS 65555 /* toe & shoulder points */ +#define TIFFTAG_DCSCALIBRATIONFD 65556 /* calibration file desc */ +/* Note: quality level is on the ZLIB 1-9 scale. Default value is -1 */ +#define TIFFTAG_ZIPQUALITY 65557 /* compression quality level */ +#define TIFFTAG_PIXARLOGQUALITY 65558 /* PixarLog uses same scale */ +/* 65559 is allocated to Oceana Matrix */ +#define TIFFTAG_DCSCLIPRECTANGLE 65559 /* area of image to acquire */ +#define TIFFTAG_SGILOGDATAFMT 65560 /* SGILog user data format */ +#define SGILOGDATAFMT_FLOAT 0 /* IEEE float samples */ +#define SGILOGDATAFMT_16BIT 1 /* 16-bit samples */ +#define SGILOGDATAFMT_RAW 2 /* uninterpreted data */ +#define SGILOGDATAFMT_8BIT 3 /* 8-bit RGB monitor values */ +#define TIFFTAG_SGILOGENCODE 65561 /* SGILog data encoding control*/ +#define SGILOGENCODE_NODITHER 0 /* do not dither encoded values*/ +#define SGILOGENCODE_RANDITHER 1 /* randomly dither encd values */ + +/* + * EXIF tags + */ +#define EXIFTAG_EXPOSURETIME 33434 /* Exposure time */ +#define EXIFTAG_FNUMBER 33437 /* F number */ +#define EXIFTAG_EXPOSUREPROGRAM 34850 /* Exposure program */ +#define EXIFTAG_SPECTRALSENSITIVITY 34852 /* Spectral sensitivity */ +#define EXIFTAG_ISOSPEEDRATINGS 34855 /* ISO speed rating */ +#define EXIFTAG_OECF 34856 /* Optoelectric conversion + factor */ +#define EXIFTAG_EXIFVERSION 36864 /* Exif version */ +#define EXIFTAG_DATETIMEORIGINAL 36867 /* Date and time of original + data generation */ +#define EXIFTAG_DATETIMEDIGITIZED 36868 /* Date and time of digital + data generation */ +#define EXIFTAG_COMPONENTSCONFIGURATION 37121 /* Meaning of each component */ +#define EXIFTAG_COMPRESSEDBITSPERPIXEL 37122 /* Image compression mode */ +#define EXIFTAG_SHUTTERSPEEDVALUE 37377 /* Shutter speed */ +#define EXIFTAG_APERTUREVALUE 37378 /* Aperture */ +#define EXIFTAG_BRIGHTNESSVALUE 37379 /* Brightness */ +#define EXIFTAG_EXPOSUREBIASVALUE 37380 /* Exposure bias */ +#define EXIFTAG_MAXAPERTUREVALUE 37381 /* Maximum lens aperture */ +#define EXIFTAG_SUBJECTDISTANCE 37382 /* Subject distance */ +#define EXIFTAG_METERINGMODE 37383 /* Metering mode */ +#define EXIFTAG_LIGHTSOURCE 37384 /* Light source */ +#define EXIFTAG_FLASH 37385 /* Flash */ +#define EXIFTAG_FOCALLENGTH 37386 /* Lens focal length */ +#define EXIFTAG_SUBJECTAREA 37396 /* Subject area */ +#define EXIFTAG_MAKERNOTE 37500 /* Manufacturer notes */ +#define EXIFTAG_USERCOMMENT 37510 /* User comments */ +#define EXIFTAG_SUBSECTIME 37520 /* DateTime subseconds */ +#define EXIFTAG_SUBSECTIMEORIGINAL 37521 /* DateTimeOriginal subseconds */ +#define EXIFTAG_SUBSECTIMEDIGITIZED 37522 /* DateTimeDigitized subseconds */ +#define EXIFTAG_FLASHPIXVERSION 40960 /* Supported Flashpix version */ +#define EXIFTAG_COLORSPACE 40961 /* Color space information */ +#define EXIFTAG_PIXELXDIMENSION 40962 /* Valid image width */ +#define EXIFTAG_PIXELYDIMENSION 40963 /* Valid image height */ +#define EXIFTAG_RELATEDSOUNDFILE 40964 /* Related audio file */ +#define EXIFTAG_FLASHENERGY 41483 /* Flash energy */ +#define EXIFTAG_SPATIALFREQUENCYRESPONSE 41484 /* Spatial frequency response */ +#define EXIFTAG_FOCALPLANEXRESOLUTION 41486 /* Focal plane X resolution */ +#define EXIFTAG_FOCALPLANEYRESOLUTION 41487 /* Focal plane Y resolution */ +#define EXIFTAG_FOCALPLANERESOLUTIONUNIT 41488 /* Focal plane resolution unit */ +#define EXIFTAG_SUBJECTLOCATION 41492 /* Subject location */ +#define EXIFTAG_EXPOSUREINDEX 41493 /* Exposure index */ +#define EXIFTAG_SENSINGMETHOD 41495 /* Sensing method */ +#define EXIFTAG_FILESOURCE 41728 /* File source */ +#define EXIFTAG_SCENETYPE 41729 /* Scene type */ +#define EXIFTAG_CFAPATTERN 41730 /* CFA pattern */ +#define EXIFTAG_CUSTOMRENDERED 41985 /* Custom image processing */ +#define EXIFTAG_EXPOSUREMODE 41986 /* Exposure mode */ +#define EXIFTAG_WHITEBALANCE 41987 /* White balance */ +#define EXIFTAG_DIGITALZOOMRATIO 41988 /* Digital zoom ratio */ +#define EXIFTAG_FOCALLENGTHIN35MMFILM 41989 /* Focal length in 35 mm film */ +#define EXIFTAG_SCENECAPTURETYPE 41990 /* Scene capture type */ +#define EXIFTAG_GAINCONTROL 41991 /* Gain control */ +#define EXIFTAG_CONTRAST 41992 /* Contrast */ +#define EXIFTAG_SATURATION 41993 /* Saturation */ +#define EXIFTAG_SHARPNESS 41994 /* Sharpness */ +#define EXIFTAG_DEVICESETTINGDESCRIPTION 41995 /* Device settings description */ +#define EXIFTAG_SUBJECTDISTANCERANGE 41996 /* Subject distance range */ +#define EXIFTAG_GAINCONTROL 41991 /* Gain control */ +#define EXIFTAG_GAINCONTROL 41991 /* Gain control */ +#define EXIFTAG_IMAGEUNIQUEID 42016 /* Unique image ID */ + +#endif /* _TIFF_ */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/winclude/tiffconf.h b/winclude/tiffconf.h new file mode 100755 index 000000000..1b7a4d511 --- /dev/null +++ b/winclude/tiffconf.h @@ -0,0 +1,101 @@ +/* libtiff/tiffconf.h. Generated by configure. */ +/* + Configuration defines for installed libtiff. + This file maintained for backward compatibility. Do not use definitions + from this file in your programs. +*/ + +#ifndef _TIFFCONF_ +#define _TIFFCONF_ + +/* Define to 1 if the system has the type `int16'. */ +/* #undef HAVE_INT16 */ + +/* Define to 1 if the system has the type `int32'. */ +/* #undef HAVE_INT32 */ + +/* Define to 1 if the system has the type `int8'. */ +/* #undef HAVE_INT8 */ + +/* The size of a `int', as computed by sizeof. */ +#define SIZEOF_INT 4 + +/* The size of a `long', as computed by sizeof. */ +#define SIZEOF_LONG 4 + +/* Compatibility stuff. */ + +/* Define as 0 or 1 according to the floating point format suported by the + machine */ +#define HAVE_IEEEFP 1 + +/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */ +#define HOST_FILLORDER FILLORDER_LSB2MSB + +/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian + (Intel) */ +#define HOST_BIGENDIAN 0 + +/* Support CCITT Group 3 & 4 algorithms */ +#define CCITT_SUPPORT 1 + +/* Support JPEG compression (requires IJG JPEG library) */ +/* #undef JPEG_SUPPORT */ + +/* Support LogLuv high dynamic range encoding */ +#define LOGLUV_SUPPORT 1 + +/* Support LZW algorithm */ +#define LZW_SUPPORT 1 + +/* Support NeXT 2-bit RLE algorithm */ +#define NEXT_SUPPORT 1 + +/* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation + fails with unpatched IJG JPEG library) */ +/* #undef OJPEG_SUPPORT */ + +/* Support Macintosh PackBits algorithm */ +#define PACKBITS_SUPPORT 1 + +/* Support Pixar log-format algorithm (requires Zlib) */ +#define PIXARLOG_SUPPORT 1 + +/* Support ThunderScan 4-bit RLE algorithm */ +#define THUNDER_SUPPORT 1 + +/* Support Deflate compression */ +#define ZIP_SUPPORT 1 + +/* Support strip chopping (whether or not to convert single-strip uncompressed + images to mutiple strips of ~8Kb to reduce memory usage) */ +#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP + +/* Enable SubIFD tag (330) support */ +#define SUBIFD_SUPPORT 1 + +/* Treat extra sample as alpha (default enabled). The RGBA interface will + treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many + packages produce RGBA files but don't mark the alpha properly. */ +#define DEFAULT_EXTRASAMPLE_AS_ALPHA 1 + +/* Pick up YCbCr subsampling info from the JPEG data stream to support files + lacking the tag (default enabled). */ +#define CHECK_JPEG_YCBCR_SUBSAMPLING 1 + +/* Support MS MDI magic number files as TIFF */ +#define MDI_SUPPORT 1 + +/* + * Feature support definitions. + * XXX: These macros are obsoleted. Don't use them in your apps! + * Macros stays here for backward compatibility and should be always defined. + */ +#define COLORIMETRY_SUPPORT +#define YCBCR_SUPPORT +#define CMYK_SUPPORT +#define ICC_SUPPORT +#define PHOTOSHOP_SUPPORT +#define IPTC_SUPPORT + +#endif /* _TIFFCONF_ */ diff --git a/winclude/tiffio.h b/winclude/tiffio.h new file mode 100755 index 000000000..61c3d642a --- /dev/null +++ b/winclude/tiffio.h @@ -0,0 +1,516 @@ +/* $Id: tiffio.h,v 1.49 2005/12/27 11:13:58 dron Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _TIFFIO_ +#define _TIFFIO_ + +/* + * TIFF I/O Library Definitions. + */ +#include "tiff.h" +#include "tiffvers.h" + +/* + * TIFF is defined as an incomplete type to hide the + * library's internal data structures from clients. + */ +typedef struct tiff TIFF; + +/* + * The following typedefs define the intrinsic size of + * data types used in the *exported* interfaces. These + * definitions depend on the proper definition of types + * in tiff.h. Note also that the varargs interface used + * to pass tag types and values uses the types defined in + * tiff.h directly. + * + * NB: ttag_t is unsigned int and not unsigned short because + * ANSI C requires that the type before the ellipsis be a + * promoted type (i.e. one of int, unsigned int, pointer, + * or double) and because we defined pseudo-tags that are + * outside the range of legal Aldus-assigned tags. + * NB: tsize_t is int32 and not uint32 because some functions + * return -1. + * NB: toff_t is not off_t for many reasons; TIFFs max out at + * 32-bit file offsets being the most important, and to ensure + * that it is unsigned, rather than signed. + */ +typedef uint32 ttag_t; /* directory tag */ +typedef uint16 tdir_t; /* directory index */ +typedef uint16 tsample_t; /* sample number */ +typedef uint32 tstrip_t; /* strip number */ +typedef uint32 ttile_t; /* tile number */ +typedef int32 tsize_t; /* i/o size in bytes */ +typedef void* tdata_t; /* image data ref */ +typedef uint32 toff_t; /* file offset */ + +#if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32)) +#define __WIN32__ +#endif + +/* + * On windows you should define USE_WIN32_FILEIO if you are using tif_win32.c + * or AVOID_WIN32_FILEIO if you are using something else (like tif_unix.c). + * + * By default tif_win32.c is assumed on windows if not using the cygwin + * environment. + */ + +#if defined(_WINDOWS) || defined(__WIN32__) || defined(_Windows) +# if !defined(__CYGWIN) && !defined(AVOID_WIN32_FILEIO) && !defined(USE_WIN32_FILEIO) +# define USE_WIN32_FILEIO +# endif +#endif + +#if defined(USE_WIN32_FILEIO) +# define VC_EXTRALEAN +# include +# ifdef __WIN32__ +DECLARE_HANDLE(thandle_t); /* Win32 file handle */ +# else +typedef HFILE thandle_t; /* client data handle */ +# endif /* __WIN32__ */ +#else +typedef void* thandle_t; /* client data handle */ +#endif /* USE_WIN32_FILEIO */ + +#ifndef NULL +# define NULL (void *)0 +#endif + +/* + * Flags to pass to TIFFPrintDirectory to control + * printing of data structures that are potentially + * very large. Bit-or these flags to enable printing + * multiple items. + */ +#define TIFFPRINT_NONE 0x0 /* no extra info */ +#define TIFFPRINT_STRIPS 0x1 /* strips/tiles info */ +#define TIFFPRINT_CURVES 0x2 /* color/gray response curves */ +#define TIFFPRINT_COLORMAP 0x4 /* colormap */ +#define TIFFPRINT_JPEGQTABLES 0x100 /* JPEG Q matrices */ +#define TIFFPRINT_JPEGACTABLES 0x200 /* JPEG AC tables */ +#define TIFFPRINT_JPEGDCTABLES 0x200 /* JPEG DC tables */ + +/* + * Colour conversion stuff + */ + +/* reference white */ +#define D65_X0 (95.0470F) +#define D65_Y0 (100.0F) +#define D65_Z0 (108.8827F) + +#define D50_X0 (96.4250F) +#define D50_Y0 (100.0F) +#define D50_Z0 (82.4680F) + +/* Structure for holding information about a display device. */ + +typedef unsigned char TIFFRGBValue; /* 8-bit samples */ + +typedef struct { + float d_mat[3][3]; /* XYZ -> luminance matrix */ + float d_YCR; /* Light o/p for reference white */ + float d_YCG; + float d_YCB; + uint32 d_Vrwr; /* Pixel values for ref. white */ + uint32 d_Vrwg; + uint32 d_Vrwb; + float d_Y0R; /* Residual light for black pixel */ + float d_Y0G; + float d_Y0B; + float d_gammaR; /* Gamma values for the three guns */ + float d_gammaG; + float d_gammaB; +} TIFFDisplay; + +typedef struct { /* YCbCr->RGB support */ + TIFFRGBValue* clamptab; /* range clamping table */ + int* Cr_r_tab; + int* Cb_b_tab; + int32* Cr_g_tab; + int32* Cb_g_tab; + int32* Y_tab; +} TIFFYCbCrToRGB; + +typedef struct { /* CIE Lab 1976->RGB support */ + int range; /* Size of conversion table */ +#define CIELABTORGB_TABLE_RANGE 1500 + float rstep, gstep, bstep; + float X0, Y0, Z0; /* Reference white point */ + TIFFDisplay display; + float Yr2r[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yr to r */ + float Yg2g[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yg to g */ + float Yb2b[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yb to b */ +} TIFFCIELabToRGB; + +/* + * RGBA-style image support. + */ +typedef struct _TIFFRGBAImage TIFFRGBAImage; +/* + * The image reading and conversion routines invoke + * ``put routines'' to copy/image/whatever tiles of + * raw image data. A default set of routines are + * provided to convert/copy raw image data to 8-bit + * packed ABGR format rasters. Applications can supply + * alternate routines that unpack the data into a + * different format or, for example, unpack the data + * and draw the unpacked raster on the display. + */ +typedef void (*tileContigRoutine) + (TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32, + unsigned char*); +typedef void (*tileSeparateRoutine) + (TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32, + unsigned char*, unsigned char*, unsigned char*, unsigned char*); +/* + * RGBA-reader state. + */ +struct _TIFFRGBAImage { + TIFF* tif; /* image handle */ + int stoponerr; /* stop on read error */ + int isContig; /* data is packed/separate */ + int alpha; /* type of alpha data present */ + uint32 width; /* image width */ + uint32 height; /* image height */ + uint16 bitspersample; /* image bits/sample */ + uint16 samplesperpixel; /* image samples/pixel */ + uint16 orientation; /* image orientation */ + uint16 req_orientation; /* requested orientation */ + uint16 photometric; /* image photometric interp */ + uint16* redcmap; /* colormap pallete */ + uint16* greencmap; + uint16* bluecmap; + /* get image data routine */ + int (*get)(TIFFRGBAImage*, uint32*, uint32, uint32); + union { + void (*any)(TIFFRGBAImage*); + tileContigRoutine contig; + tileSeparateRoutine separate; + } put; /* put decoded strip/tile */ + TIFFRGBValue* Map; /* sample mapping array */ + uint32** BWmap; /* black&white map */ + uint32** PALmap; /* palette image map */ + TIFFYCbCrToRGB* ycbcr; /* YCbCr conversion state */ + TIFFCIELabToRGB* cielab; /* CIE L*a*b conversion state */ + + int row_offset; + int col_offset; +}; + +/* + * Macros for extracting components from the + * packed ABGR form returned by TIFFReadRGBAImage. + */ +#define TIFFGetR(abgr) ((abgr) & 0xff) +#define TIFFGetG(abgr) (((abgr) >> 8) & 0xff) +#define TIFFGetB(abgr) (((abgr) >> 16) & 0xff) +#define TIFFGetA(abgr) (((abgr) >> 24) & 0xff) + +/* + * A CODEC is a software package that implements decoding, + * encoding, or decoding+encoding of a compression algorithm. + * The library provides a collection of builtin codecs. + * More codecs may be registered through calls to the library + * and/or the builtin implementations may be overridden. + */ +typedef int (*TIFFInitMethod)(TIFF*, int); +typedef struct { + char* name; + uint16 scheme; + TIFFInitMethod init; +} TIFFCodec; + +#include +#include + +/* share internal LogLuv conversion routines? */ +#ifndef LOGLUV_PUBLIC +#define LOGLUV_PUBLIC 1 +#endif + +#if defined(c_plusplus) || defined(__cplusplus) +extern "C" { +#endif +typedef void (*TIFFErrorHandler)(const char*, const char*, va_list); +typedef void (*TIFFErrorHandlerExt)(thandle_t, const char*, const char*, va_list); +typedef tsize_t (*TIFFReadWriteProc)(thandle_t, tdata_t, tsize_t); +typedef toff_t (*TIFFSeekProc)(thandle_t, toff_t, int); +typedef int (*TIFFCloseProc)(thandle_t); +typedef toff_t (*TIFFSizeProc)(thandle_t); +typedef int (*TIFFMapFileProc)(thandle_t, tdata_t*, toff_t*); +typedef void (*TIFFUnmapFileProc)(thandle_t, tdata_t, toff_t); +typedef void (*TIFFExtendProc)(TIFF*); + +extern const char* TIFFGetVersion(void); + +extern const TIFFCodec* TIFFFindCODEC(uint16); +extern TIFFCodec* TIFFRegisterCODEC(uint16, const char*, TIFFInitMethod); +extern void TIFFUnRegisterCODEC(TIFFCodec*); +extern int TIFFIsCODECConfigured(uint16); +extern TIFFCodec* TIFFGetConfiguredCODECs(void); + +/* + * Auxiliary functions. + */ + +extern tdata_t _TIFFmalloc(tsize_t); +extern tdata_t _TIFFrealloc(tdata_t, tsize_t); +extern void _TIFFmemset(tdata_t, int, tsize_t); +extern void _TIFFmemcpy(tdata_t, const tdata_t, tsize_t); +extern int _TIFFmemcmp(const tdata_t, const tdata_t, tsize_t); +extern void _TIFFfree(tdata_t); + +/* +** Stuff, related to tag handling and creating custom tags. +*/ +extern int TIFFGetTagListCount( TIFF * ); +extern ttag_t TIFFGetTagListEntry( TIFF *, int tag_index ); + +#define TIFF_ANY TIFF_NOTYPE /* for field descriptor searching */ +#define TIFF_VARIABLE -1 /* marker for variable length tags */ +#define TIFF_SPP -2 /* marker for SamplesPerPixel tags */ +#define TIFF_VARIABLE2 -3 /* marker for uint32 var-length tags */ + +#define FIELD_CUSTOM 65 + +typedef struct { + ttag_t field_tag; /* field's tag */ + short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */ + short field_writecount; /* write count/TIFF_VARIABLE */ + TIFFDataType field_type; /* type of associated data */ + unsigned short field_bit; /* bit in fieldsset bit vector */ + unsigned char field_oktochange; /* if true, can change while writing */ + unsigned char field_passcount; /* if true, pass dir count on set */ + char *field_name; /* ASCII name */ +} TIFFFieldInfo; + +typedef struct _TIFFTagValue { + const TIFFFieldInfo *info; + int count; + void *value; +} TIFFTagValue; + +extern void TIFFMergeFieldInfo(TIFF*, const TIFFFieldInfo[], int); +extern const TIFFFieldInfo* TIFFFindFieldInfo(TIFF*, ttag_t, TIFFDataType); +extern const TIFFFieldInfo* TIFFFindFieldInfoByName(TIFF* , const char *, + TIFFDataType); +extern const TIFFFieldInfo* TIFFFieldWithTag(TIFF*, ttag_t); +extern const TIFFFieldInfo* TIFFFieldWithName(TIFF*, const char *); + +typedef int (*TIFFVSetMethod)(TIFF*, ttag_t, va_list); +typedef int (*TIFFVGetMethod)(TIFF*, ttag_t, va_list); +typedef void (*TIFFPrintMethod)(TIFF*, FILE*, long); + +typedef struct { + TIFFVSetMethod vsetfield; /* tag set routine */ + TIFFVGetMethod vgetfield; /* tag get routine */ + TIFFPrintMethod printdir; /* directory print routine */ +} TIFFTagMethods; + +extern TIFFTagMethods *TIFFAccessTagMethods( TIFF * ); +extern void *TIFFGetClientInfo( TIFF *, const char * ); +extern void TIFFSetClientInfo( TIFF *, void *, const char * ); + +extern void TIFFCleanup(TIFF*); +extern void TIFFClose(TIFF*); +extern int TIFFFlush(TIFF*); +extern int TIFFFlushData(TIFF*); +extern int TIFFGetField(TIFF*, ttag_t, ...); +extern int TIFFVGetField(TIFF*, ttag_t, va_list); +extern int TIFFGetFieldDefaulted(TIFF*, ttag_t, ...); +extern int TIFFVGetFieldDefaulted(TIFF*, ttag_t, va_list); +extern int TIFFReadDirectory(TIFF*); +extern int TIFFReadCustomDirectory(TIFF*, toff_t, const TIFFFieldInfo[], + size_t); +extern int TIFFReadEXIFDirectory(TIFF*, toff_t); +extern tsize_t TIFFScanlineSize(TIFF*); +extern tsize_t TIFFRasterScanlineSize(TIFF*); +extern tsize_t TIFFStripSize(TIFF*); +extern tsize_t TIFFRawStripSize(TIFF*, tstrip_t); +extern tsize_t TIFFVStripSize(TIFF*, uint32); +extern tsize_t TIFFTileRowSize(TIFF*); +extern tsize_t TIFFTileSize(TIFF*); +extern tsize_t TIFFVTileSize(TIFF*, uint32); +extern uint32 TIFFDefaultStripSize(TIFF*, uint32); +extern void TIFFDefaultTileSize(TIFF*, uint32*, uint32*); +extern int TIFFFileno(TIFF*); +extern int TIFFSetFileno(TIFF*, int); +extern thandle_t TIFFClientdata(TIFF*); +extern thandle_t TIFFSetClientdata(TIFF*, thandle_t); +extern int TIFFGetMode(TIFF*); +extern int TIFFSetMode(TIFF*, int); +extern int TIFFIsTiled(TIFF*); +extern int TIFFIsByteSwapped(TIFF*); +extern int TIFFIsUpSampled(TIFF*); +extern int TIFFIsMSB2LSB(TIFF*); +extern int TIFFIsBigEndian(TIFF*); +extern TIFFReadWriteProc TIFFGetReadProc(TIFF*); +extern TIFFReadWriteProc TIFFGetWriteProc(TIFF*); +extern TIFFSeekProc TIFFGetSeekProc(TIFF*); +extern TIFFCloseProc TIFFGetCloseProc(TIFF*); +extern TIFFSizeProc TIFFGetSizeProc(TIFF*); +extern TIFFMapFileProc TIFFGetMapFileProc(TIFF*); +extern TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF*); +extern uint32 TIFFCurrentRow(TIFF*); +extern tdir_t TIFFCurrentDirectory(TIFF*); +extern tdir_t TIFFNumberOfDirectories(TIFF*); +extern uint32 TIFFCurrentDirOffset(TIFF*); +extern tstrip_t TIFFCurrentStrip(TIFF*); +extern ttile_t TIFFCurrentTile(TIFF*); +extern int TIFFReadBufferSetup(TIFF*, tdata_t, tsize_t); +extern int TIFFWriteBufferSetup(TIFF*, tdata_t, tsize_t); +extern int TIFFSetupStrips(TIFF *); +extern int TIFFWriteCheck(TIFF*, int, const char *); +extern void TIFFFreeDirectory(TIFF*); +extern int TIFFCreateDirectory(TIFF*); +extern int TIFFLastDirectory(TIFF*); +extern int TIFFSetDirectory(TIFF*, tdir_t); +extern int TIFFSetSubDirectory(TIFF*, uint32); +extern int TIFFUnlinkDirectory(TIFF*, tdir_t); +extern int TIFFSetField(TIFF*, ttag_t, ...); +extern int TIFFVSetField(TIFF*, ttag_t, va_list); +extern int TIFFWriteDirectory(TIFF *); +extern int TIFFCheckpointDirectory(TIFF *); +extern int TIFFRewriteDirectory(TIFF *); +extern int TIFFReassignTagToIgnore(enum TIFFIgnoreSense, int); + +#if defined(c_plusplus) || defined(__cplusplus) +extern void TIFFPrintDirectory(TIFF*, FILE*, long = 0); +extern int TIFFReadScanline(TIFF*, tdata_t, uint32, tsample_t = 0); +extern int TIFFWriteScanline(TIFF*, tdata_t, uint32, tsample_t = 0); +extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int = 0); +extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*, + int = ORIENTATION_BOTLEFT, int = 0); +#else +extern void TIFFPrintDirectory(TIFF*, FILE*, long); +extern int TIFFReadScanline(TIFF*, tdata_t, uint32, tsample_t); +extern int TIFFWriteScanline(TIFF*, tdata_t, uint32, tsample_t); +extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int); +extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*, int, int); +#endif + +extern int TIFFReadRGBAStrip(TIFF*, tstrip_t, uint32 * ); +extern int TIFFReadRGBATile(TIFF*, uint32, uint32, uint32 * ); +extern int TIFFRGBAImageOK(TIFF*, char [1024]); +extern int TIFFRGBAImageBegin(TIFFRGBAImage*, TIFF*, int, char [1024]); +extern int TIFFRGBAImageGet(TIFFRGBAImage*, uint32*, uint32, uint32); +extern void TIFFRGBAImageEnd(TIFFRGBAImage*); +extern TIFF* TIFFOpen(const char*, const char*); +# ifdef __WIN32__ +extern TIFF* TIFFOpenW(const wchar_t*, const char*); +# endif /* __WIN32__ */ +extern TIFF* TIFFFdOpen(int, const char*, const char*); +extern TIFF* TIFFClientOpen(const char*, const char*, + thandle_t, + TIFFReadWriteProc, TIFFReadWriteProc, + TIFFSeekProc, TIFFCloseProc, + TIFFSizeProc, + TIFFMapFileProc, TIFFUnmapFileProc); +extern const char* TIFFFileName(TIFF*); +extern const char* TIFFSetFileName(TIFF*, const char *); +extern void TIFFError(const char*, const char*, ...); +extern void TIFFErrorExt(thandle_t, const char*, const char*, ...); +extern void TIFFWarning(const char*, const char*, ...); +extern void TIFFWarningExt(thandle_t, const char*, const char*, ...); +extern TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler); +extern TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt); +extern TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler); +extern TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt); +extern TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc); +extern ttile_t TIFFComputeTile(TIFF*, uint32, uint32, uint32, tsample_t); +extern int TIFFCheckTile(TIFF*, uint32, uint32, uint32, tsample_t); +extern ttile_t TIFFNumberOfTiles(TIFF*); +extern tsize_t TIFFReadTile(TIFF*, + tdata_t, uint32, uint32, uint32, tsample_t); +extern tsize_t TIFFWriteTile(TIFF*, + tdata_t, uint32, uint32, uint32, tsample_t); +extern tstrip_t TIFFComputeStrip(TIFF*, uint32, tsample_t); +extern tstrip_t TIFFNumberOfStrips(TIFF*); +extern tsize_t TIFFReadEncodedStrip(TIFF*, tstrip_t, tdata_t, tsize_t); +extern tsize_t TIFFReadRawStrip(TIFF*, tstrip_t, tdata_t, tsize_t); +extern tsize_t TIFFReadEncodedTile(TIFF*, ttile_t, tdata_t, tsize_t); +extern tsize_t TIFFReadRawTile(TIFF*, ttile_t, tdata_t, tsize_t); +extern tsize_t TIFFWriteEncodedStrip(TIFF*, tstrip_t, tdata_t, tsize_t); +extern tsize_t TIFFWriteRawStrip(TIFF*, tstrip_t, tdata_t, tsize_t); +extern tsize_t TIFFWriteEncodedTile(TIFF*, ttile_t, tdata_t, tsize_t); +extern tsize_t TIFFWriteRawTile(TIFF*, ttile_t, tdata_t, tsize_t); +extern int TIFFDataWidth(TIFFDataType); /* table of tag datatype widths */ +extern void TIFFSetWriteOffset(TIFF*, toff_t); +extern void TIFFSwabShort(uint16*); +extern void TIFFSwabLong(uint32*); +extern void TIFFSwabDouble(double*); +extern void TIFFSwabArrayOfShort(uint16*, unsigned long); +extern void TIFFSwabArrayOfTriples(uint8*, unsigned long); +extern void TIFFSwabArrayOfLong(uint32*, unsigned long); +extern void TIFFSwabArrayOfDouble(double*, unsigned long); +extern void TIFFReverseBits(unsigned char *, unsigned long); +extern const unsigned char* TIFFGetBitRevTable(int); + +#ifdef LOGLUV_PUBLIC +#define U_NEU 0.210526316 +#define V_NEU 0.473684211 +#define UVSCALE 410. +extern double LogL16toY(int); +extern double LogL10toY(int); +extern void XYZtoRGB24(float*, uint8*); +extern int uv_decode(double*, double*, int); +extern void LogLuv24toXYZ(uint32, float*); +extern void LogLuv32toXYZ(uint32, float*); +#if defined(c_plusplus) || defined(__cplusplus) +extern int LogL16fromY(double, int = SGILOGENCODE_NODITHER); +extern int LogL10fromY(double, int = SGILOGENCODE_NODITHER); +extern int uv_encode(double, double, int = SGILOGENCODE_NODITHER); +extern uint32 LogLuv24fromXYZ(float*, int = SGILOGENCODE_NODITHER); +extern uint32 LogLuv32fromXYZ(float*, int = SGILOGENCODE_NODITHER); +#else +extern int LogL16fromY(double, int); +extern int LogL10fromY(double, int); +extern int uv_encode(double, double, int); +extern uint32 LogLuv24fromXYZ(float*, int); +extern uint32 LogLuv32fromXYZ(float*, int); +#endif +#endif /* LOGLUV_PUBLIC */ + +extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB*, TIFFDisplay *, float*); +extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32, int32, int32, + float *, float *, float *); +extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float, + uint32 *, uint32 *, uint32 *); + +extern int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB*, float*, float*); +extern void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *, uint32, int32, int32, + uint32 *, uint32 *, uint32 *); + +#if defined(c_plusplus) || defined(__cplusplus) +} +#endif + +#endif /* _TIFFIO_ */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/winclude/tiffiop.h b/winclude/tiffiop.h new file mode 100755 index 000000000..5e8d0dacc --- /dev/null +++ b/winclude/tiffiop.h @@ -0,0 +1,322 @@ +/* $Id: tiffiop.h,v 1.44 2005/12/21 13:05:32 joris Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _TIFFIOP_ +#define _TIFFIOP_ +/* + * ``Library-private'' definitions. + */ + +#include "tif_config.h" + +#ifdef HAVE_FCNTL_H +# include +#endif + +#ifdef HAVE_SYS_TYPES_H +# include +#endif + +#ifdef HAVE_STRING_H +# include +#endif + +#ifdef HAVE_ASSERT_H +# include +#else +# define assert(x) +#endif + +#ifdef HAVE_SEARCH_H +# include +#else +extern void *lfind(const void *, const void *, size_t *, size_t, + int (*)(const void *, const void *)); +#endif + +#include "tiffio.h" +#include "tif_dir.h" + +typedef double dblparam_t; + +#define GLOBALDATA(TYPE,NAME) extern TYPE NAME + +#define streq(a,b) (strcmp(a,b) == 0) + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +typedef struct client_info { + struct client_info *next; + void *data; + char *name; +} TIFFClientInfoLink; + +/* + * Typedefs for ``method pointers'' used internally. + */ +typedef unsigned char tidataval_t; /* internal image data value type */ +typedef tidataval_t* tidata_t; /* reference to internal image data */ + +typedef void (*TIFFVoidMethod)(TIFF*); +typedef int (*TIFFBoolMethod)(TIFF*); +typedef int (*TIFFPreMethod)(TIFF*, tsample_t); +typedef int (*TIFFCodeMethod)(TIFF*, tidata_t, tsize_t, tsample_t); +typedef int (*TIFFSeekMethod)(TIFF*, uint32); +typedef void (*TIFFPostMethod)(TIFF*, tidata_t, tsize_t); +typedef uint32 (*TIFFStripMethod)(TIFF*, uint32); +typedef void (*TIFFTileMethod)(TIFF*, uint32*, uint32*); + +struct tiff { + char* tif_name; /* name of open file */ + int tif_fd; /* open file descriptor */ + int tif_mode; /* open mode (O_*) */ + uint32 tif_flags; +#define TIFF_FILLORDER 0x0003 /* natural bit fill order for machine */ +#define TIFF_DIRTYHEADER 0x0004 /* header must be written on close */ +#define TIFF_DIRTYDIRECT 0x0008 /* current directory must be written */ +#define TIFF_BUFFERSETUP 0x0010 /* data buffers setup */ +#define TIFF_CODERSETUP 0x0020 /* encoder/decoder setup done */ +#define TIFF_BEENWRITING 0x0040 /* written 1+ scanlines to file */ +#define TIFF_SWAB 0x0080 /* byte swap file information */ +#define TIFF_NOBITREV 0x0100 /* inhibit bit reversal logic */ +#define TIFF_MYBUFFER 0x0200 /* my raw data buffer; free on close */ +#define TIFF_ISTILED 0x0400 /* file is tile, not strip- based */ +#define TIFF_MAPPED 0x0800 /* file is mapped into memory */ +#define TIFF_POSTENCODE 0x1000 /* need call to postencode routine */ +#define TIFF_INSUBIFD 0x2000 /* currently writing a subifd */ +#define TIFF_UPSAMPLED 0x4000 /* library is doing data up-sampling */ +#define TIFF_STRIPCHOP 0x8000 /* enable strip chopping support */ +#define TIFF_HEADERONLY 0x10000 /* read header only, do not process */ + /* the first directory */ + toff_t tif_diroff; /* file offset of current directory */ + toff_t tif_nextdiroff; /* file offset of following directory */ + toff_t* tif_dirlist; /* list of offsets to already seen */ + /* directories to prevent IFD looping */ + uint16 tif_dirnumber; /* number of already seen directories */ + TIFFDirectory tif_dir; /* internal rep of current directory */ + TIFFHeader tif_header; /* file's header block */ + const int* tif_typeshift; /* data type shift counts */ + const long* tif_typemask; /* data type masks */ + uint32 tif_row; /* current scanline */ + tdir_t tif_curdir; /* current directory (index) */ + tstrip_t tif_curstrip; /* current strip for read/write */ + toff_t tif_curoff; /* current offset for read/write */ + toff_t tif_dataoff; /* current offset for writing dir */ +/* SubIFD support */ + uint16 tif_nsubifd; /* remaining subifds to write */ + toff_t tif_subifdoff; /* offset for patching SubIFD link */ +/* tiling support */ + uint32 tif_col; /* current column (offset by row too) */ + ttile_t tif_curtile; /* current tile for read/write */ + tsize_t tif_tilesize; /* # of bytes in a tile */ +/* compression scheme hooks */ + int tif_decodestatus; + TIFFBoolMethod tif_setupdecode;/* called once before predecode */ + TIFFPreMethod tif_predecode; /* pre- row/strip/tile decoding */ + TIFFBoolMethod tif_setupencode;/* called once before preencode */ + int tif_encodestatus; + TIFFPreMethod tif_preencode; /* pre- row/strip/tile encoding */ + TIFFBoolMethod tif_postencode; /* post- row/strip/tile encoding */ + TIFFCodeMethod tif_decoderow; /* scanline decoding routine */ + TIFFCodeMethod tif_encoderow; /* scanline encoding routine */ + TIFFCodeMethod tif_decodestrip;/* strip decoding routine */ + TIFFCodeMethod tif_encodestrip;/* strip encoding routine */ + TIFFCodeMethod tif_decodetile; /* tile decoding routine */ + TIFFCodeMethod tif_encodetile; /* tile encoding routine */ + TIFFVoidMethod tif_close; /* cleanup-on-close routine */ + TIFFSeekMethod tif_seek; /* position within a strip routine */ + TIFFVoidMethod tif_cleanup; /* cleanup state routine */ + TIFFStripMethod tif_defstripsize;/* calculate/constrain strip size */ + TIFFTileMethod tif_deftilesize;/* calculate/constrain tile size */ + tidata_t tif_data; /* compression scheme private data */ +/* input/output buffering */ + tsize_t tif_scanlinesize;/* # of bytes in a scanline */ + tsize_t tif_scanlineskew;/* scanline skew for reading strips */ + tidata_t tif_rawdata; /* raw data buffer */ + tsize_t tif_rawdatasize;/* # of bytes in raw data buffer */ + tidata_t tif_rawcp; /* current spot in raw buffer */ + tsize_t tif_rawcc; /* bytes unread from raw buffer */ +/* memory-mapped file support */ + tidata_t tif_base; /* base of mapped file */ + toff_t tif_size; /* size of mapped file region (bytes) */ + TIFFMapFileProc tif_mapproc; /* map file method */ + TIFFUnmapFileProc tif_unmapproc;/* unmap file method */ +/* input/output callback methods */ + thandle_t tif_clientdata; /* callback parameter */ + TIFFReadWriteProc tif_readproc; /* read method */ + TIFFReadWriteProc tif_writeproc;/* write method */ + TIFFSeekProc tif_seekproc; /* lseek method */ + TIFFCloseProc tif_closeproc; /* close method */ + TIFFSizeProc tif_sizeproc; /* filesize method */ +/* post-decoding support */ + TIFFPostMethod tif_postdecode; /* post decoding routine */ +/* tag support */ + TIFFFieldInfo** tif_fieldinfo; /* sorted table of registered tags */ + size_t tif_nfields; /* # entries in registered tag table */ + const TIFFFieldInfo *tif_foundfield;/* cached pointer to already found tag */ + TIFFTagMethods tif_tagmethods; /* tag get/set/print routines */ + TIFFClientInfoLink *tif_clientinfo; /* extra client information. */ +}; + +#define isPseudoTag(t) (t > 0xffff) /* is tag value normal or pseudo */ + +#define isTiled(tif) (((tif)->tif_flags & TIFF_ISTILED) != 0) +#define isMapped(tif) (((tif)->tif_flags & TIFF_MAPPED) != 0) +#define isFillOrder(tif, o) (((tif)->tif_flags & (o)) != 0) +#define isUpSampled(tif) (((tif)->tif_flags & TIFF_UPSAMPLED) != 0) +#define TIFFReadFile(tif, buf, size) \ + ((*(tif)->tif_readproc)((tif)->tif_clientdata,buf,size)) +#define TIFFWriteFile(tif, buf, size) \ + ((*(tif)->tif_writeproc)((tif)->tif_clientdata,buf,size)) +#define TIFFSeekFile(tif, off, whence) \ + ((*(tif)->tif_seekproc)((tif)->tif_clientdata,(toff_t)(off),whence)) +#define TIFFCloseFile(tif) \ + ((*(tif)->tif_closeproc)((tif)->tif_clientdata)) +#define TIFFGetFileSize(tif) \ + ((*(tif)->tif_sizeproc)((tif)->tif_clientdata)) +#define TIFFMapFileContents(tif, paddr, psize) \ + ((*(tif)->tif_mapproc)((tif)->tif_clientdata,paddr,psize)) +#define TIFFUnmapFileContents(tif, addr, size) \ + ((*(tif)->tif_unmapproc)((tif)->tif_clientdata,addr,size)) + +/* + * Default Read/Seek/Write definitions. + */ +#ifndef ReadOK +#define ReadOK(tif, buf, size) \ + (TIFFReadFile(tif, (tdata_t) buf, (tsize_t)(size)) == (tsize_t)(size)) +#endif +#ifndef SeekOK +#define SeekOK(tif, off) \ + (TIFFSeekFile(tif, (toff_t) off, SEEK_SET) == (toff_t) off) +#endif +#ifndef WriteOK +#define WriteOK(tif, buf, size) \ + (TIFFWriteFile(tif, (tdata_t) buf, (tsize_t) size) == (tsize_t) size) +#endif + +/* NB: the uint32 casts are to silence certain ANSI-C compilers */ +#define TIFFhowmany(x, y) ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y))) +#define TIFFhowmany8(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3) +#define TIFFroundup(x, y) (TIFFhowmany(x,y)*(y)) + +#define TIFFmax(A,B) ((A)>(B)?(A):(B)) +#define TIFFmin(A,B) ((A)<(B)?(A):(B)) + +#define TIFFArrayCount(a) (sizeof (a) / sizeof ((a)[0])) + +#if defined(__cplusplus) +extern "C" { +#endif +extern int _TIFFgetMode(const char*, const char*); +extern int _TIFFNoRowEncode(TIFF*, tidata_t, tsize_t, tsample_t); +extern int _TIFFNoStripEncode(TIFF*, tidata_t, tsize_t, tsample_t); +extern int _TIFFNoTileEncode(TIFF*, tidata_t, tsize_t, tsample_t); +extern int _TIFFNoRowDecode(TIFF*, tidata_t, tsize_t, tsample_t); +extern int _TIFFNoStripDecode(TIFF*, tidata_t, tsize_t, tsample_t); +extern int _TIFFNoTileDecode(TIFF*, tidata_t, tsize_t, tsample_t); +extern void _TIFFNoPostDecode(TIFF*, tidata_t, tsize_t); +extern int _TIFFNoPreCode (TIFF*, tsample_t); +extern int _TIFFNoSeek(TIFF*, uint32); +extern void _TIFFSwab16BitData(TIFF*, tidata_t, tsize_t); +extern void _TIFFSwab24BitData(TIFF*, tidata_t, tsize_t); +extern void _TIFFSwab32BitData(TIFF*, tidata_t, tsize_t); +extern void _TIFFSwab64BitData(TIFF*, tidata_t, tsize_t); +extern int TIFFFlushData1(TIFF*); +extern int TIFFDefaultDirectory(TIFF*); +extern int TIFFSetCompressionScheme(TIFF*, int); +extern int TIFFSetDefaultCompressionState(TIFF*); +extern uint32 _TIFFDefaultStripSize(TIFF*, uint32); +extern void _TIFFDefaultTileSize(TIFF*, uint32*, uint32*); +extern int _TIFFDataSize(TIFFDataType); + +extern void _TIFFsetByteArray(void**, void*, uint32); +extern void _TIFFsetString(char**, char*); +extern void _TIFFsetShortArray(uint16**, uint16*, uint32); +extern void _TIFFsetLongArray(uint32**, uint32*, uint32); +extern void _TIFFsetFloatArray(float**, float*, uint32); +extern void _TIFFsetDoubleArray(double**, double*, uint32); + +extern void _TIFFprintAscii(FILE*, const char*); +extern void _TIFFprintAsciiTag(FILE*, const char*, const char*); + +GLOBALDATA(TIFFErrorHandler,_TIFFwarningHandler); +GLOBALDATA(TIFFErrorHandler,_TIFFerrorHandler); +GLOBALDATA(TIFFErrorHandlerExt,_TIFFwarningHandlerExt); +GLOBALDATA(TIFFErrorHandlerExt,_TIFFerrorHandlerExt); + +extern tdata_t _TIFFCheckMalloc(TIFF*, size_t, size_t, const char*); + +extern int TIFFInitDumpMode(TIFF*, int); +#ifdef PACKBITS_SUPPORT +extern int TIFFInitPackBits(TIFF*, int); +#endif +#ifdef CCITT_SUPPORT +extern int TIFFInitCCITTRLE(TIFF*, int), TIFFInitCCITTRLEW(TIFF*, int); +extern int TIFFInitCCITTFax3(TIFF*, int), TIFFInitCCITTFax4(TIFF*, int); +#endif +#ifdef THUNDER_SUPPORT +extern int TIFFInitThunderScan(TIFF*, int); +#endif +#ifdef NEXT_SUPPORT +extern int TIFFInitNeXT(TIFF*, int); +#endif +#ifdef LZW_SUPPORT +extern int TIFFInitLZW(TIFF*, int); +#endif +#ifdef OJPEG_SUPPORT +extern int TIFFInitOJPEG(TIFF*, int); +#endif +#ifdef JPEG_SUPPORT +extern int TIFFInitJPEG(TIFF*, int); +#endif +#ifdef JBIG_SUPPORT +extern int TIFFInitJBIG(TIFF*, int); +#endif +#ifdef ZIP_SUPPORT +extern int TIFFInitZIP(TIFF*, int); +#endif +#ifdef PIXARLOG_SUPPORT +extern int TIFFInitPixarLog(TIFF*, int); +#endif +#ifdef LOGLUV_SUPPORT +extern int TIFFInitSGILog(TIFF*, int); +#endif +#ifdef VMS +extern const TIFFCodec _TIFFBuiltinCODECS[]; +#else +extern TIFFCodec _TIFFBuiltinCODECS[]; +#endif + +#if defined(__cplusplus) +} +#endif +#endif /* _TIFFIOP_ */ + +/* vim: set ts=8 sts=8 sw=8 noet: */ diff --git a/winclude/tiffvers.h b/winclude/tiffvers.h new file mode 100755 index 000000000..afefd74bb --- /dev/null +++ b/winclude/tiffvers.h @@ -0,0 +1,9 @@ +#define TIFFLIB_VERSION_STR "LIBTIFF, Version 3.8.0\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc." +/* + * This define can be used in code that requires + * compilation-related definitions specific to a + * version or versions of the library. Runtime + * version checking should be done based on the + * string returned by TIFFGetVersion. + */ +#define TIFFLIB_VERSION 20051230 diff --git a/winclude/transupp.h b/winclude/transupp.h new file mode 100755 index 000000000..f8cdb0014 --- /dev/null +++ b/winclude/transupp.h @@ -0,0 +1,135 @@ +/* + * transupp.h + * + * Copyright (C) 1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains declarations for image transformation routines and + * other utility code used by the jpegtran sample application. These are + * NOT part of the core JPEG library. But we keep these routines separate + * from jpegtran.c to ease the task of maintaining jpegtran-like programs + * that have other user interfaces. + * + * NOTE: all the routines declared here have very specific requirements + * about when they are to be executed during the reading and writing of the + * source and destination files. See the comments in transupp.c, or see + * jpegtran.c for an example of correct usage. + */ + +/* If you happen not to want the image transform support, disable it here */ +#ifndef TRANSFORMS_SUPPORTED +#define TRANSFORMS_SUPPORTED 1 /* 0 disables transform code */ +#endif + +/* Short forms of external names for systems with brain-damaged linkers. */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jtransform_request_workspace jTrRequest +#define jtransform_adjust_parameters jTrAdjust +#define jtransform_execute_transformation jTrExec +#define jcopy_markers_setup jCMrkSetup +#define jcopy_markers_execute jCMrkExec +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* + * Codes for supported types of image transformations. + */ + +typedef enum { + JXFORM_NONE, /* no transformation */ + JXFORM_FLIP_H, /* horizontal flip */ + JXFORM_FLIP_V, /* vertical flip */ + JXFORM_TRANSPOSE, /* transpose across UL-to-LR axis */ + JXFORM_TRANSVERSE, /* transpose across UR-to-LL axis */ + JXFORM_ROT_90, /* 90-degree clockwise rotation */ + JXFORM_ROT_180, /* 180-degree rotation */ + JXFORM_ROT_270 /* 270-degree clockwise (or 90 ccw) */ +} JXFORM_CODE; + +/* + * Although rotating and flipping data expressed as DCT coefficients is not + * hard, there is an asymmetry in the JPEG format specification for images + * whose dimensions aren't multiples of the iMCU size. The right and bottom + * image edges are padded out to the next iMCU boundary with junk data; but + * no padding is possible at the top and left edges. If we were to flip + * the whole image including the pad data, then pad garbage would become + * visible at the top and/or left, and real pixels would disappear into the + * pad margins --- perhaps permanently, since encoders & decoders may not + * bother to preserve DCT blocks that appear to be completely outside the + * nominal image area. So, we have to exclude any partial iMCUs from the + * basic transformation. + * + * Transpose is the only transformation that can handle partial iMCUs at the + * right and bottom edges completely cleanly. flip_h can flip partial iMCUs + * at the bottom, but leaves any partial iMCUs at the right edge untouched. + * Similarly flip_v leaves any partial iMCUs at the bottom edge untouched. + * The other transforms are defined as combinations of these basic transforms + * and process edge blocks in a way that preserves the equivalence. + * + * The "trim" option causes untransformable partial iMCUs to be dropped; + * this is not strictly lossless, but it usually gives the best-looking + * result for odd-size images. Note that when this option is active, + * the expected mathematical equivalences between the transforms may not hold. + * (For example, -rot 270 -trim trims only the bottom edge, but -rot 90 -trim + * followed by -rot 180 -trim trims both edges.) + * + * We also offer a "force to grayscale" option, which simply discards the + * chrominance channels of a YCbCr image. This is lossless in the sense that + * the luminance channel is preserved exactly. It's not the same kind of + * thing as the rotate/flip transformations, but it's convenient to handle it + * as part of this package, mainly because the transformation routines have to + * be aware of the option to know how many components to work on. + */ + +typedef struct { + /* Options: set by caller */ + JXFORM_CODE transform; /* image transform operator */ + jboolean trim; /* if TRUE, trim partial MCUs as needed */ + jboolean force_grayscale; /* if TRUE, convert color image to grayscale */ + + /* Internal workspace: caller should not touch these */ + int num_components; /* # of components in workspace */ + jvirt_barray_ptr * workspace_coef_arrays; /* workspace for transformations */ +} jpeg_transform_info; + + +#if TRANSFORMS_SUPPORTED + +/* Request any required workspace */ +EXTERN(void) jtransform_request_workspace + JPP((j_decompress_ptr srcinfo, jpeg_transform_info *info)); +/* Adjust output image parameters */ +EXTERN(jvirt_barray_ptr *) jtransform_adjust_parameters + JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr *src_coef_arrays, + jpeg_transform_info *info)); +/* Execute the actual transformation, if any */ +EXTERN(void) jtransform_execute_transformation + JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr *src_coef_arrays, + jpeg_transform_info *info)); + +#endif /* TRANSFORMS_SUPPORTED */ + + +/* + * Support for copying optional markers from source to destination file. + */ + +typedef enum { + JCOPYOPT_NONE, /* copy no optional markers */ + JCOPYOPT_COMMENTS, /* copy only comment (COM) markers */ + JCOPYOPT_ALL /* copy all optional markers */ +} JCOPY_OPTION; + +#define JCOPYOPT_DEFAULT JCOPYOPT_COMMENTS /* recommended default */ + +/* Setup decompression object to save desired markers in memory */ +EXTERN(void) jcopy_markers_setup + JPP((j_decompress_ptr srcinfo, JCOPY_OPTION option)); +/* Copy markers saved in the given source object to the destination object */ +EXTERN(void) jcopy_markers_execute + JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + JCOPY_OPTION option)); diff --git a/winclude/trees.h b/winclude/trees.h new file mode 100755 index 000000000..1ca868b84 --- /dev/null +++ b/winclude/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/winclude/zconf.h b/winclude/zconf.h new file mode 100755 index 000000000..f404cefa8 --- /dev/null +++ b/winclude/zconf.h @@ -0,0 +1,279 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef _ZCONF_H +#define _ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateReset z_inflateReset +# define compress z_compress +# define compress2 z_compress2 +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table + +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) +# define WIN32 +#endif +#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) +# ifndef __32BIT__ +# define __32BIT__ +# endif +#endif +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#if defined(MSDOS) && !defined(__32BIT__) +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) +# define STDC +#endif +#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__) +# ifndef STDC +# define STDC +# endif +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Old Borland C incorrectly complains about missing returns: */ +#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500) +# define NEED_DUMMY_RETURN +#endif + + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +#endif +#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) +# ifndef __32BIT__ +# define SMALL_MEDIUM +# define FAR _far +# endif +#endif + +/* Compile with -DZLIB_DLL for Windows DLL support */ +#if defined(ZLIB_DLL) +# if defined(_WINDOWS) || defined(WINDOWS) +# ifdef FAR +# undef FAR +# endif +# include +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR _cdecl _export +# endif +# endif +# if defined (__BORLANDC__) +# if (__BORLANDC__ >= 0x0500) && defined (WIN32) +# include +# define ZEXPORT __declspec(dllexport) WINAPI +# define ZEXPORTRVA __declspec(dllexport) WINAPIV +# else +# if defined (_Windows) && defined (__DLL__) +# define ZEXPORT _export +# define ZEXPORTVA _export +# endif +# endif +# endif +#endif + +#if defined (__BEOS__) +# if defined (ZLIB_DLL) +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +#endif + +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif +#ifndef ZEXTERN +# define ZEXTERN extern +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(MACOS) && !defined(TARGET_OS_MAC) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#ifdef HAVE_UNISTD_H +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(inflate_blocks,"INBL") +# pragma map(inflate_blocks_new,"INBLNE") +# pragma map(inflate_blocks_free,"INBLFR") +# pragma map(inflate_blocks_reset,"INBLRE") +# pragma map(inflate_codes_free,"INCOFR") +# pragma map(inflate_codes,"INCO") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_flush,"INFLU") +# pragma map(inflate_mask,"INMA") +# pragma map(inflate_set_dictionary,"INSEDI2") +# pragma map(inflate_copyright,"INCOPY") +# pragma map(inflate_trees_bits,"INTRBI") +# pragma map(inflate_trees_dynamic,"INTRDY") +# pragma map(inflate_trees_fixed,"INTRFI") +# pragma map(inflate_trees_free,"INTRFR") +#endif + +#endif /* _ZCONF_H */ diff --git a/winclude/zlib.h b/winclude/zlib.h new file mode 100755 index 000000000..5979f040c --- /dev/null +++ b/winclude/zlib.h @@ -0,0 +1,893 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.1.4, March 11th, 2002 + + Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef _ZLIB_H +#define _ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.1.4" + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: ascii or binary */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +/* Allowed flush values; see deflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_ASCII 1 +#define Z_UNKNOWN 2 +/* Possible values of the data_type field */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + the compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + 0.1% larger than avail_in plus 12 bytes. If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may some + introduce some output latency (reading input without producing any output) + except when forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much + output as possible to the output buffer. The flushing behavior of inflate is + not specified for values of the flush parameter other than Z_SYNC_FLUSH + and Z_FINISH, but the current implementation actually flushes as much output + as possible anyway. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster routine + may be used for the single inflate() call. + + If a preset dictionary is needed at this point (see inflateSetDictionary + below), inflate sets strm-adler to the adler32 checksum of the + dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise + it sets strm->adler to the adler32 checksum of all output produced + so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or + an error code as described below. At the end of the stream, inflate() + checks that its computed adler32 checksum is equal to that saved by the + compressor and returns Z_STREAM_END only if the checksum is correct. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect + adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent + (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if no progress is possible or if there was not + enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR + case, the application may then call inflateSync to look for a good + compression block. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match). Filtered data consists mostly of small values with a + somewhat random distribution. In this case, the compression algorithm is + tuned to compress them better. The effect of Z_FILTERED is to force more + Huffman coding and less string matching; it is somewhat intermediate + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects + the compression ratio but not the correctness of the compressed output even + if it is not set appropriately. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. + + Upon return of this function, strm->adler is set to the Adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. If a compressed stream with a larger window size is given as + input, inflate() will return with the error code Z_DATA_ERROR instead of + trying to allocate a larger window. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative + memLevel). msg is set to null if there is no error message. inflateInit2 + does not perform any decompression apart from reading the zlib header if + present: this will be done by inflate(). (So next_in and avail_in may be + modified, but next_out and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler32 value returned by this call of + inflate. The compressor and decompressor must use exactly the same + dictionary (see deflateSetDictionary). + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least 0.1% larger than + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h". (See the description + of deflateInit2 for more information about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + const voidp buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); + +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int err)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* _ZLIB_H */ diff --git a/winclude/zutil.h b/winclude/zutil.h new file mode 100755 index 000000000..2e06fcfd3 --- /dev/null +++ b/winclude/zutil.h @@ -0,0 +1,220 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef _Z_UTIL_H +#define _Z_UTIL_H + +#include "zlib.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#ifdef MSDOS +# define OS_CODE 0x00 +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +#endif + +#ifdef WIN32 /* Window 95 & Windows NT */ +# define OS_CODE 0x0b +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0F +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) +# define fdopen(fd,type) _fdopen(fd,type) +#endif + + + /* Common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#ifdef HAVE_STRERROR + extern char *strerror OF((int)); +# define zstrerror(errnum) strerror(errnum) +#else +# define zstrerror(errnum) "" +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + extern void zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int z_verbose; + extern void z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf, + uInt len)); +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +void zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* _Z_UTIL_H */