pull/4/head
Adeel Abbas 2018-04-09 13:51:33 -07:00
commit a513701afc
365 zmienionych plików z 179674 dodań i 0 usunięć

36
.gitignore vendored 100644
Wyświetl plik

@ -0,0 +1,36 @@
.DS_Store
build/
scripts/*.pyc
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app

9
AUTHORS.md 100644
Wyświetl plik

@ -0,0 +1,9 @@
# GPR Authors List
##### Please add entries to the bottom of the list in the following format
* `@GitHub UserName (Required) - [Name and/or Organization](link)`
# Authors
* @aabbas-gpfw - [GoPro, Inc.](https://github.com/GoPro/gpr)
* @dnewman-gpsw - [GoPro, Inc.](https://github.com/GoPro/gpr)

71
CMakeLists.txt 100644
Wyświetl plik

@ -0,0 +1,71 @@
# minimum required cmake version
cmake_minimum_required( VERSION 3.5 FATAL_ERROR )
set(CMAKE_SUPPRESS_REGENERATION true)
set(CMAKE_C_FLAGS "-std=c99")
# project name
project( gpr )
if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
execute_process(
COMMAND git rev-parse --abbrev-ref HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_BRANCH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND git log -1 --format=%h
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_COMMIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
else(EXISTS "${CMAKE_SOURCE_DIR}/.git")
set(GIT_BRANCH "")
set(GIT_COMMIT_HASH "")
endif(EXISTS "${CMAKE_SOURCE_DIR}/.git")
message(STATUS "Git current branch: ${GIT_BRANCH}")
message(STATUS "Git commit hash: ${GIT_COMMIT_HASH}")
add_definitions("-DGIT_COMMIT_HASH=\"${GIT_COMMIT_HASH}\"")
add_definitions("-DGIT_BRANCH=\"${GIT_BRANCH}\"")
# add needed subdirectories
add_subdirectory( "source/lib/common" )
add_subdirectory( "source/lib/vc5_common" )
if(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_decoder")
MESSAGE( STATUS "Found source/lib/vc5_decoder - enabling vc5 decoder and setting GPR_READING=1" )
add_subdirectory( "source/lib/vc5_decoder" )
add_subdirectory( "source/app/vc5_decoder_app" )
else(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_decoder")
MESSAGE( STATUS "Could not find source/lib/vc5_decoder - disabling vc5 decoder and setting GPR_READING=0" )
endif(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_decoder")
if(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_encoder")
MESSAGE( STATUS "Found source/lib/vc5_encoder - enabling vc5 encoder and setting GPR_WRITING=1" )
add_subdirectory( "source/lib/vc5_encoder" )
add_subdirectory( "source/app/vc5_encoder_app" )
else(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_encoder")
MESSAGE( STATUS "Could not find source/lib/vc5_encoder - disabling vc5 encoder and setting GPR_WRITING=0" )
endif(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_encoder")
add_subdirectory( "source/lib/dng_sdk" )
add_subdirectory( "source/lib/gpr_sdk" )
add_subdirectory( "source/lib/xmp_core" )
add_subdirectory( "source/lib/expat_lib" )
add_subdirectory( "source/lib/md5_lib" )
if(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/tiny_jpeg")
MESSAGE( STATUS "Found source/lib/tiny_jpeg - enabling jpeg writing and setting GPR_JPEG_AVAILABLE=1" )
add_subdirectory( "source/lib/tiny_jpeg" )
else(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/tiny_jpeg")
MESSAGE( STATUS "Could not find source/lib/tiny_jpeg - disabling jpeg writing and setting GPR_JPEG_AVAILABLE=0" )
endif(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/tiny_jpeg")
add_subdirectory( "source/app/common/cJSON" )
add_subdirectory( "source/app/common/argument_parser" )
add_subdirectory( "source/app/gpr_tools" )

31
CONTRIBUTING.md 100644
Wyświetl plik

@ -0,0 +1,31 @@
# How to Contribute
Want to contribute to GPR? Please take a moment to review this document in order to make your contribution and the process around it easier and more effective for everyone.
## Issue tracker
The [issue tracker](https://www.github.com/gopro/gpr/issues) is the best place to report a bug. Please make sure to check the following guide on how to use the issue tracker :
### Reporting a bug
- If you really think it is a bug, consult the list of issues and make sure nobody has reported it yet. This will avoid duplication of effort.
- If it hasn't been reported yet, submit a new issue.
### Suggesting a feature
- Consult the roadmap within [projects](https://github.com/gopro/gpr/projects) to know if it is planned.
- Consult the list of things that **won't** be implemented.
- Read up on what type of feature requests are accepted.
- See if anybody has not requested the feature yet.
- If it hasn't beed requested yet, submit a new request as an issue.
### Submitting a pull-request
- All contributors must sign a [contributor license agreement (CLA)](https://cla.gopro.com). Your code will not be reviewed and accepted by the Admins until this has been received.
- To be sure your changes could be interesting and accepted, ask about your patch on Discourse.
- Fork the repository and work on the `master` branch, while respecting the imposed guidelines.
- Add tests if needed, and make sure that all of them pass.
- Document the code according to the guidelines, and make sure the build is OK. If you encounter some problem with the Closure Compiler part, don't hesitate to ask.
- Submit a pull request for your changes.
- The Admins will review your work and may optionally request conformance, functional or other changes. Work with them to resolve any issues.
- Upon acceptance, your code will be added to the main branch and available for all.

201
LICENSE-APACHE 100644
Wyświetl plik

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2018 GoPro, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

19
LICENSE-MIT 100644
Wyświetl plik

@ -0,0 +1,19 @@
Copyright 2018 GoPro, Inc.
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.

228
LICENSE.txt 100644
Wyświetl plik

@ -0,0 +1,228 @@
Apache License 2.0 or MIT
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2018 GoPro, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
OR
Copyright 2018 GoPro, Inc.
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.

305
README.md 100755
Wyświetl plik

@ -0,0 +1,305 @@
# GPR Introduction
The General Purpose Raw (GPR) is 12-bit raw image coding format that is based on [Adobe DNG®](https://helpx.adobe.com/photoshop/digital-negative.html) standard. Image compression is a balance of speed, file size and photo quality, and typically one can only choose two. GPR was designed to provide a better tradeoff for all three parameters than what's possible with DNG or any other raw format. The intention of GPR is not to compete with DNG, rather to be as close as possible to DNG. This guarantees compatibility with applications that already understand DNG, but provide an alternate compression scheme in situations where compression and encoding/decoding speed matter.
Action cameras, like that from GoPro, have limited computing resources, so ability to compress data using fewest CPU cycles matters. File sizes matter because GoPro cameras can record thousands of images very quickly using timelapse and burst mode features. As the world shifts from desktop to mobile, people now shoot and process more and more photos on smartphones which are always limited on storage space and bandwidth. And last but not the least, image quality matters because we want GPR to provide visually transparent image quality when compared to uncompressed DNG. All this combined enables customers to capture DSLR-class image quality in a GPR file that has nearly same size as JPEG, on a camera that is as small and rugged as a GoPro.
DNG allows storage of RAW sensor data in three main formats: uncompressed, lossless JPEG or lossy JPEG. Lossless mode typically achieves 2:1 compression that is clearly not enough in the mobile-first age. Lossy mode uses the 8x8 DCT transform that was developed for JPEG more than 25 years ago (when photo resolutions were much smaller), achieving compression ratios around 4:1. In comparison, GPR achieves typical compression ratios between 10:1 and 4:1. This is due to Full-Frame Wavelet Transform (FFWT). FFWT has a few nice properties compared to DCT:
- The compression performance increases as image resolutions go up - making it more future proof
- Better image quality as it does not suffer from ringing or blocky artifacts observed in JPEG files.
The wavelet codec in GPR is not new, but has been a SMPTE® standard under the name [VC-5](https://kws.smpte.org/higherlogic/ws/public/projects/15/details). VC-5 shares a lot of technical barebones with the [CineForm®](https://gopro.github.io/cineform-sdk/), an open and cross-platform intermediate codec designed for high-resolution video editing.
## File Types
Following file types are discussed in this document:
* `RAW or CFA RAW` - The Bayer RAW format is typically composed of 50% green, 25% red and 25% blue samples captured from sensor, e.g. RGGB and GBRG. The RAW image doesn't directly carry metadata about image development e.g. exposure, white balance or noise etc, thus cannot easily be turned into a well developed image.
* `DNG` - Widely regarded as a defacto standard, a DNG file can be opened natively on most operating systems and image development tools. As mentioned earlier, DNG stores compressed or uncompressed RAW sensor data along with accompanying metadata that is needed to properly develop image.
* `GPR` - General purpose RAW format file. GoPro cameras including Hero5/6 and Fusion record photos in this format. GPR is an extension of DNG, enabling high performance VC-5 compression for faster storage and smaller files without impacting image quality. Today, GPR files can be opened in Adobe products like Camera Raw®, Photoshop® and Lightroom®.
* `VC5` - A file with VC5 extension stores RAW sensor image data in a compressed format that is compatible with VC-5. Similar to RAW file, VC5 file does not store metadata needed for proper image development.
* `PPM` - [Portable Pixel Map](http://netpbm.sourceforge.net/doc/ppm.html) is one of the simplest storage formats of uncompressed debayered RGB image. It is very easy to write and analyze programs to process this format, and that is why it is used here.
* `JPG or JPEG` One of the simplest formats for lossy compression of debayered RGB image.
# Included Within This Repository
* The complete source of GPR-SDK, a library that implements conversion of RAW, DNG, GPR, PPM or JPG formats. GPR-SDK has C-99 interface for maximum portability, yet is implemented in C/C++ for programming effectiveness.
* Source of VC-5 encoder and decoder library. Encoder is hand-optimized with NEON intrinsics for ARM processors.
* `gpr_tools` - a sample demo code that uses GPR-SDK to convert between GPR, DNG and RAW formats.
* `vc5_encoder_app` - a sample VC5 encoder application that encodes a RAW frame to VC5 file.
* `vc5_decoder_app` - a sample VC5 decoder application that decodes VC5 file to RAW file.
* CMake support for building all projects.
* Tested on:
- macOS High Sierra with XCode v8 & v9, El Capitan with XCode v8
- Windows 10 with Visual Studio 2015 & 2017
- Ubuntu 16.04 with gcc v5.4
# License Terms
GPR is licensed under either:
* Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
## Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
# Quick Start for Developers
## Setup Source Code
Clone the project from Github (`git clone https://github.com/gopro/gpr`). You will need [CMake](https://cmake.org/download/) version 3.5.1 or better to compile source code.
### Compiling Source Code
Run following commands:
```
$ mkdir build
$ cd build
$ cmake ../
```
For Xcode, use command line switch `-G Xcode`. On Windows, CMake should automatically figure out installed version of Visual Studio and generate corresponding project files.
## Using gpr_tools
Some example commands are shown below:
Convert GPR to DNG:
```
$ gpr_tools -i INPUT.GPR -o OUTPUT.DNG
```
Extract RAW from GPR:
```
$ gpr_tools -i INPUT.GPR -o OUTPUT.RAW
```
Convert DNG to GPR:
```
$ gpr_tools -i INPUT.DNG -o OUTPUT.GPR
```
Analyze a GPR (or even DNG) and output parameters that define DNG metadata to a file:
```
$ gpr_tools -i INPUT.GPR -d 1 > PARAMETERS.TXT
```
Read RAW pixel data, along with parameters that define DNG metadata and apply to an output GPR (or DNG) file:
```
$ gpr_tools -i INPUT.RAW -o OUTPUT.DNG -a PARAMETERS.TXT
```
Read GPR file and output PPM preview:
```
$ gpr_tools -i INPUT.GPR -o OUTPUT.PPM
```
Read GPR file and output JPG preview:
```
$ gpr_tools -i INPUT.GPR -o OUTPUT.JPG
```
For a complete list of commands, please refer to data/tests/run_tests.sh
## Using vc5_encoder_app
vc5_encoder_app is an optional tool that can be used to convert RAW image data to VC5 essence, as shown below:
```
$ vc5_encoder_app -i INPUT.RAW -o OUTPUT.VC5 -w 4000 -h 3000 -p 8000
```
## Using vc5_decoder_app
vc5_decoder_app is an optional tool that can be used to decode VC5 essence into RAW image data, as shown below:
```
$ vc5_decoder_app -i INPUT.VC5 -o OUTPUT.RAW
```
## Source code organization
### Folder structure
Source code is organized inside `source` folder. All library and sdk code is located in `lib` folder, while all tools and applications that use `lib` are located in `app` folder.
The ``` lib``` folder is made up of following folders:
- `common` - common source code that is accessable to all libraries and applications
- `dng_sdk` - mostly borrowed from [Adobe DNG SDK](https://www.adobe.com/support/downloads/dng/dng_sdk.html) version 1.4.
- `xmp_core` - [Extensible Metadata Platform](https://en.wikipedia.org/wiki/Extensible_Metadata_Platform), mostly borrowed from Adobe DNG SDK version 1.4
- `expat_lib` - A stream-oriented XML parser borrowed from Adobe DNG SDK version 1.4
- `vc5_decoder` - vc5 decoder. If this is not present, cmake won't use it (and define `GPR_READING=0`); otherwise cmake uses it (and defines `GPR_READING=1`).
- `vc5_encoder` - vc5 encoder. If this is not present, cmake won't use it (and define `GPR_WRITING=0`); otherwise cmake uses it (and defines `GPR_WRITING=1`).
- `vc5_common` - common source code that is shared between vc5_encoder and vc5_decoder
- `md5_lib` - md5 checksum calculation library
- `tiny_jpeg` - lightweight jpeg encoder available [here](https://github.com/serge-rgb/TinyJPEG). If this folder is not present, cmake will not use it (and define `GPR_JPEG_AVAILABLE=0`); otherwise cmake defines `GPR_JPEG_AVAILABLE=1` and uses it.
- `gpr_sdk` - uses all modules above to read/write GPR files.
The `app` folder is made up of following folders:
- `common` - common application level source code that is accessable to sample applications
- `vc5_decoder_app` - sample vc5 decoder application
- `vc5_encoder_app` - sample vc5 encoder application
- `gpr_tools` - utility to convert to/from various formats mentioned above and measure runtime
### Important Defines
Here are some important compile time definitions:
* ```GPR_TIMING``` enables timing code that prints out time spent (in milliseconds) in different functions. In production builds, applications should define ```TIMING=0```. Set to a higher value to output greater timing information.
* ```GPR_WRITING``` enables all code that writes GPR files. If application does not need to write GPR, set ```GPR_WRITING=0``` to reduce code size.
* ```GPR_READING``` enables all code that reads GPR files. If application does not need to read GPR, set ```GPR_READING=0``` to reduce code size.
* ```GPR_JPEG_AVAILABLE``` enables lightweight jpeg encoder located in `source/lib/tiny_jpeg`. This is used to write a small thumbnail inside GPR file. If ```GPR_JPEG_AVAILABLE=0```, thumnail is not written, although you can still set pre-encoded jpeg file as thumbnail, by using -P, -W and -H command line options in `gpr_tools`.
* ```NEON``` enables arm neon intrinsics (disabled by default). This can be enabled from CMake by ```-DNEON=1``` switch.
### GPR-SDK API
GPR-SDK API is defined in header files in the following folders:
- source/lib/common/public
- source/lib/gpr_sdk/public
An application needs to include above two folders in order to access API. API defines various functions named ```gpr_convert_XXX_to_XXX``` which convert from one format to another. As an example, GPR to DNG conversion is done from ```gpr_convert_gpr_to_dng```. When output file is GPR or DNR, ```gpr_parameters``` structure has to be specified. Fields in this structure map to DNG metadata tags, and we have tried to abstract low-level DNG details in a very clean and easy to use structure.
# Compression Technology
## Wavelet Transforms
The wavelet used within VC-5 is a 2D three-level 2-6 Wavelet. If you look up wavelets on Wikipedia, prepare to get confused fast. Wavelet compression of images is fairly simple if you don't get distracted by the theory. The wavelet is a one dimensional filter that separates low frequency data from high frequency data, and the math is simple. For each two pixels in an image simply add them (low frequency):
* low frequency sample = pixel[x] + pixel[x+1]
- two inputs, is the '2' part of 2-6 Wavelet.
For high frequency it can be as simple as the difference of the same two pixels:
* high frequency sample = pixel[x] - pixel[x+1]
- this would be a 2-2 Wavelet, also called a [HAAR wavelet](https://en.wikipedia.org/wiki/Haar_wavelet).
For a 2-6 wavelet this math is for the high frequency:
* high frequency sample = pixel[x] - pixel[x+1] + (-pixel[x-2] - pixel[x-1] + pixel[x+2] + pixel[x+3])/8
- i.e 6 inputs for the high frequency, the '6' part of 2-6 Wavelet.
The math doesn't get much more complex than that.
To wavelet compress a monochrome frame (color can be compressed as separate monochrome channels), we start with a 2D array of pixels (a.k.a image.)
![](data/readmegfx/source-640.png "Source image")
If you store data with low frequencies (low pass) on the left and the high frequencies (high pass) on the right you get the image below. A low pass image is basically the average, and high pass image is like an edge enhance.
![](data/readmegfx/level1D-640.png "1D Wavelet")
You repeat the same operation vertically using the previous output as the input image.
Resulting in a 1 level 2D wavelet:
![](data/readmegfx/level1-640.png "1D Wavelet")
For a two level wavelet, you repeat the same horizontal and vertical wavelet operations of the top left quadrant to provide:
![](data/readmegfx/level2-640.png "2 Level 2D-Wavelet")
Repeating again for the third level.
![](data/readmegfx/level3-640.png "3 Level 2D-Wavelet")
## Quantization
All that grey is easy to compress. The reason there is very little information in these high frequency regions is that the high frequency data of the image has been quantized. The human eye is not very good at seeing subtle changes in high frequency regions, so this is exploited by scaling the high-frequency samples before they are stored:
* high frequency sample = (wavelet output) / quantizer
## Entropy Coding
After the wavelet and quantization stages, you have the same number of samples as the original source. The compression is achieved as the samples are no longer evenly distributed (after wavelet and quantization.) There are many many zeros and ones, than higher values, so we can store all these values more efficiently, often up to 10 times more so.
### Run length
The output of the quantization stage has a lot of zeros, and many in a row. Additional compression is achieved by counting runs of zeros, and storing them like: a "z15" for 15 zeros, rather than "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
### Variable length coding
After all previous steps, the high frequency samples are stored with a variable length coding scheme using [Huffman coding](https://en.wikipedia.org/wiki/Huffman_coding). A table then maps sample values to codewords with differing bit lengths where most common codewords are expressed in few bits and rare codewords are expressed in larger bits.
The lack of complexity is what makes VC-5 fast. Low pass filter is just addition. High pass filter is 6 tap where all coefficients are rational numbers and no multiplication or division is required. Variable length coding can be implemented with a lookup table, an approach that is faster than other entropy coding techniques.
## To Decode
Reverse all the steps.
# Thumbnail and Preview Generation
A nice property of the Wavelet codec is scalability support: i.e. various resolutions ranging from original coded resolution to one-sixteenth resolution are encoded and can be retrieved efficiently. Scalability means that extracting lowest resolution is fastest and cost of extracting resolutions increases as resolution goes up. For application scenarios where rendering a smaller resolution suffices, a decoder can very cheaply extract lower resolution. Common examples of this use case are thumbnail previews in file browsers or rendering image on devices with smaller resolution e.g. mobile phones.
Scalability is more efficient than decoding full resolution image, performing demosaicing and downsampling. To avoid demosaic, DNG allows mechanism to store a separate thumbnail and preview image (often encoded in JPG). File browers use thumbnail, while preview is useful for rendering higher resolution version of image. Since these are separately enoded images and do not exploit compression amongst each other or with original RAW image, file sizes add up quickly.
As an example, GoPro Hero6 Black captures 4000x3000 RAW image in Bayer RGGB format. Red, blue and two green channels are split up and separately encoded into wavelet resolutions of 2000x1500 (or 2:1), 1000x750 (or 4:1), 500x375 (or 8:1). The Low-Low band of lowest resolution wavelet is a 250x188 (or 16:1) image, and it is stored uncompressed (generating thumbnail is essentially a memory copy). RGB images at other resolutions can be obtained at successive complexity levels, without performing demosaicing. To illustrate this, decoding speed of various resolutions is measured and shown using `gpr_tools` (in milliseconds inside square brackets).
```
Decode GPR to 8-bit PPM (250x188)
[ 6-ms] [BEG] gpr_convert_gpr_to_rgb() gpr.cpp (line 1695)
[ 16-ms] [END] gpr_convert_gpr_to_rgb() gpr.cpp (line 1738)
```
```
Decode GPR to 8-bit PPM (500x375)
[ 6-ms] [BEG] gpr_convert_gpr_to_rgb() gpr.cpp (line 1695)
[ 37-ms] [END] gpr_convert_gpr_to_rgb() gpr.cpp (line 1738)
```
```
Decode GPR to 8-bit PPM (1000x750)
[ 5-ms] [BEG] gpr_convert_gpr_to_rgb() gpr.cpp (line 1695)
[ 130-ms] [END] gpr_convert_gpr_to_rgb() gpr.cpp (line 1738)
```
```
Decode GPR to 8-bit PPM (2000x1500)
[ 5-ms] [BEG] gpr_convert_gpr_to_rgb() gpr.cpp (line 1695)
[ 357-ms] [END] gpr_convert_gpr_to_rgb() gpr.cpp (line 1738)
```
And here is the output of full GPR to DNG decoding.
```
Decode GPR to DNG
[ 6-ms] [BEG] gpr_convert_gpr_to_dng() gpr.cpp (line 1748)
[ 422-ms] [END] gpr_convert_gpr_to_dng() gpr.cpp (line 1768)
```
To summarize, here are speed gain factors over full resolution DNG decoding:
| Resolution | 250x188 | 500x375 | 1000x750 | 2000x1500
| :---: | :---: | :---: | :---: | :---:
| Speed factor | 41.6x | 13.4x | 3.3x | 1.2x
Demosaicing has a higher complexity than GPR decoding, so numbers for RGB output after demosaic will be higher. Similar speed improvements can also be seen when writing JPG file.
```
GoPro and CineForm are trademarks of GoPro, Inc.
DNG, Photoshop and Lightroom is trademarks of Adobe Inc.
```

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 132 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 190 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 61 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 56 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 144 KiB

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -0,0 +1,89 @@
#!/bin/sh
GPR_TOOLS=$1
# cp ../../xcode/source/app/gpr_tools/Release/gpr_tools .
# Start with one GPR file
rm *.GPR
rm *.DNG
rm *.PPM
rm *.JPG
rm -rf JPB
rm -rf PPM
rm -rf DNG
rm -rf GPR
rm -rf RAW
echo
echo Dump GPR parameters to a file
$GPR_TOOLS -i ../samples/Hero6/GOPR0024.GPR -d 1 > GOPR0024.TXT
mkdir PPM
echo
echo Decode "GPR to 8-bit PPM (250x188)"
$GPR_TOOLS -i ../samples/Hero6/GOPR0024.GPR -o PPM/GOPR0024-250x188-8-bit.PPM -r 16:1
echo
echo Decode "GPR to 8-bit PPM (500x375)"
$GPR_TOOLS -i ../samples/Hero6/GOPR0024.GPR -o PPM/GOPR0024-500x375-8-bit.PPM -r 8:1
echo
echo Decode "GPR to 8-bit PPM (1000x750)"
$GPR_TOOLS -i ../samples/Hero6/GOPR0024.GPR -o PPM/GOPR0024-1000x750-8-bit.PPM -r 4:1
echo
echo "Decode GPR to 8-bit PPM (2000x1500)"
$GPR_TOOLS -i ../samples/Hero6/GOPR0024.GPR -o PPM/GOPR0024-2000x1500-8-bit.PPM -r 2:1
echo
echo Decode "GPR to 16-bit PPM (250x188)"
$GPR_TOOLS -i ../samples/Hero6/GOPR0024.GPR -o PPM/GOPR0024-250x188-16-bit.PPM -r 16:1 -b 16
echo
echo Decode "GPR to 16-bit PPM (500x375)"
$GPR_TOOLS -i ../samples/Hero6/GOPR0024.GPR -o PPM/GOPR0024-500x375-16-bit.PPM -r 8:1 -b 16
echo
echo Decode "GPR to 16-bit PPM (1000x750)"
$GPR_TOOLS -i ../samples/Hero6/GOPR0024.GPR -o PPM/GOPR0024-1000x750-16-bit.PPM -r 4:1 -b 16
echo
echo "Decode GPR to 16-bit PPM (2000x1500)"
$GPR_TOOLS -i ../samples/Hero6/GOPR0024.GPR -o PPM/GOPR0024-2000x1500-16-bit.PPM -r 2:1 -b 16
mkdir JPG
echo
echo Decode "GPR to JPG (250x188)"
$GPR_TOOLS -i ../samples/Hero6/GOPR0024.GPR -o JPG/GOPR0024-250x188.JPG -r 16:1
echo
echo Decode "GPR to JPG (500x375)"
$GPR_TOOLS -i ../samples/Hero6/GOPR0024.GPR -o JPG/GOPR0024-500x375.JPG -r 8:1
echo
echo Decode "GPR to JPG (1000x750)"
$GPR_TOOLS -i ../samples/Hero6/GOPR0024.GPR -o JPG/GOPR0024-1000x750.JPG -r 4:1
echo
echo Decode "GPR to JPG (2000x1500)"
$GPR_TOOLS -i ../samples/Hero6/GOPR0024.GPR -o JPG/GOPR0024-2000x1500.JPG -r 2:1
mkdir RAW
echo
echo Decode GPR to RAW
$GPR_TOOLS -i ../samples/Hero6/GOPR0024.GPR -o RAW/GOPR0024.RAW
mkdir DNG
echo
echo Decode GPR to DNG
$GPR_TOOLS -i ../samples/Hero6/GOPR0024.GPR -o DNG/GOPR0024.DNG
echo
echo Encode RAW to DNG
$GPR_TOOLS -i RAW/GOPR0024.RAW -o DNG/GOPR0024-FROM-RAW.DNG -a GOPR0024.TXT
mkdir GPR
echo
echo Encode DNG to GPR and using thumbnail from JPG file that was previously written
$GPR_TOOLS -i DNG/GOPR0024.DNG -o GPR/GOPR0024-PREVIEW-250x188.GPR -P JPG/GOPR0024-250x188.JPG -H 188 -W 250
$GPR_TOOLS -i DNG/GOPR0024.DNG -o GPR/GOPR0024-PREVIEW-500x375.GPR -P JPG/GOPR0024-500x375.JPG -H 375 -W 500
$GPR_TOOLS -i DNG/GOPR0024.DNG -o GPR/GOPR0024-PREVIEW-1000x750.GPR -P JPG/GOPR0024-1000x750.JPG -H 750 -W 1000
$GPR_TOOLS -i DNG/GOPR0024.DNG -o GPR/GOPR0024-PREVIEW-2000x1500.GPR -P JPG/GOPR0024-2000x1500.JPG -H 750 -W 1000
echo
echo Encode RAW to GPR
$GPR_TOOLS -i RAW/GOPR0024.RAW -o GPR/GOPR0024-FROM-RAW.GPR -a GOPR0024.TXT

Wyświetl plik

@ -0,0 +1,16 @@
# library
set( LIB_NAME argument_parser )
# get source files
file( GLOB SRC_FILES "*.c" "*.cpp" )
# get include files
file( GLOB INC_FILES "*.h" )
# library
add_library( ${LIB_NAME} STATIC ${SRC_FILES} ${INC_FILES} )
target_link_libraries( ${LIB_NAME} )
# set the folder where to place the projects
set_target_properties( ${LIB_NAME} PROPERTIES FOLDER lib )

Wyświetl plik

@ -0,0 +1,126 @@
/*! @file argument_parser.cpp
*
* @brief Implement class to handle argument parsing
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "argument_parser.h"
#include <stdio.h>
using namespace std;
#ifdef __GNUC__
#define COMPILER "[GCC %d.%d.%d]", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__
#elif __INTEL_COMPILER
#define COMPILER "[ICC %d]", __INTEL_COMPILER
#elif _MSC_VER
#define COMPILER "[VS %d]", _MSC_VER
#else
#define COMPILER "[Unknown-CXX]"
#endif
#ifdef _WIN32
#define OPERATING_SYSTEM "[Windows]"
#elif __linux
#define OPERATING_SYSTEM "[Linux]"
#elif __CYGWIN__
#define OPERATING_SYSTEM "[Cygwin]"
#elif __APPLE__
#define OPERATING_SYSTEM "[Mac OS X]"
#else
#define OPERATING_SYSTEM "[Unknown-OS]"
#endif
#define NUMBER_OF_BITS "[%d bit] ", (sizeof(void*) == 8 ? 64 : 32) ///< used for checking 64-bit O/S
argument_parser::argument_parser(bool verbose)
{
}
void argument_parser::set_options()
{
}
int argument_parser::parse(int argc, char *argv [], const char* application_text, const char* prefix_text)
{
application_path = argv[0];
argument_count = argc;
for (int i = 0; i < argc; i++)
arguments[i] = argv[i];
set_options();
program_options_lite::setDefaults(command_options);
const list<const char*>& argv_unhandled = program_options_lite::scanArgv(command_options, argument_count, (const char**) arguments);
for (list<const char*>::const_iterator it = argv_unhandled.begin(); it != argv_unhandled.end(); it++)
{
fprintf(stderr, "Unhandled argument ignored: `%s'\n", *it);
}
bool show_help = get_argument_count() == 1 || get_help();
if( get_verbose() || show_help )
{
if( application_text )
{
fprintf( stderr, "%s", application_text );
fprintf( stderr, OPERATING_SYSTEM );
fprintf( stderr, COMPILER );
fprintf( stderr, NUMBER_OF_BITS );
fprintf( stderr, "\n" );
}
printf("Executable: %s \n", get_application_path() );
printf("Arguments: ");
for (int i = 1; i < get_argument_count(); i++)
{
printf("%s ", get_argument(i));
}
printf("\n");
}
if ( show_help )
{
print_help();
return -1;
}
if( application_text )
{
if( prefix_text )
fprintf( stderr, "%s %s", prefix_text, application_text );
else
fprintf( stderr, "%s", application_text );
fprintf( stderr, OPERATING_SYSTEM );
fprintf( stderr, COMPILER );
fprintf( stderr, NUMBER_OF_BITS );
fprintf( stderr, "\n" );
}
return 0;
}
void argument_parser::print_help()
{
doHelp(cout, command_options);
}

Wyświetl plik

@ -0,0 +1,51 @@
/*! @file argument_parser.h
*
* @brief Declare class to handle argument parsing
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define MAX_ARGC 100
#include "program_options_lite.h"
class argument_parser
{
private:
char* application_path;
int argument_count;
char* arguments[MAX_ARGC];
protected:
program_options_lite::Options command_options;
public:
argument_parser(bool verbose = true);
const int get_argument_count() { return argument_count; }
const char* get_argument(int index) { return arguments[index]; }
const char* get_application_path() { return application_path; }
virtual int parse(int argc, char *argv [], const char* application_text = NULL, const char* prefix_text = NULL );
virtual void set_options();
virtual void print_help();
virtual bool get_verbose() { return false; }
virtual bool get_help() { return false; }
};

Wyświetl plik

@ -0,0 +1,491 @@
/* The copyright in this software is being made available under the BSD
* License, included below. This software may be subject to other third party
* and contributor rights, including patent rights, and no such rights are
* granted under this license.
*
* Copyright (c) 2010-2015, ITU/ISO/IEC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <list>
#include <map>
#include <algorithm>
#include "program_options_lite.h"
using namespace std;
namespace program_options_lite
{
Options::~Options()
{
for(Options::NamesPtrList::iterator it = opt_list.begin(); it != opt_list.end(); it++)
{
delete *it;
}
}
void Options::addOption(OptionBase *opt)
{
Names* names = new Names();
names->opt = opt;
string& opt_string = opt->opt_string;
size_t opt_start = 0;
for (size_t opt_end = 0; opt_end != string::npos;)
{
opt_end = opt_string.find_first_of(',', opt_start);
bool force_short = 0;
if (opt_string[opt_start] == '-')
{
opt_start++;
force_short = 1;
}
string opt_name = opt_string.substr(opt_start, opt_end - opt_start);
if (force_short || opt_name.size() == 1)
{
names->opt_short.push_back(opt_name);
opt_short_map[opt_name].push_back(names);
}
else
{
names->opt_long.push_back(opt_name);
opt_long_map[opt_name].push_back(names);
}
opt_start += opt_end + 1;
}
opt_list.push_back(names);
}
/* Helper method to initiate adding options to Options */
OptionSpecific Options::addOptions()
{
return OptionSpecific(*this);
}
static void setOptions(Options::NamesPtrList& opt_list, const string& value)
{
/* multiple options may be registered for the same name:
* allow each to parse value */
for (Options::NamesPtrList::iterator it = opt_list.begin(); it != opt_list.end(); ++it)
{
(*it)->opt->parse(value);
}
}
static const char spaces[41] = " ";
/* format help text for a single option:
* using the formatting: "-x, --long",
* if a short/long option isn't specified, it is not printed
*/
static void doHelpOpt(ostream& out, const Options::Names& entry, unsigned pad_short = 0)
{
pad_short = min(pad_short, 8u);
if (!entry.opt_short.empty())
{
unsigned pad = max((int)pad_short - (int)entry.opt_short.front().size(), 0);
out << "-" << entry.opt_short.front();
if (!entry.opt_long.empty())
{
out << ", ";
}
out << &(spaces[40 - pad]);
}
else
{
out << " ";
out << &(spaces[40 - pad_short]);
}
if (!entry.opt_long.empty())
{
out << "--" << entry.opt_long.front();
}
}
/* format the help text */
void doHelp(ostream& out, Options& opts, unsigned columns)
{
const unsigned pad_short = 3;
/* first pass: work out the longest option name */
unsigned max_width = 0;
for(Options::NamesPtrList::iterator it = opts.opt_list.begin(); it != opts.opt_list.end(); it++)
{
ostringstream line(ios_base::out);
doHelpOpt(line, **it, pad_short);
max_width = max(max_width, (unsigned) line.tellp());
}
unsigned opt_width = min(max_width+2, 28u + pad_short) + 2;
unsigned desc_width = columns - opt_width;
/* second pass: write out formatted option and help text.
* - align start of help text to start at opt_width
* - if the option text is longer than opt_width, place the help
* text at opt_width on the next line.
*/
for(Options::NamesPtrList::iterator it = opts.opt_list.begin(); it != opts.opt_list.end(); it++)
{
ostringstream line(ios_base::out);
line << " ";
doHelpOpt(line, **it, pad_short);
const string& opt_desc = (*it)->opt->opt_desc;
if (opt_desc.empty())
{
/* no help text: output option, skip further processing */
cout << line.str() << endl;
continue;
}
size_t currlength = size_t(line.tellp());
if (currlength > opt_width)
{
/* if option text is too long (and would collide with the
* help text, split onto next line */
line << endl;
currlength = 0;
}
/* split up the help text, taking into account new lines,
* (add opt_width of padding to each new line) */
for (size_t newline_pos = 0, cur_pos = 0; cur_pos != string::npos; currlength = 0)
{
/* print any required padding space for vertical alignment */
line << &(spaces[40 - opt_width + currlength]);
newline_pos = opt_desc.find_first_of('\n', newline_pos);
if (newline_pos != string::npos)
{
/* newline found, print substring (newline needn't be stripped) */
newline_pos++;
line << opt_desc.substr(cur_pos, newline_pos - cur_pos);
cur_pos = newline_pos;
continue;
}
if (cur_pos + desc_width > opt_desc.size())
{
/* no need to wrap text, remainder is less than avaliable width */
line << opt_desc.substr(cur_pos);
break;
}
/* find a suitable point to split text (avoid spliting in middle of word) */
size_t split_pos = opt_desc.find_last_of(' ', cur_pos + desc_width);
if (split_pos != string::npos)
{
/* eat up multiple space characters */
split_pos = opt_desc.find_last_not_of(' ', split_pos) + 1;
}
/* bad split if no suitable space to split at. fall back to width */
bool bad_split = split_pos == string::npos || split_pos <= cur_pos;
if (bad_split)
{
split_pos = cur_pos + desc_width;
}
line << opt_desc.substr(cur_pos, split_pos - cur_pos);
/* eat up any space for the start of the next line */
if (!bad_split)
{
split_pos = opt_desc.find_first_not_of(' ', split_pos);
}
cur_pos = newline_pos = split_pos;
if (cur_pos >= opt_desc.size())
{
break;
}
line << endl;
}
cout << line.str() << endl;
}
}
bool storePair(Options& opts, bool allow_long, bool allow_short, const string& name, const string& value)
{
bool found = false;
Options::NamesMap::iterator opt_it;
if (allow_long)
{
opt_it = opts.opt_long_map.find(name);
if (opt_it != opts.opt_long_map.end())
{
found = true;
}
}
/* check for the short list */
if (allow_short && !(found && allow_long))
{
opt_it = opts.opt_short_map.find(name);
if (opt_it != opts.opt_short_map.end())
{
found = true;
}
}
if (!found)
{
/* not found */
cerr << "Unknown option: `" << name << "' (value:`" << value << "')" << endl;
return false;
}
setOptions((*opt_it).second, value);
return true;
}
bool storePair(Options& opts, const string& name, const string& value)
{
return storePair(opts, true, true, name, value);
}
/**
* returns number of extra arguments consumed
*/
unsigned parseGNU(Options& opts, unsigned argc, const char* argv[])
{
/* gnu style long options can take the forms:
* --option=arg
* --option arg
*/
string arg(argv[0]);
size_t arg_opt_start = arg.find_first_not_of('-');
size_t arg_opt_sep = arg.find_first_of('=');
string option = arg.substr(arg_opt_start, arg_opt_sep - arg_opt_start);
unsigned extra_argc_consumed = 0;
if (arg_opt_sep == string::npos)
{
/* no argument found => argument in argv[1] (maybe) */
/* xxx, need to handle case where option isn't required */
#if 0
/* commented out, to return to true GNU style processing
* where longopts have to include an =, otherwise they are
* booleans */
if (argc == 1)
{
return 0; /* run out of argv for argument */
}
extra_argc_consumed = 1;
#endif
if(!storePair(opts, true, false, option, "1"))
{
return 0;
}
}
else
{
/* argument occurs after option_sep */
string val = arg.substr(arg_opt_sep + 1);
storePair(opts, true, false, option, val);
}
return extra_argc_consumed;
}
unsigned parseSHORT(Options& opts, unsigned argc, const char* argv[])
{
/* short options can take the forms:
* --option arg
* -option arg
*/
string arg(argv[0]);
size_t arg_opt_start = arg.find_first_not_of('-');
string option = arg.substr(arg_opt_start);
/* lookup option */
/* argument in argv[1] */
/* xxx, need to handle case where option isn't required */
if (argc == 1)
{
cerr << "Not processing option without argument `" << option << "'" << endl;
return 0; /* run out of argv for argument */
}
storePair(opts, false, true, option, string(argv[1]));
return 1;
}
list<const char*>
scanArgv(Options& opts, unsigned argc, const char* argv[])
{
/* a list for anything that didn't get handled as an option */
list<const char*> non_option_arguments;
for(unsigned i = 1; i < argc; i++)
{
if (argv[i][0] != '-')
{
non_option_arguments.push_back(argv[i]);
continue;
}
if (argv[i][1] == 0)
{
/* a lone single dash is an argument (usually signifying stdin) */
non_option_arguments.push_back(argv[i]);
continue;
}
if (argv[i][1] != '-')
{
/* handle short (single dash) options */
#if 0
i += parsePOSIX(opts, argc - i, &argv[i]);
#else
i += parseSHORT(opts, argc - i, &argv[i]);
#endif
continue;
}
if (argv[i][2] == 0)
{
/* a lone double dash ends option processing */
while (++i < argc)
{
non_option_arguments.push_back(argv[i]);
}
break;
}
/* handle long (double dash) options */
i += parseGNU(opts, argc - i, &argv[i]);
}
return non_option_arguments;
}
void scanLine(Options& opts, string& line)
{
/* strip any leading whitespace */
size_t start = line.find_first_not_of(" \t\n\r");
if (start == string::npos)
{
/* blank line */
return;
}
if (line[start] == '#')
{
/* comment line */
return;
}
/* look for first whitespace or ':' after the option end */
size_t option_end = line.find_first_of(": \t\n\r",start);
string option = line.substr(start, option_end - start);
/* look for ':', eat up any whitespace first */
start = line.find_first_not_of(" \t\n\r", option_end);
if (start == string::npos)
{
/* error: badly formatted line */
return;
}
if (line[start] != ':')
{
/* error: badly formatted line */
return;
}
/* look for start of value string -- eat up any leading whitespace */
start = line.find_first_not_of(" \t\n\r", ++start);
if (start == string::npos)
{
/* error: badly formatted line */
return;
}
/* extract the value part, which may contain embedded spaces
* by searching for a word at a time, until we hit a comment or end of line */
size_t value_end = start;
do
{
if (line[value_end] == '#')
{
/* rest of line is a comment */
value_end--;
break;
}
value_end = line.find_first_of(" \t\n\r", value_end);
/* consume any white space, incase there is another word.
* any trailing whitespace will be removed shortly */
value_end = line.find_first_not_of(" \t\n\r", value_end);
} while (value_end != string::npos);
/* strip any trailing space from value*/
value_end = line.find_last_not_of(" \t\n\r", value_end);
string value;
if (value_end >= start)
{
value = line.substr(start, value_end +1 - start);
}
else
{
/* error: no value */
return;
}
/* store the value in option */
storePair(opts, true, false, option, value);
}
void scanFile(Options& opts, istream& in)
{
do
{
string line;
getline(in, line);
scanLine(opts, line);
} while(!!in);
}
/* for all options in opts, set their storage to their specified
* default value */
void setDefaults(Options& opts)
{
for(Options::NamesPtrList::iterator it = opts.opt_list.begin(); it != opts.opt_list.end(); it++)
{
(*it)->opt->setDefault();
}
}
void parseConfigFile(Options& opts, const string& filename)
{
ifstream cfgstream(filename.c_str(), ifstream::in);
if (!cfgstream)
{
cerr << "Failed to open config file: `" << filename << "'" << endl;
exit(EXIT_FAILURE);
}
scanFile(opts, cfgstream);
}
}

Wyświetl plik

@ -0,0 +1,231 @@
/* The copyright in this software is being made available under the BSD
* License, included below. This software may be subject to other third party
* and contributor rights, including patent rights, and no such rights are
* granted under this license.
*
* Copyright (c) 2010-2015, ITU/ISO/IEC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <iostream>
#include <sstream>
#include <string>
#include <list>
#include <map>
#ifndef __PROGRAM_OPTIONS_LITE__
#define __PROGRAM_OPTIONS_LITE__
namespace program_options_lite
{
struct Options;
struct ParseFailure : public std::exception
{
ParseFailure(std::string arg0, std::string val0) throw()
: arg(arg0), val(val0)
{}
~ParseFailure() throw() {};
std::string arg;
std::string val;
const char* what() const throw() { return "Option Parse Failure"; }
};
void doHelp(std::ostream& out, Options& opts, unsigned columns = 80);
unsigned parseGNU(Options& opts, unsigned argc, const char* argv[]);
unsigned parseSHORT(Options& opts, unsigned argc, const char* argv[]);
std::list<const char*> scanArgv(Options& opts, unsigned argc, const char* argv[]);
void scanLine(Options& opts, std::string& line);
void scanFile(Options& opts, std::istream& in);
void setDefaults(Options& opts);
void parseConfigFile(Options& opts, const std::string& filename);
bool storePair(Options& opts, const std::string& name, const std::string& value);
/** OptionBase: Virtual base class for storing information relating to a
* specific option This base class describes common elements. Type specific
* information should be stored in a derived class. */
struct OptionBase
{
OptionBase(const std::string& name, const std::string& desc)
: opt_string(name), opt_desc(desc)
{};
virtual ~OptionBase() {}
/* parse argument arg, to obtain a value for the option */
virtual void parse(const std::string& arg) = 0;
/* set the argument to the default value */
virtual void setDefault() = 0;
std::string opt_string;
std::string opt_desc;
};
/** Type specific option storage */
template<typename T>
struct Option : public OptionBase
{
Option(const std::string& name, T& storage, T default_val, const std::string& desc)
: OptionBase(name, desc), opt_storage(storage), opt_default_val(default_val)
{}
void parse(const std::string& arg);
void setDefault()
{
opt_storage = opt_default_val;
}
T& opt_storage;
T opt_default_val;
};
/* Generic parsing */
template<typename T>
inline void
Option<T>::parse(const std::string& arg)
{
std::istringstream arg_ss (arg,std::istringstream::in);
arg_ss.exceptions(std::ios::failbit);
try
{
arg_ss >> opt_storage;
}
catch (...)
{
throw ParseFailure(opt_string, arg);
}
}
/* string parsing is specialized -- copy the whole string, not just the
* first word */
template<>
inline void
Option<std::string>::parse(const std::string& arg)
{
opt_storage = arg;
}
/** Option class for argument handling using a user provided function */
struct OptionFunc : public OptionBase
{
typedef void (Func)(Options&, const std::string&);
OptionFunc(const std::string& name, Options& parent_, Func *func_, const std::string& desc)
: OptionBase(name, desc), parent(parent_), func(func_)
{}
void parse(const std::string& arg)
{
func(parent, arg);
}
void setDefault()
{
return;
}
private:
Options& parent;
void (*func)(Options&, const std::string&);
};
class OptionSpecific;
struct Options
{
~Options();
OptionSpecific addOptions();
struct Names
{
Names() : opt(0) {};
~Names()
{
if (opt)
{
delete opt;
}
}
std::list<std::string> opt_long;
std::list<std::string> opt_short;
OptionBase* opt;
};
void addOption(OptionBase *opt);
typedef std::list<Names*> NamesPtrList;
NamesPtrList opt_list;
typedef std::map<std::string, NamesPtrList> NamesMap;
NamesMap opt_long_map;
NamesMap opt_short_map;
};
/* Class with templated overloaded operator(), for use by Options::addOptions() */
class OptionSpecific
{
public:
OptionSpecific(Options& parent_) : parent(parent_) {}
/**
* Add option described by name to the parent Options list,
* with storage for the option's value
* with default_val as the default value
* with desc as an optional help description
*/
template<typename T>
OptionSpecific&
operator()(const std::string& name, T& storage, T default_val, const std::string& desc = "")
{
parent.addOption(new Option<T>(name, storage, default_val, desc));
return *this;
}
/**
* Add option described by name to the parent Options list,
* with desc as an optional help description
* instead of storing the value somewhere, a function of type
* OptionFunc::Func is called. It is upto this function to correctly
* handle evaluating the option's value.
*/
OptionSpecific&
operator()(const std::string& name, OptionFunc::Func *func, const std::string& desc = "")
{
parent.addOption(new OptionFunc(name, parent, func, desc));
return *this;
}
private:
Options& parent;
};
} /* namespace: program_options_lite */
#endif // __PROGRAM_OPTIONS_LITE__

Wyświetl plik

@ -0,0 +1,16 @@
# library
set( LIB_NAME cJSON )
# get source files
file( GLOB SRC_FILES "*.c" "*.cpp" )
# get include files
file( GLOB INC_FILES "*.h" )
# library
add_library( ${LIB_NAME} STATIC ${SRC_FILES} ${INC_FILES} )
target_link_libraries( ${LIB_NAME} )
# set the folder where to place the projects
set_target_properties( ${LIB_NAME} PROPERTIES FOLDER lib )

Plik diff jest za duży Load Diff

Wyświetl plik

@ -0,0 +1,263 @@
/*
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
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.
*/
#ifndef cJSON__h
#define cJSON__h
#ifdef __cplusplus
extern "C"
{
#endif
/* project version */
#define CJSON_VERSION_MAJOR 1
#define CJSON_VERSION_MINOR 5
#define CJSON_VERSION_PATCH 5
#include <stddef.h>
/* cJSON Types: */
#define cJSON_Invalid (0)
#define cJSON_False (1 << 0)
#define cJSON_True (1 << 1)
#define cJSON_NULL (1 << 2)
#define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4)
#define cJSON_Array (1 << 5)
#define cJSON_Object (1 << 6)
#define cJSON_Raw (1 << 7) /* raw json */
#define cJSON_IsReference 256
#define cJSON_StringIsConst 512
/* The cJSON structure: */
typedef struct cJSON
{
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *next;
struct cJSON *prev;
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
struct cJSON *child;
/* The type of the item, as above. */
int type;
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
char *valuestring;
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
int valueint;
/* The item's number, if type==cJSON_Number */
double valuedouble;
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
char *string;
} cJSON;
typedef struct cJSON_Hooks
{
void *(*malloc_fn)(size_t sz);
void (*free_fn)(void *ptr);
} cJSON_Hooks;
typedef int cJSON_bool;
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
#define __WINDOWS__
#endif
#ifdef __WINDOWS__
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 2 define options:
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
For *nix builds that support visibility attribute, you can define similar behavior by
setting default visibility to hidden by adding
-fvisibility=hidden (for gcc)
or
-xldscope=hidden (for sun cc)
to CFLAGS
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
*/
/* export symbols by default, this is necessary for copy pasting the C and header file */
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_EXPORT_SYMBOLS
#endif
#if defined(CJSON_HIDE_SYMBOLS)
#define CJSON_PUBLIC(type) type __stdcall
#elif defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllexport) type __stdcall
#elif defined(CJSON_IMPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllimport) type __stdcall
#endif
#else /* !WIN32 */
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
#else
#define CJSON_PUBLIC(type) type
#endif
#endif
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
* This is to prevent stack overflows. */
#ifndef CJSON_NESTING_LIMIT
#define CJSON_NESTING_LIMIT 1000
#endif
/* returns the version of cJSON as a string */
CJSON_PUBLIC(const char*) cJSON_Version(void);
/* Supply malloc, realloc and free functions to cJSON */
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
/* Render a cJSON entity to text for transfer/storage. */
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. */
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
/* Delete a cJSON entity and all subentities. */
CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
/* Returns the number of items in an array (or object). */
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
/* Get item "string" from object. Case insensitive. */
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
/* These functions check the type of an item */
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
/* These calls create a cJSON item of the appropriate type. */
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
/* raw json */
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
/* These utilities create an Array of count items. */
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
/* Append item to the specified array/object. */
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
* writing to `item->string` */
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
/* Remove/Detatch items from Arrays/Objects. */
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
/* Update array items. */
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
/* Duplicate a cJSON item */
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
need to be released. With recurse!=0, it will duplicate any children connected to the item.
The item->next and ->prev pointers are always zero on return from Duplicate. */
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error. If not, then cJSON_GetErrorPtr() does the job. */
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
CJSON_PUBLIC(void) cJSON_Minify(char *json);
/* Macros for creating things quickly. */
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
#define cJSON_AddRawToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateRaw(s))
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
/* helper for the cJSON_SetNumberValue macro */
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
/* Macro for iterating over an array or object */
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
CJSON_PUBLIC(void) cJSON_free(void *object);
#ifdef __cplusplus
}
#endif
#endif

Plik diff jest za duży Load Diff

Wyświetl plik

@ -0,0 +1,74 @@
/*
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
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.
*/
#include "cJSON.h"
/* Implement RFC6901 (https://tools.ietf.org/html/rfc6901) JSON Pointer spec. */
CJSON_PUBLIC(cJSON *) cJSONUtils_GetPointer(cJSON * const object, const char *pointer);
CJSON_PUBLIC(cJSON *) cJSONUtils_GetPointerCaseSensitive(cJSON * const object, const char *pointer);
/* Implement RFC6902 (https://tools.ietf.org/html/rfc6902) JSON Patch spec. */
/* NOTE: This modifies objects in 'from' and 'to' by sorting the elements by their key */
CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatches(cJSON * const from, cJSON * const to);
CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatchesCaseSensitive(cJSON * const from, cJSON * const to);
/* Utility for generating patch array entries. */
CJSON_PUBLIC(void) cJSONUtils_AddPatchToArray(cJSON * const array, const char * const operation, const char * const path, const cJSON * const value);
/* Returns 0 for success. */
CJSON_PUBLIC(int) cJSONUtils_ApplyPatches(cJSON * const object, const cJSON * const patches);
CJSON_PUBLIC(int) cJSONUtils_ApplyPatchesCaseSensitive(cJSON * const object, const cJSON * const patches);
/*
// Note that ApplyPatches is NOT atomic on failure. To implement an atomic ApplyPatches, use:
//int cJSONUtils_AtomicApplyPatches(cJSON **object, cJSON *patches)
//{
// cJSON *modme = cJSON_Duplicate(*object, 1);
// int error = cJSONUtils_ApplyPatches(modme, patches);
// if (!error)
// {
// cJSON_Delete(*object);
// *object = modme;
// }
// else
// {
// cJSON_Delete(modme);
// }
//
// return error;
//}
// Code not added to library since this strategy is a LOT slower.
*/
/* Implement RFC7386 (https://tools.ietf.org/html/rfc7396) JSON Merge Patch spec. */
/* target will be modified by patch. return value is new ptr for target. */
CJSON_PUBLIC(cJSON *) cJSONUtils_MergePatch(cJSON *target, const cJSON * const patch);
CJSON_PUBLIC(cJSON *) cJSONUtils_MergePatchCaseSensitive(cJSON *target, const cJSON * const patch);
/* generates a patch to move from -> to */
/* NOTE: This modifies objects in 'from' and 'to' by sorting the elements by their key */
CJSON_PUBLIC(cJSON *) cJSONUtils_GenerateMergePatch(cJSON * const from, cJSON * const to);
CJSON_PUBLIC(cJSON *) cJSONUtils_GenerateMergePatchCaseSensitive(cJSON * const from, cJSON * const to);
/* Given a root object and a target object, construct a pointer from one to the other. */
CJSON_PUBLIC(char *) cJSONUtils_FindPointerFromObjectTo(const cJSON * const object, const cJSON * const target);
/* Sorts the members of the object into alphabetical order. */
CJSON_PUBLIC(void) cJSONUtils_SortObject(cJSON * const object);
CJSON_PUBLIC(void) cJSONUtils_SortObjectCaseSensitive(cJSON * const object);

Wyświetl plik

@ -0,0 +1,24 @@
/*! @file common_app_def.h
*
* @brief Common defines for all sample applications
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef COMMON_APP_DEFS_H
#define COMMON_APP_DEFS_H
#define MAX_STDOUT_LINE 100
#endif

Wyświetl plik

@ -0,0 +1,69 @@
# executable
set( EXE_NAME gpr_tools )
# get source and include files
file( GLOB GPRTOOLS_SRC_FILES "*.c" "*.cpp" )
file( GLOB GPRTOOLS_INC_FILES "*.h" "../common/*.h" )
# add include files from other folders
include_directories( "../common" )
include_directories( "../common/cJSON" )
include_directories( "../common/argument_parser" )
include_directories( "../common/TinyJPEG" )
include_directories( "../../lib/common/public" )
include_directories( "../../lib/vc5_common" )
if(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_decoder")
include_directories( "../../lib/vc5_decoder" )
add_definitions("-DGPR_READING=1")
else(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_decoder")
add_definitions("-DGPR_READING=0")
endif(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_decoder")
if(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_encoder")
include_directories( "../../lib/vc5_encoder" )
add_definitions("-DGPR_WRITING=1")
else(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_encoder")
add_definitions("-DGPR_WRITING=0")
endif(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_encoder")
include_directories( "../../lib/md5_lib" )
include_directories( "../../lib/dng_sdk" )
include_directories( "../../lib/gpr_sdk/public" )
if(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/tiny_jpeg")
include_directories( "../../lib/tiny_jpeg" )
add_definitions("-DGPR_JPEG_AVAILABLE=1")
else(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/tiny_jpeg")
add_definitions("-DGPR_JPEG_AVAILABLE=0")
endif(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/tiny_jpeg")
# add executable
add_executable( ${EXE_NAME} ${GPRTOOLS_SRC_FILES} ${GPRTOOLS_INC_FILES} )
# Linked libraries
target_link_libraries( ${EXE_NAME} gpr_sdk )
if(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/tiny_jpeg")
target_link_libraries( ${EXE_NAME} tiny_jpeg )
endif(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/tiny_jpeg")
target_link_libraries( ${EXE_NAME} dng_sdk xmp_core )
if(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_decoder")
target_link_libraries( ${EXE_NAME} vc5_decoder )
endif(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_decoder")
if(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_encoder")
target_link_libraries( ${EXE_NAME} vc5_encoder )
endif(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_encoder")
target_link_libraries( ${EXE_NAME} vc5_common common md5_lib expat_lib cJSON argument_parser )
# In order to use Carbon API, define qEnableCarbon in gpr_platform.h and uncomment code below
# if (APPLE)
# target_link_libraries( ${EXE_NAME} "-framework Carbon" )
# endif (APPLE)
# set the folder where to place the projects
set_target_properties( ${EXE_NAME} PROPERTIES FOLDER app )

Wyświetl plik

@ -0,0 +1,545 @@
/*! @file gpr_parse_utils.cpp
*
* @brief Parsing utilities for gpr_tools
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "gpr_parse_utils.h"
#include "stdcpp_utils.h"
#include "cJSON.h"
#include "dng_stream.h"
#include "dng_misc_opcodes.h"
#include "dng_gain_map.h"
#define MAX_BUF_SIZE 16000
void parse_gps_info( cJSON* pGpsInfo, gpr_gps_info& exif_info )
{
exif_info.gps_info_valid = false;
}
void parse_exif_info( cJSON* pExifInfo, gpr_exif_info& exif_info )
{
cJSON* pJSON = pExifInfo->child;
strcpy( exif_info.camera_make, pJSON->valuestring );
pJSON = pJSON->next;
strcpy( exif_info.camera_model, pJSON->valuestring );
pJSON = pJSON->next;
strcpy( exif_info.camera_serial, pJSON->valuestring );
pJSON = pJSON->next;
strcpy( exif_info.software_version, pJSON->valuestring );
pJSON = pJSON->next;
strcpy( exif_info.user_comment, pJSON->valuestring );
pJSON = pJSON->next;
strcpy( exif_info.image_description, pJSON->valuestring );
pJSON = pJSON->next;
exif_info.exposure_time.numerator = pJSON->child->valueint;
exif_info.exposure_time.denominator = pJSON->child->next->valueint;
pJSON = pJSON->next;
exif_info.f_stop_number.numerator = pJSON->child->valueint;
exif_info.f_stop_number.denominator = pJSON->child->next->valueint;
pJSON = pJSON->next;
exif_info.aperture.numerator = pJSON->child->valueint;
exif_info.aperture.denominator = pJSON->child->next->valueint;
pJSON = pJSON->next;
exif_info.exposure_program = (gpr_exposure_program)pJSON->valueint;
pJSON = pJSON->next;
exif_info.iso_speed_rating = pJSON->valueint;
pJSON = pJSON->next;
// strcpy( exif_info.date_time_original, pJSON->valuestring );
pJSON = pJSON->next;
// strcpy( exif_info.date_time_digitized, pJSON->valuestring );
pJSON = pJSON->next;
exif_info.exposure_bias.numerator = pJSON->child->valueint;
exif_info.exposure_bias.denominator = pJSON->child->next->valueint;
pJSON = pJSON->next;
exif_info.light_source = (gpr_light_source)pJSON->valueint;
pJSON = pJSON->next;
exif_info.flash = (gpr_flash)pJSON->valueint;
pJSON = pJSON->next;
exif_info.focal_length.numerator = pJSON->child->valueint;
exif_info.focal_length.denominator = pJSON->child->next->valueint;
pJSON = pJSON->next;
exif_info.sharpness = (gpr_sharpness)pJSON->valueint;
pJSON = pJSON->next;
exif_info.saturation = pJSON->valueint;
pJSON = pJSON->next;
exif_info.gain_control = (gpr_gain_control)pJSON->valueint;
pJSON = pJSON->next;
exif_info.contrast = (gpr_contrast)pJSON->valueint;
pJSON = pJSON->next;
exif_info.scene_capture_type = (gpr_scene_capture_type)pJSON->valueint;
pJSON = pJSON->next;
exif_info.exposure_mode = (gpr_exposure_mode)pJSON->valueint;
pJSON = pJSON->next;
exif_info.focal_length_in_35mm_film = pJSON->valueint;
pJSON = pJSON->next;
exif_info.digital_zoom.numerator = pJSON->child->valueint;
exif_info.digital_zoom.denominator = pJSON->child->next->valueint;
pJSON = pJSON->next;
exif_info.white_balance = (gpr_white_balance)pJSON->valueint;
pJSON = pJSON->next;
exif_info.scene_type = (gpr_scene_type)pJSON->valueint;
pJSON = pJSON->next;
exif_info.file_source = (gpr_file_source)pJSON->valueint;
pJSON = pJSON->next;
exif_info.sensing_method = (gpr_sensing_method)pJSON->valueint;
pJSON = pJSON->next;
parse_gps_info( pJSON, exif_info.gps_info );
}
void parse_profile_info( cJSON* pProfileInfo, gpr_profile_info& profile_info )
{
cJSON* pJSON = pProfileInfo->child;
profile_info.compute_color_matrix = pJSON->valueint > 0 ? true : false;
pJSON = pJSON->next;
profile_info.matrix_weighting = pJSON->valuedouble;
pJSON = pJSON->next;
{
cJSON* child = pJSON->child;
profile_info.wb1[0] = child->valuedouble;
child = child->next;
profile_info.wb1[1] = child->valuedouble;
child = child->next;
profile_info.wb1[2] = child->valuedouble;
pJSON = pJSON->next;
}
{
cJSON* child = pJSON->child;
profile_info.wb2[0] = child->valuedouble;
child = child->next;
profile_info.wb2[1] = child->valuedouble;
child = child->next;
profile_info.wb2[2] = child->valuedouble;
pJSON = pJSON->next;
}
{
cJSON* child = pJSON->child;
profile_info.cam_to_srgb_1[0][0] = child->valuedouble;
child = child->next;
profile_info.cam_to_srgb_1[0][1] = child->valuedouble;
child = child->next;
profile_info.cam_to_srgb_1[0][2] = child->valuedouble;
child = child->next;
profile_info.cam_to_srgb_1[1][0] = child->valuedouble;
child = child->next;
profile_info.cam_to_srgb_1[1][1] = child->valuedouble;
child = child->next;
profile_info.cam_to_srgb_1[1][2] = child->valuedouble;
child = child->next;
profile_info.cam_to_srgb_1[2][0] = child->valuedouble;
child = child->next;
profile_info.cam_to_srgb_1[2][1] = child->valuedouble;
child = child->next;
profile_info.cam_to_srgb_1[2][2] = child->valuedouble;
pJSON = pJSON->next;
}
{
cJSON* child = pJSON->child;
profile_info.cam_to_srgb_2[0][0] = child->valuedouble;
child = child->next;
profile_info.cam_to_srgb_2[0][1] = child->valuedouble;
child = child->next;
profile_info.cam_to_srgb_2[0][2] = child->valuedouble;
child = child->next;
profile_info.cam_to_srgb_2[1][0] = child->valuedouble;
child = child->next;
profile_info.cam_to_srgb_2[1][1] = child->valuedouble;
child = child->next;
profile_info.cam_to_srgb_2[1][2] = child->valuedouble;
child = child->next;
profile_info.cam_to_srgb_2[2][0] = child->valuedouble;
child = child->next;
profile_info.cam_to_srgb_2[2][1] = child->valuedouble;
child = child->next;
profile_info.cam_to_srgb_2[2][2] = child->valuedouble;
pJSON = pJSON->next;
}
{
cJSON* child = pJSON->child;
profile_info.color_matrix_1[0][0] = child->valuedouble;
child = child->next;
profile_info.color_matrix_1[0][1] = child->valuedouble;
child = child->next;
profile_info.color_matrix_1[0][2] = child->valuedouble;
child = child->next;
profile_info.color_matrix_1[1][0] = child->valuedouble;
child = child->next;
profile_info.color_matrix_1[1][1] = child->valuedouble;
child = child->next;
profile_info.color_matrix_1[1][2] = child->valuedouble;
child = child->next;
profile_info.color_matrix_1[2][0] = child->valuedouble;
child = child->next;
profile_info.color_matrix_1[2][1] = child->valuedouble;
child = child->next;
profile_info.color_matrix_1[2][2] = child->valuedouble;
pJSON = pJSON->next;
}
{
cJSON* child = pJSON->child;
profile_info.color_matrix_2[0][0] = child->valuedouble;
child = child->next;
profile_info.color_matrix_2[0][1] = child->valuedouble;
child = child->next;
profile_info.color_matrix_2[0][2] = child->valuedouble;
child = child->next;
profile_info.color_matrix_2[1][0] = child->valuedouble;
child = child->next;
profile_info.color_matrix_2[1][1] = child->valuedouble;
child = child->next;
profile_info.color_matrix_2[1][2] = child->valuedouble;
child = child->next;
profile_info.color_matrix_2[2][0] = child->valuedouble;
child = child->next;
profile_info.color_matrix_2[2][1] = child->valuedouble;
child = child->next;
profile_info.color_matrix_2[2][2] = child->valuedouble;
pJSON = pJSON->next;
}
profile_info.illuminant1 = pJSON->valueint;
pJSON = pJSON->next;
profile_info.illuminant2 = pJSON->valueint;
}
void parse_tuning_info( cJSON* pTuningInfo, gpr_tuning_info& tuning_info )
{
cJSON* pJSON = pTuningInfo->child;
tuning_info.orientation = (GPR_ORIENTATION)pJSON->valueint;
pJSON = pJSON->next;
{
cJSON* child = pJSON->child;
tuning_info.static_black_level.r_black = child->valueint;
child = child->next;
tuning_info.static_black_level.g_r_black = child->valueint;
child = child->next;
tuning_info.static_black_level.g_b_black = child->valueint;
child = child->next;
tuning_info.static_black_level.b_black = child->valueint;
pJSON = pJSON->next;
}
{
cJSON* child = pJSON->child;
tuning_info.dgain_saturation_level.level_red = child->valueint;
child = child->next;
tuning_info.dgain_saturation_level.level_green_even = child->valueint;
child = child->next;
tuning_info.dgain_saturation_level.level_green_odd = child->valueint;
child = child->next;
tuning_info.dgain_saturation_level.level_blue = child->valueint;
pJSON = pJSON->next;
}
{
cJSON* child = pJSON->child;
tuning_info.wb_gains.r_gain = (float_t)child->valuedouble;
child = child->next;
tuning_info.wb_gains.g_gain = (float_t)child->valuedouble;
child = child->next;
tuning_info.wb_gains.b_gain = (float_t)child->valuedouble;
pJSON = pJSON->next;
}
{
cJSON* child = pJSON->child;
tuning_info.ae_info.iso_value = child->valueint;
child = child->next;
tuning_info.ae_info.shutter_time = child->valueint;
pJSON = pJSON->next;
}
tuning_info.noise_scale = pJSON->valuedouble;
pJSON = pJSON->next;
tuning_info.noise_offset = pJSON->valuedouble;
pJSON = pJSON->next;
tuning_info.warp_red_coefficient = pJSON->valuedouble;
pJSON = pJSON->next;
tuning_info.warp_blue_coefficient = pJSON->valuedouble;
pJSON = pJSON->next;
if( pJSON->child )
{
cJSON* size = pJSON->child;
int buffer_size = size->valueint;
tuning_info.gain_map.size = buffer_size;
cJSON* channel = size->next;
int channel_index = 0;
while( channel && channel_index < 4 && buffer_size > 0 )
{
cJSON* child = channel->child;
int version = child->valueint;
child = child->next;
int flags = child->valueint;
child = child->next;
int bytes = child->valueint;
child = child->next;
char gain_map_buffer[MAX_BUF_SIZE];
tuning_info.gain_map.buffers[channel_index] = (char*)malloc( buffer_size );
dng_stream gain_map_stream ( gain_map_buffer, buffer_size );
gain_map_stream.Put_uint32( version );
gain_map_stream.Put_uint32( flags );
gain_map_stream.Put_uint32( bytes );
{
cJSON* _child = child->child;
dng_rect rect;
rect.t = _child->valueint;
_child = _child->next;
rect.l = _child->valueint;
_child = _child->next;
rect.b = _child->valueint;
_child = _child->next;
rect.r = _child->valueint;
dng_area_spec area_spec(rect, 0, 1, 2, 2);
area_spec.PutData (gain_map_stream);
child = child->next;
}
dng_point points;
{
cJSON* _child = child->child;
points.h = _child->valueint;
_child = _child->next;
points.v = _child->valueint;
child = child->next;
}
dng_point_real64 spacing;
{
cJSON* _child = child->child;
spacing.h = _child->valuedouble;
_child = _child->next;
spacing.v = _child->valuedouble;
child = child->next;
}
dng_point_real64 origin;
{
cJSON* _child = child->child;
origin.h = _child->valuedouble;
_child = _child->next;
origin.v = _child->valuedouble;
child = child->next;
}
dng_gain_map gain_map( gDefaultDNGMemoryAllocator, points, spacing, origin, 1 );
cJSON* _child = child->child;
for (int row = 0; row < points.v; row++)
{
for (int col = 0; col < points.h; col++)
{
gain_map.Entry (row, col, 0) = (float_t)_child->valuedouble;
_child = _child->next;
}
}
gain_map.PutStream( gain_map_stream );
memcpy( tuning_info.gain_map.buffers[channel_index], gain_map_buffer, buffer_size );
channel = channel->next;
channel_index++;
}
}
pJSON = pJSON->next;
tuning_info.pixel_format = (GPR_PIXEL_FORMAT)pJSON->valueint;
}
int gpr_parameters_parse( gpr_parameters* parameters, const char* input_file_path )
{
gpr_buffer buffer;
if( read_from_file( &buffer, input_file_path, malloc, free) )
{
return -2;
}
const char* return_parse_end;
cJSON* pRoot = cJSON_ParseWithOpts( (const char*)buffer.buffer, &return_parse_end, 0 );
if( pRoot == NULL )
{
printf( "Error parsing %s \n", input_file_path );
printf( "Error: %s", return_parse_end );
return -1;
}
cJSON* pJSON = pRoot->child;
parameters->input_width = pJSON->valueint;
pJSON = pJSON->next;
parameters->input_height = pJSON->valueint;
pJSON = pJSON->next;
parameters->input_pitch = pJSON->valueint;
pJSON = pJSON->next;
parameters->fast_encoding = pJSON->valueint > 0 ? true : false;
pJSON = pJSON->next;
parameters->gpmf_payload.size = pJSON->valueint;
pJSON = pJSON->next;
parse_exif_info( pJSON, parameters->exif_info );
pJSON = pJSON->next;
parse_profile_info( pJSON, parameters->profile_info );
pJSON = pJSON->next;
parse_tuning_info( pJSON, parameters->tuning_info );
free( buffer.buffer );
return 0;
}

Wyświetl plik

@ -0,0 +1,34 @@
/*! @file gpr_parse_utils.h
*
* @brief Parsing utilities for gpr_tools
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GPR_PARSE_UTILS_H
#define GPR_PARSE_UTILS_H
#include "gpr.h"
#ifdef __cplusplus
extern "C" {
#endif
int gpr_parameters_parse( gpr_parameters* parameters, const char* input_file_path );
#ifdef __cplusplus
}
#endif
#endif // GPR_PARSE_UTILS_H

Wyświetl plik

@ -0,0 +1,541 @@
/*! @file gpr_print_utils.cpp
*
* @brief Printing utilities for gpr_tools
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "gpr_print_utils.h"
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
#include "dng_stream.h"
#include "dng_misc_opcodes.h"
#include "dng_gain_map.h"
uint32 spaces = 0;
ostream& operator<<(ostream& output, const gpr_signed_rational& x)
{
output << "[" << x.numerator << "," << x.denominator << "]";
return output;
}
ostream& operator<<(ostream& output, const gpr_unsigned_rational& x)
{
output << "[" << x.numerator << "," << x.denominator << "]";
return output;
}
ostream& operator<<(ostream& output, const gpr_date_and_time& x)
{
output << "\"" << x.year << "-" << x.month << "-" << x.day << " " << x.hour << ":" << x.minute << ":" << x.second << "\"";
return output;
}
ostream& operator<<(ostream& output, const dng_area_spec& x)
{
dng_rect area = x.Area();
output << "{ \"top\" : " << area.t << ", \"left\" : " << area.l << ", \"bottom\" : " << area.b << ", \"right\" : " << area.r << ", \"row_pitch\" : " << x.RowPitch() << ", \"col_pitch\" : " << x.ColPitch() << " }";
return output;
}
ostream& operator<<(ostream& output, const dng_point& x)
{
output << "{ \"h\" : " << x.h << ", \"v\" : " << x.v << " }";
return output;
}
ostream& operator<<(ostream& output, const dng_point_real64& x)
{
output << "{ \"h\" : " << x.h << ", \"v\" : " << x.v << " }";
return output;
}
void start_tag( const string& tag_id, ostream& output )
{
output << "{" << endl;
spaces += 2;
}
void end_tag( const string& tag_id, ostream& output )
{
spaces -= 2;
output << string( spaces, ' ' ).c_str() << "}";
}
template<class T>
void print_val(ostream& output, string tag, T x, int N = 0, bool last = false)
{
if( last )
output << string( spaces, ' ' ).c_str() << "\"" << tag.c_str() << "\": " << x << "" << endl;
else
output << string( spaces, ' ' ).c_str() << "\"" << tag.c_str() << "\": " << x << "," << endl;
}
template<>
void print_val<const char*>(ostream& output, string tag, const char* x, int N, bool last)
{
if( last )
output << string( spaces, ' ' ).c_str() << "\"" << tag.c_str() << "\": " << "\"" << x << "\"" << "" << endl;
else
output << string( spaces, ' ' ).c_str() << "\"" << tag.c_str() << "\": " << "\"" << x << "\"" << "," << endl;
}
template<>
void print_val<const double*>(ostream& output, string tag, const double* x, int N, bool last)
{
output << string( spaces, ' ' ).c_str() << "\"" << tag.c_str() << "\": " << "[";
for (int i = 0; i < N; i++)
{
if( i < N - 1 )
output << x[i] << ",";
else
output << x[i];
}
if( last )
output << "]" << "" << endl;
else
output << "]" << "," << endl;
}
template<>
void print_val<const gpr_unsigned_rational*>(ostream& output, string tag, const gpr_unsigned_rational* x, int N, bool last)
{
output << string( spaces, ' ' ).c_str() << "\"" << tag.c_str() << "\": " << "[";
for (int i = 0; i < N; i++)
{
if( i < N - 1 )
output << x[i] << ",";
else
output << x[i];
}
if( last )
output << "]" << "" << endl;
else
output << "]" << "," << endl;
}
template<class T, int N>
void print_val(ostream& output, string tag, T x[N][N])
{
output << string( spaces, ' ' ) << "\"" << tag << "\": " << "[";
output << x[0][0] << ",";
output << x[0][1] << ",";
output << x[0][2] << ",";
output << x[1][0] << ",";
output << x[1][1] << ",";
output << x[1][2] << ",";
output << x[2][0] << ",";
output << x[2][1] << ",";
output << x[2][2];
output << "]";
output << "," << endl;
}
ostream& operator<<(ostream& output, const gpr_gain_map& x)
{
start_tag( "gain_map", output );
if( x.size > 0 )
{
print_val( output, "size", x.size );
for (int i = 0; i < 4; i++)
{
dng_stream gain_map_stream (x.buffers[i], x.size);
output << string( spaces, ' ' ).c_str() << "\"" << "channel_" << i << "\": ";
start_tag( "channel", output );
print_val( output, "version", gain_map_stream.Get_uint32() );
print_val( output, "flags", gain_map_stream.Get_uint32() );
print_val( output, "bytes", gain_map_stream.Get_uint32() );
dng_area_spec area_spec;
area_spec.GetData (gain_map_stream);
print_val( output, "area", area_spec );
AutoPtr<dng_gain_map> gain_map;
gain_map.Reset (dng_gain_map::GetStream (gain_map_stream, gDefaultDNGMemoryAllocator));
dng_point points = gain_map.Get()->Points();
dng_point_real64 spacing = gain_map.Get()->Spacing();
dng_point_real64 origin = gain_map.Get()->Origin();
print_val( output, "points", points );
print_val( output, "spacing", spacing );
print_val( output, "origin", origin );
output << string( spaces, ' ' ).c_str() << "\"" << "values" << "\": [";
for (int row = 0; row < points.v; row++)
{
for (int col = 0; col < points.h; col++)
{
output << gain_map->Entry (row, col, 0);
if( row == points.v - 1 && col == points.h - 1 )
output << " ";
else
output << ", ";
}
}
output << "] " << endl;
end_tag( "channel", output );
if( i < 3 )
output << ", " << endl;
}
}
end_tag( "gain_map", output );
return output;
}
ostream& operator<<(ostream& output, const gpr_gps_info& x)
{
start_tag( "gps_info", output );
if( x.gps_info_valid )
{
print_val( output, "gps_info_valid", x.gps_info_valid );
print_val( output, "version_id", x.version_id );
print_val( output, "latitude_ref", x.latitude_ref );
print_val( output, "latitude", x.latitude, 3 );
print_val( output, "longitude_ref", x.longitude_ref );
print_val( output, "longitude", x.longitude, 3 );
print_val( output, "altitude_ref", (uint32)x.altitude_ref );
print_val( output, "altitude", x.altitude );
print_val( output, "time_stamp", x.time_stamp );
print_val( output, "satellites", x.satellites );
print_val( output, "status", x.status );
print_val( output, "dop", x.dop );
print_val( output, "speed_ref", x.speed_ref );
print_val( output, "speed", x.speed );
print_val( output, "track_ref", x.track_ref );
print_val( output, "track", x.track );
print_val( output, "img_direction_ref", x.img_direction_ref );
print_val( output, "img_direction", x.img_direction );
print_val( output, "map_datum", x.map_datum );
print_val( output, "dest_latitude_ref", x.dest_latitude_ref );
print_val( output, "dest_latitude", x.dest_latitude );
print_val( output, "dest_longitude_ref", x.dest_longitude_ref );
print_val( output, "dest_longitude", x.dest_longitude );
print_val( output, "dest_bearing_ref", x.dest_bearing_ref );
print_val( output, "dest_bearing", x.dest_bearing );
print_val( output, "dest_distance_ref", x.dest_distance_ref );
print_val( output, "dest_distance", x.dest_distance );
print_val( output, "processing_method", x.processing_method );
print_val( output, "area_information", x.area_information );
print_val( output, "date_stamp", x.date_stamp );
print_val( output, "differential", x.differential, 0, true );
}
else
{
print_val( output, "gps_info_valid", x.gps_info_valid, 0, true );
}
end_tag( "gps_info", output );
return output;
}
ostream& operator<<(ostream& output, const gpr_exif_info& x)
{
start_tag( "exif_info", output );
print_val( output, "camera_make", x.camera_make );
print_val( output, "camera_model", x.camera_model );
print_val( output, "camera_serial", x.camera_serial );
print_val( output, "software_version", x.software_version );
print_val( output, "user_comment", x.user_comment );
{
string str_image_description = x.image_description;
std::replace( str_image_description.begin(), str_image_description.end(), '\\', '/');
print_val( output, "image_description", str_image_description.c_str() );
}
print_val( output, "exposure_time", x.exposure_time );
print_val( output, "f_stop_number", x.f_stop_number );
print_val( output, "aperture", x.aperture );
print_val( output, "exposure_program", x.exposure_program );
print_val( output, "iso_speed_rating", x.iso_speed_rating );
print_val( output, "date_time_original", x.date_time_original );
print_val( output, "date_time_digitized", x.date_time_digitized );
print_val( output, "exposure_bias", x.exposure_bias );
print_val( output, "light_source", x.light_source );
print_val( output, "flash", x.flash );
print_val( output, "focal_length", x.focal_length );
print_val( output, "sharpness", x.sharpness );
print_val( output, "saturation", x.saturation );
print_val( output, "gain_control", x.gain_control );
print_val( output, "contrast", x.contrast );
print_val( output, "scene_capture_type", x.scene_capture_type );
print_val( output, "exposure_mode", x.exposure_mode );
print_val( output, "focal_length_in_35mm_film", x.focal_length_in_35mm_film );
print_val( output, "digital_zoom", x.digital_zoom );
print_val( output, "white_balance", x.white_balance );
print_val( output, "scene_type", x.scene_type );
print_val( output, "file_source", x.file_source );
print_val( output, "sensing_method", x.sensing_method );
print_val( output, "gps_info", x.gps_info, 0, true );
end_tag( "exif_info", output );
return output;
}
ostream& operator<<(ostream& output, const gpr_profile_info& x)
{
start_tag( "profile_info", output );
print_val( output, "compute_color_matrix", x.compute_color_matrix );
print_val( output, "matrix_weighting", x.matrix_weighting );
print_val( output, "wb1", x.wb1, 3, false );
print_val( output, "wb2", x.wb2, 3, false );
print_val( output, "cam_to_srgb_1", (const double*)x.cam_to_srgb_1, 9, false );
print_val( output, "cam_to_srgb_2", (const double*)x.cam_to_srgb_2, 9, false );
print_val( output, "color_matrix_1", (const double*)x.color_matrix_1, 9, false );
print_val( output, "color_matrix_2", (const double*)x.color_matrix_2, 9, false );
print_val( output, "illuminant1", x.illuminant1, 0, false );
print_val( output, "illuminant2", x.illuminant2, 0, true );
end_tag( "profile_info", output );
return output;
}
ostream& operator<<(ostream& output, const gpr_static_black_level& x)
{
start_tag( "static_black_level", output );
print_val( output, "r_black", x.r_black );
print_val( output, "g_r_black", x.g_r_black );
print_val( output, "g_b_black", x.g_b_black );
print_val( output, "b_black", x.b_black, 0, true );
end_tag( "static_black_level", output );
return output;
}
ostream& operator<<(ostream& output, const gpr_saturation_level& x)
{
start_tag( "dgain_saturation_level", output );
print_val( output, "level_red", x.level_red );
print_val( output, "level_green_even", x.level_green_even );
print_val( output, "level_green_odd", x.level_green_odd );
print_val( output, "level_blue", x.level_blue, 0, true );
end_tag( "dgain_saturation_level", output );
return output;
}
ostream& operator<<(ostream& output, const gpr_white_balance_gains& x)
{
start_tag( "wb_gains", output );
print_val( output, "r_gain", x.r_gain );
print_val( output, "g_gain", x.g_gain );
print_val( output, "b_gain", x.b_gain, 0, true );
end_tag( "wb_gains", output );
return output;
}
ostream& operator<<(ostream& output, const gpr_auto_exposure_info& x)
{
start_tag( "ae_info", output );
print_val( output, "iso_value", x.iso_value );
print_val( output, "shutter_time", x.shutter_time, 0, true );
end_tag( "ae_info", output );
return output;
}
ostream& operator<<(ostream& output, const gpr_tuning_info& x)
{
start_tag( "tuning_info", output );
print_val( output, "orientation", x.orientation );
print_val( output, "static_black_level", x.static_black_level );
print_val( output, "dgain_saturation_level", x.dgain_saturation_level );
print_val( output, "wb_gains", x.wb_gains );
print_val( output, "ae_info", x.ae_info );
print_val( output, "noise_scale", x.noise_scale );
print_val( output, "noise_offset", x.noise_offset );
print_val( output, "warp_red_coefficient", x.warp_red_coefficient );
print_val( output, "warp_blue_coefficient", x.warp_blue_coefficient );
print_val( output, "gain_map", x.gain_map );
print_val( output, "pixel_format", x.pixel_format, 0, true );
end_tag( "tuning_info", output );
return output;
}
ostream& operator<<(ostream& output, const gpr_parameters& x)
{
print_val( output, "input_width", x.input_width );
print_val( output, "input_height", x.input_height );
print_val( output, "input_pitch", x.input_pitch );
print_val( output, "fast_encoding", x.fast_encoding );
// print_val( output, "gpmf_payload_buffer", x.gpmf_payload.buffer );
print_val( output, "gpmf_payload_size", x.gpmf_payload.size );
print_val( output, "exif_info", x.exif_info );
print_val( output, "profile_info", x.profile_info );
print_val( output, "tuning_info", x.tuning_info, 0, true );
return output;
}
int gpr_parameters_print( const gpr_parameters* parameters, const char* output_file_path )
{
ofstream output;
ostream* output_ref = &cout;
if( output_file_path )
{
output.open (output_file_path);
output_ref = &output;
}
start_tag( "", *output_ref );
*output_ref << *parameters;
end_tag( "", *output_ref );
return 0;
}

Wyświetl plik

@ -0,0 +1,34 @@
/*! @file gpr_print_utils.h
*
* @brief Printing utilities for gpr_tools
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GPR_PRINT_UTILS_H
#define GPR_PRINT_UTILS_H
#include "gpr.h"
#ifdef __cplusplus
extern "C" {
#endif
int gpr_parameters_print( const gpr_parameters* parameters, const char* output_file_path );
#ifdef __cplusplus
}
#endif
#endif // GPR_PRINT_UTILS_H

Wyświetl plik

@ -0,0 +1,203 @@
/*! @file main.cpp
*
* @brief Main program file for the gpr_tools.
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include "argument_parser.h"
#include "gpr.h"
#include "gpr_buffer.h"
#include "gpr_print_utils.h"
#include "main_c.h"
#include "common_app_def.h"
using namespace std;
class my_argument_parser : public argument_parser
{
protected:
bool help;
bool verbose;
public:
bool dump_gpr_parameters;
string jpg_preview_file_path;
int jpg_preview_file_width;
int jpg_preview_file_height;
int input_width;
int input_height;
int input_pitch;
int input_skip_rows;
string input_pixel_format;
string input_file_path;
string gpmf_file_path;
string rgb_file_resolution;
int rgb_file_bits;
string output_file_path;
string apply_gpr_parameters;
public:
bool get_verbose() { return verbose; }
bool get_help() { return help; }
void set_options()
{
command_options.addOptions()
/* long and short name */ /* variable to update */ /* default value */ /* help text */
("help", help, false, "Prints this help text")
("verbose", verbose, false, "Verbosity of the output")
("JpgPreviewFilePath,P", jpg_preview_file_path, string(""), "Preview jpg file path")
("JpgPreviewFileWidth,W", jpg_preview_file_width, 0, "Preview jpg file width")
("JpgPreviewFileHeight,H", jpg_preview_file_height, 0, "Preview jpg file height")
("DumpGprParameters,d", dump_gpr_parameters, false, "Dump GPR parameters to standard output")
("InputSkipRows,s", input_skip_rows, 0, "Input image rows to skip")
("InputFilePath,i", input_file_path, string(""), "Input file path.\n(files types: GPR, DNG, RAW)")
("InputWidth,w", input_width, 4000, "Input image width in pixel samples [4000]")
("InputHeight,h", input_height, 3000, "Input image height in pixel samples [3000]")
("InputPitch,p", input_pitch, 8000, "Input image pitch in bytes [8000]")
("InputPixelFormat,x", input_pixel_format, string("rggb14"), "Input pixel format \n(rggb12, rggb12p, [rggb14], gbrg12, gbrg12p)")
("ApplyGprParameters,a", apply_gpr_parameters, string(""), "Parameters to use for GPR or DNG file.")
("GPMFFilePath,g", gpmf_file_path, string(""), "GPMF file path")
("RgbFileResolution,r", rgb_file_resolution, string(""), "Output RGB resolution \n[1:1, 2:1, 4:1, 8:1. 16:1]")
("RgbFileBits,b", rgb_file_bits, 8, "Output RGB bits [8]")
("OutputFilePath,o", output_file_path, string(""), "Output file path.\n(files types: GPR, DNG, PPM, RAW, JPG)");
;
}
};
int dng_dump(const char* input_file_path)
{
gpr_allocator allocator;
allocator.Alloc = malloc;
allocator.Free = free;
gpr_buffer input_buffer = { NULL, 0 };
gpr_parameters params;
gpr_parameters_set_defaults(&params);
if( read_from_file( &input_buffer, input_file_path, allocator.Alloc, allocator.Free ) != 0 )
{
return -1;
}
int success = gpr_parse_metadata( &allocator, &input_buffer, &params );
if( success )
{
gpr_parameters_print( &params, NULL );
}
return 0;
}
int main(int argc, char *argv [])
{
my_argument_parser args;
char zerotag[MAX_STDOUT_LINE];
sprintf(zerotag, "[%5d-ms] ", 0);
char line[MAX_STDOUT_LINE];
sprintf( line, "GPR Tools Version %d.%d.%d [%s @ %s] ", GPR_VERSION_MAJOR, GPR_VERSION_MINOR, GPR_VERSION_REVISION, GIT_BRANCH, GIT_COMMIT_HASH );
if( args.parse(argc, argv, line, zerotag) )
{
printf("\n");
printf("-- Example Commnads (please see data/tests/run_tests.sh for more examples) --\n");
printf("GPR to DNG: \n");
printf(" %s -i ./data/samples/Hero6/GOPR0024.GPR -o ./data/samples/Hero6/GOPR0024.DNG \n\n", argv[0] );
printf("GPR to RGB (PPM format in 1000x750 resolution): \n");
printf(" %s -i ./data/samples/Hero6/GOPR0024.GPR -o ./data/samples/Hero6/GOPR0024.PPM -r 4:1 \n\n", argv[0] );
printf("GPR to RGB (JPG format in 500x375 resolution): \n");
printf(" %s -i ./data/samples/Hero6/GOPR0024.GPR -o ./data/samples/Hero6/GOPR0024.JPG -r 8:1 \n\n", argv[0] );
printf("Analyze a GPR or DNG file and output metadata parameters to a file: \n");
printf(" %s -i ./data/samples/Hero6/GOPR0024.GPR -d 1 > ./data/samples/Hero6/GOPR0024.TXT \n\n", argv[0] );
printf("Read RAW pixel data, along with gpr parameters (from a file) and apply to an output GPR or DNG file: \n");
printf(" %s -i ./data/samples/Hero6/GOPR0024.RAW -o ./data/samples/Hero6/GOPR0024.DNG -a ./data/samples/Hero6/GOPR0024.TXT \n\n", argv[0] );
return -1;
}
if( args.dump_gpr_parameters )
{
if( dng_dump(args.input_file_path.c_str()) != 0 )
return -1;
}
else
{
string ext = strrchr( args.input_file_path.c_str(),'.');
if( args.output_file_path == string("") && ( ext == string(".GPR") || ext == string(".gpr") ) )
{
args.output_file_path = args.input_file_path;
args.output_file_path.erase(args.output_file_path.find_last_of("."), string::npos);
args.output_file_path = args.output_file_path + string(".DNG");
}
}
fprintf( stderr, "%s Input File: %s \n", zerotag, args.input_file_path.c_str() );
fprintf( stderr, "%s Output File: %s \n", zerotag, args.output_file_path.c_str() );
if( args.output_file_path != "" )
{
return dng_convert_main(args.input_file_path.c_str(), args.input_width, args.input_height, args.input_pitch, args.input_skip_rows, args.input_pixel_format.c_str(),
args.output_file_path.c_str(), args.apply_gpr_parameters.c_str(), args.gpmf_file_path.c_str(), args.rgb_file_resolution.c_str(), args.rgb_file_bits,
args.jpg_preview_file_path.c_str(), args.jpg_preview_file_width, args.jpg_preview_file_height );
}
return 0;
}

Wyświetl plik

@ -0,0 +1,346 @@
/*! @file main_c.c
*
* @brief Implement C conversion routines used by gpr_tools
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "gpr.h"
#if defined __GNUC__
#define stricmp strcasecmp
#else
#endif // if defined __GNUC__
#include "main_c.h"
#include "gpr_parse_utils.h"
#include "gpr_print_utils.h"
#if GPR_JPEG_AVAILABLE
#include "jpeg.h"
#endif
#define MAX_FILE_PATH 256
typedef enum
{
FILE_TYPE_UNKNOWN = -1,
FILE_TYPE_RAW,
FILE_TYPE_GPR,
FILE_TYPE_DNG,
FILE_TYPE_PPM,
FILE_TYPE_JPG,
FILE_TYPE_COUNT,
} FILE_TYPE;
static FILE_TYPE GetFileType( const char* file_path )
{
const char *extension = NULL;
if (file_path == NULL) {
return FILE_TYPE_UNKNOWN;
}
// Get the pathname extension
extension = strrchr(file_path, '.');
if (extension == NULL)
{
return FILE_TYPE_UNKNOWN;
}
if (stricmp(extension, ".raw") == 0 || stricmp(extension, ".RAW") == 0)
{
return FILE_TYPE_RAW;
}
if (stricmp(extension, ".gpr") == 0 || stricmp(extension, ".GPR") == 0)
{
return FILE_TYPE_GPR;
}
if (stricmp(extension, ".dng") == 0 || stricmp(extension, ".DNG") == 0 )
{
return FILE_TYPE_DNG;
}
if (stricmp(extension, ".ppm") == 0 || stricmp(extension, ".PPM") == 0)
{
return FILE_TYPE_PPM;
}
if (stricmp(extension, ".jpg") == 0 || stricmp(extension, ".JPG") == 0)
{
return FILE_TYPE_JPG;
}
return FILE_TYPE_UNKNOWN;
}
int dng_convert_main(const char* input_file_path, unsigned int input_width, unsigned int input_height, size_t input_pitch, size_t input_skip_rows, const char* input_pixel_format,
const char* output_file_path, const char* metadata_file_path, const char* gpmf_file_path, const char* rgb_file_resolution, int rgb_file_bits,
const char* jpg_preview_file_path, int jpg_preview_file_width, int jpg_preview_file_height )
{
bool success;
bool write_buffer_to_file = true;
FILE_TYPE input_file_type = GetFileType( input_file_path );
FILE_TYPE output_file_type = GetFileType( output_file_path );
if( input_file_type == FILE_TYPE_UNKNOWN )
{
printf( "Unsupported input file type" );
return -1;
}
if( output_file_type == FILE_TYPE_UNKNOWN )
{
printf( "Unsupported output file type" );
return -1;
}
gpr_allocator allocator;
allocator.Alloc = malloc;
allocator.Free = free;
gpr_parameters params;
gpr_parameters_set_defaults(&params);
gpr_buffer input_buffer = { NULL, 0 };
if( read_from_file( &input_buffer, input_file_path, allocator.Alloc, allocator.Free ) != 0 )
{
return -1;
}
if( metadata_file_path && strcmp(metadata_file_path, "") )
{
if( gpr_parameters_parse( &params, metadata_file_path ) != 0 )
return -1;
}
else if( input_file_type == FILE_TYPE_GPR || input_file_type == FILE_TYPE_DNG )
{
gpr_parse_metadata( &allocator, &input_buffer, &params );
}
else
{
params.input_width = input_width;
params.input_height = input_height;
params.input_pitch = input_pitch;
int32_t saturation_level = params.tuning_info.dgain_saturation_level.level_red;
if( output_file_type == FILE_TYPE_GPR )
saturation_level = (1 << 14) - 1;
else if( output_file_type == FILE_TYPE_DNG )
saturation_level = (1 << 12) - 1;
if( strcmp(input_pixel_format, "rggb12") == 0 )
{
params.tuning_info.pixel_format = PIXEL_FORMAT_RGGB_12;
if( input_pitch == -1 )
input_pitch = input_width * 2;
}
if( strcmp(input_pixel_format, "rggb12p") == 0 )
{
params.tuning_info.pixel_format = PIXEL_FORMAT_RGGB_12P;
if( input_pitch == -1 )
input_pitch = (input_width * 3 / 4) * 2;
}
else if( strcmp(input_pixel_format, "rggb14") == 0 )
{
params.tuning_info.pixel_format = PIXEL_FORMAT_RGGB_14;
saturation_level = (1 << 14) - 1;
if( input_pitch == -1 )
input_pitch = input_width * 2;
}
else if( strcmp(input_pixel_format, "gbrg12") == 0 )
{
params.tuning_info.pixel_format = PIXEL_FORMAT_GBRG_12;
if( input_pitch == -1 )
input_pitch = input_width * 2;
}
else if( strcmp(input_pixel_format, "gbrg12p") == 0 )
{
params.tuning_info.pixel_format = PIXEL_FORMAT_GBRG_12P;
if( input_pitch == -1 )
input_pitch = (input_width * 3 / 4) * 2;
}
params.tuning_info.dgain_saturation_level.level_red = saturation_level;
params.tuning_info.dgain_saturation_level.level_green_even = saturation_level;
params.tuning_info.dgain_saturation_level.level_green_odd = saturation_level;
params.tuning_info.dgain_saturation_level.level_blue = saturation_level;
}
if( gpmf_file_path != NULL && strcmp(gpmf_file_path, "") )
{
read_from_file( &params.gpmf_payload, gpmf_file_path, allocator.Alloc, allocator.Free );
}
gpr_buffer output_buffer = { NULL, 0 };
if( input_skip_rows > 0 )
{
input_buffer.buffer = (unsigned char*)(input_buffer.buffer) + (input_skip_rows * input_pitch);
}
gpr_buffer preview = { NULL, 0 };
if( strcmp(jpg_preview_file_path, "") != 0 )
{
if( read_from_file( &preview, jpg_preview_file_path, allocator.Alloc, allocator.Free) == 0 )
{
params.preview_image.jpg_preview = preview;
params.preview_image.preview_width = jpg_preview_file_width;
params.preview_image.preview_height = jpg_preview_file_height;
}
}
if( input_file_type == FILE_TYPE_RAW && output_file_type == FILE_TYPE_DNG )
{
success = gpr_convert_raw_to_dng( &allocator, &params, &input_buffer, &output_buffer );
}
else if( input_file_type == FILE_TYPE_DNG && output_file_type == FILE_TYPE_RAW )
{
success = gpr_convert_dng_to_raw( &allocator, &input_buffer, &output_buffer );
}
else if( input_file_type == FILE_TYPE_DNG && output_file_type == FILE_TYPE_DNG )
{
success = gpr_convert_dng_to_dng( &allocator, &params, &input_buffer, &output_buffer );
}
#if GPR_WRITING
else if( input_file_type == FILE_TYPE_DNG && output_file_type == FILE_TYPE_GPR )
{
success = gpr_convert_dng_to_gpr( &allocator, &params, &input_buffer, &output_buffer );
}
else if( input_file_type == FILE_TYPE_RAW && output_file_type == FILE_TYPE_GPR )
{
success = gpr_convert_raw_to_gpr( &allocator, &params, &input_buffer, &output_buffer );
}
#endif
#if GPR_READING
else if( input_file_type == FILE_TYPE_GPR && ( output_file_type == FILE_TYPE_PPM || output_file_type == FILE_TYPE_JPG ) )
{
gpr_rgb_buffer rgb_buffer = { NULL, 0, 0, 0 };
GPR_RGB_RESOLUTION rgb_resolution = GPR_RGB_RESOLUTION_DEFAULT;
if( strcmp(rgb_file_resolution, "1:1") == 0 )
rgb_resolution = GPR_RGB_RESOLUTION_FULL;
else if( strcmp(rgb_file_resolution, "2:1") == 0 )
rgb_resolution = GPR_RGB_RESOLUTION_HALF;
else if( strcmp(rgb_file_resolution, "4:1") == 0 )
rgb_resolution = GPR_RGB_RESOLUTION_QUARTER;
else if( strcmp(rgb_file_resolution, "8:1") == 0 )
rgb_resolution = GPR_RGB_RESOLUTION_EIGHTH;
else if( strcmp(rgb_file_resolution, "16:1") == 0 )
rgb_resolution = GPR_RGB_RESOLUTION_SIXTEENTH;
if( output_file_type == FILE_TYPE_JPG && rgb_file_bits == 16 )
{
printf( "Asked to output 16-bits RGB, but that is only possible in PPM format.\n");
rgb_file_bits = 8;
}
success = gpr_convert_gpr_to_rgb( &allocator, rgb_resolution, rgb_file_bits, &input_buffer, &rgb_buffer );
if( output_file_type == FILE_TYPE_PPM )
{
#define PPM_HEADER_SIZE 100
char header_text[PPM_HEADER_SIZE];
if( rgb_file_bits == 8 )
{
// 8 bits
sprintf( header_text, "P6\n%ld %ld\n255\n", rgb_buffer.width, rgb_buffer.height );
}
else
{
// 16 bits
sprintf( header_text, "P6\n%ld %ld\n65535\n", rgb_buffer.width, rgb_buffer.height );
}
output_buffer.size = rgb_buffer.size + strlen( header_text );
output_buffer.buffer = allocator.Alloc( output_buffer.size );
char* buffer_c = (char*)output_buffer.buffer;
memcpy( buffer_c, header_text, strlen( header_text ) );
memcpy( buffer_c + strlen( header_text ), rgb_buffer.buffer, rgb_buffer.size );
#undef PPM_HEADER_SIZE
}
else if( output_file_type == FILE_TYPE_JPG )
{
write_buffer_to_file = false;
#if GPR_JPEG_AVAILABLE
tje_encode_to_file( output_file_path, rgb_buffer.width, rgb_buffer.height, 3, rgb_buffer.buffer );
#else
printf("JPG writing capability is disabled. You could still write to a PPM file");
#endif
}
allocator.Free( rgb_buffer.buffer );
}
else if( input_file_type == FILE_TYPE_GPR && output_file_type == FILE_TYPE_DNG )
{
success = gpr_convert_gpr_to_dng( &allocator, &params, &input_buffer, &output_buffer );
}
else if( input_file_type == FILE_TYPE_GPR && output_file_type == FILE_TYPE_RAW )
{
success = gpr_convert_gpr_to_raw( &allocator, &input_buffer, &output_buffer );
}
#endif
else
{
printf( "Unsupported conversion from %s to %s \n", input_file_path, output_file_path );
return -1;
}
if( success == 0 )
{
printf("Conversion failed \n");
return -1;
}
else if( write_buffer_to_file )
{
write_to_file( &output_buffer, output_file_path );
}
if( input_skip_rows > 0 )
{
input_buffer.buffer = (unsigned char*)(input_buffer.buffer) - (input_skip_rows * input_pitch);
}
if( preview.buffer )
{
allocator.Free( preview.buffer );
}
gpr_parameters_destroy(&params, allocator.Free);
return 0;
}

Wyświetl plik

@ -0,0 +1,34 @@
/*! @file main_c.h
*
* @brief Definition of C conversion routines used by gpr_tools
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MAIN_C_H
#define MAIN_C_H
#ifdef __cplusplus
extern "C" {
#endif
int dng_convert_main(const char* input_file_path, unsigned int input_width, unsigned int input_height, size_t input_pitch, size_t input_skip_rows, const char* input_pixel_format,
const char* output_file_path, const char* exiftool_file_path, const char* gpmf_file_path, const char* rgb_file_resolution, int rgb_file_bits,
const char* jpg_preview_file_path, int jpg_preview_file_width, int jpg_preview_file_height );
#ifdef __cplusplus
}
#endif
#endif // MAIN_C_H

Wyświetl plik

@ -0,0 +1,138 @@
/*! @file stdcpp_utils.h
*
* @brief Implement some standard C++ routines using templates
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef STDCPP_UTILS_H
#define STDCPP_UTILS_H
#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <vector>
#include <algorithm>
#include <vector>
#include <functional>
#include <cctype>
#include <stdio.h>
#include <string.h>
std::string& ltrim(std::string& s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(),
std::ptr_fun<int, int>(std::isgraph)));
return s;
}
std::string& rtrim(std::string& s)
{
s.erase(std::find_if(s.rbegin(), s.rend(),
std::ptr_fun<int, int>(std::isgraph)).base(), s.end());
return s;
}
std::string& trim(std::string& s)
{
return ltrim(rtrim(s));
}
std::vector<std::string> tokenizer( const std::string& p_pcstStr, char delim ) {
std::vector<std::string> tokens;
std::stringstream mySstream( p_pcstStr );
std::string temp;
while( getline( mySstream, temp, delim ) ) {
tokens.push_back( temp );
}
return tokens;
}
template<class T>
bool find_key( std::map<std::string, std::string> hash, const std::string key, T& value )
{
std::map<std::string, std::string>::iterator it = hash.find( key.c_str() );
if(it != hash.end())
{
value = atoi( it->second.c_str() );
return true;
}
return false;
}
template<>
bool find_key<std::string>( std::map<std::string, std::string> hash, const std::string key, std::string& value )
{
std::map<std::string, std::string>::iterator it = hash.find( key.c_str() );
if(it != hash.end())
{
value = it->second;
return true;
}
return false;
}
template<class T>
bool find_key( std::map<std::string, std::string> hash, const std::string key, T& value_numerator, T& value_denominator )
{
std::map<std::string, std::string>::iterator it = hash.find( key.c_str() );
if(it != hash.end())
{
std::string fraction = it->second;
std::vector<std::string> tokens = tokenizer( fraction, '/' );
value_numerator = atoi( tokens[0].c_str() );
if( tokens.size() == 2 )
value_denominator = atoi( tokens[1].c_str() );
else
value_denominator = 1;
return true;
}
return false;
}
template<class T>
static T parse_field(const char *tuning_sring, const char *field_name, const char* format_specifier, T default_val, bool* found = NULL )
{
const char *foundStr = strstr(tuning_sring, field_name);
T ret_data;
if (foundStr)
{
sscanf(foundStr + strlen(field_name), format_specifier, &ret_data);
if(found)
*found = true;
return ret_data;
}
if(found)
*found = false;
return default_val;
}
#endif // STDCPP_UTILS_H

Wyświetl plik

@ -0,0 +1,25 @@
# executable
set( EXE_NAME vc5_decoder_app )
# get source and include files
file( GLOB DECODER_SRC_FILES "*.c" "*.cpp" )
file( GLOB DECODER_INC_FILES "*.h" "../common/*.h" )
# add include files from other folders
include_directories( "../common" )
include_directories( "../common/argument_parser" )
include_directories( "../../lib/common/private" )
include_directories( "../../lib/common/public" )
include_directories( "../../lib/vc5_common" )
include_directories( "../../lib/vc5_decoder" )
include_directories( "../../lib/md5_lib" )
add_definitions("-DGPR_READING=1")
# add executable
add_executable( ${EXE_NAME} ${DECODER_SRC_FILES} ${DECODER_INC_FILES} ${COMMON_SRC_FILES} ${COMMON_INC_FILES} )
target_link_libraries( ${EXE_NAME} vc5_decoder vc5_common common md5_lib argument_parser )
# set the folder where to place the projects
set_target_properties( ${EXE_NAME} PROPERTIES FOLDER app )

Wyświetl plik

@ -0,0 +1,223 @@
/*! @file main.cpp
*
* @brief Main program file for the sample vc5 decoder.
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "stdc_includes.h"
#include "stdcpp_includes.h"
#if GPR_READING
#include "vc5_decoder.h"
#endif
#include "argument_parser.h"
#include "timer.h"
#include "gpr_buffer.h"
#include "log.h"
#include "logcurve.h"
#include "common_app_def.h"
#define DECODER_RUN_COUNT 1
using namespace std;
class my_argument_parser : public argument_parser
{
protected:
bool help;
bool verbose;
public:
string log_curve_file_path;
string output_pixel_format;
string input_file_path;
string output_file_path;
public:
bool get_verbose() { return verbose; }
bool get_help() { return help; }
void set_options()
{
command_options.addOptions()
/* long and short name */ /* variable to update */ /* default value */ /* help text */
("help", help, false, "Prints this help text")
("verbose", verbose, false, "Verbosity of the output")
("InputFilePath,i", input_file_path, string(""), "Input file path")
("OutputPixelFormat,x", output_pixel_format, string("rggb14"), "Output pixel format [rggb12, rggb12p, rggb14, gbrg12, gbrg12p]")
("OutputFilePath,o", output_file_path, string(""), "Output file path")
("PrintLogCurve,l", log_curve_file_path, string(""), "File for encoding log curve output");
;
}
};
/*!
@brief Main entry point for the reference decoder
The program takes two arguments: the pathname to the file that contains a
sample to decode and the pathname to the output file for the decoded image.
The input file should contain a single encoded sample without any header.
The output file can be a DPX file, otherwise the decoded image is written to the output
file without a header.
The image is decoded to the same dimensions as the encoded image and the decoded format
is the same format as the original source image input to the encoder.
*/
int main(int argc, char *argv[])
{
my_argument_parser args;
char line[MAX_STDOUT_LINE];
sprintf( line, "VC5 Decoder Version %d.%d.%d [%s @ %s] ", VC5_VERSION_MAJOR, VC5_VERSION_MINOR, VC5_VERSION_REVISION, GIT_BRANCH, GIT_COMMIT_HASH );
if( args.parse(argc, argv, line, "[0000000000]" ) )
return -1;
int i;
CODEC_ERROR error = CODEC_ERROR_OKAY;
vc5_decoder_parameters vc5_decoder_params;
vc5_decoder_parameters_set_default(&vc5_decoder_params);
vc5_decoder_params.enabled_parts = VC5_ENABLED_PARTS;
vc5_decoder_params.mem_alloc = malloc;
vc5_decoder_params.mem_free = free;
if( strcmp(args.output_pixel_format.c_str(), "rggb12") == 0 )
{
vc5_decoder_params.pixel_format = VC5_DECODER_PIXEL_FORMAT_RGGB_12;
}
else if( strcmp(args.output_pixel_format.c_str(), "rggb14") == 0 )
{
vc5_decoder_params.pixel_format = VC5_DECODER_PIXEL_FORMAT_RGGB_14;
}
else if( strcmp(args.output_pixel_format.c_str(), "gbrg12") == 0 )
{
vc5_decoder_params.pixel_format = VC5_DECODER_PIXEL_FORMAT_GBRG_12;
}
else if( strcmp(args.output_pixel_format.c_str(), "gbrg14") == 0 )
{
vc5_decoder_params.pixel_format = VC5_DECODER_PIXEL_FORMAT_GBRG_14;
}
else
{
LogPrint("Invalid output format: %s", args.output_pixel_format.c_str());
return -1;
}
LogInit();
gpr_buffer vc5_image = { NULL, 0 };
// Print the flags indicating which parts are enabled for this encoder
LogPrint("Vc5 Input image: %s", args.input_file_path.c_str() );
LogPrint("Raw Output file: %s", args.output_file_path.c_str() );
if( read_from_file( &vc5_image, args.input_file_path.c_str(), vc5_decoder_params.mem_alloc, vc5_decoder_params.mem_free ) )
{
LogPrint("Could not read input file: %s", args.input_file_path.c_str());
exit(-1);
}
TIMER timer; // Performance timer
InitTimer(&timer);
for (i = 0; i < DECODER_RUN_COUNT; i++)
{ // Decode all frames
gpr_buffer raw_image = { NULL, 0 };
gpr_rgb_buffer rgb_image = { NULL, 0, 0, 0 };
StartTimer(&timer);
LogPrint("%d ", i);
vc5_decoder_process( &vc5_decoder_params, &vc5_image, &raw_image, &rgb_image );
StopTimer(&timer);
fflush(stdout);
assert( raw_image.buffer && raw_image.size > 0 );
if( write_to_file( &raw_image, args.output_file_path.c_str() ) )
{
LogPrint("Error writing bitstream to location %s", args.output_file_path.c_str() );
return -1;
}
if( raw_image.buffer )
{
vc5_decoder_params.mem_free(raw_image.buffer);
}
if( rgb_image.buffer )
{
vc5_decoder_params.mem_free(rgb_image.buffer);
}
}
LogPrint("Decoding %.3f secs per frame", TimeSecs(&timer) / DECODER_RUN_COUNT );
if( args.log_curve_file_path != "" )
{
LogPrint("Printing log curve to %s", args.log_curve_file_path.c_str() );
ofstream file;
file.open ( args.log_curve_file_path.c_str() );
for( int i = 0; i < LOG_CURVE_TABLE_LENGTH; i++ )
{
file.fill( '0' );
file.width( 4 );
file << i;
file << ": ";
file.fill( '0' );
file.width( 4 );
file << (DecoderLogCurve[i] >> 4);
file << endl;
}
file.close();
}
if( vc5_image.buffer )
{
vc5_decoder_params.mem_free( vc5_image.buffer );
}
LogUninit();
return error;
}

Wyświetl plik

@ -0,0 +1,25 @@
# executable
set( EXE_NAME vc5_encoder_app )
# get source and include files
file( GLOB ENCODER_SRC_FILES "*.c" "*.cpp" )
file( GLOB ENCODER_INC_FILES "*.h" "../common/*.h" )
# add include files from other folders
include_directories( "../common" )
include_directories( "../common/argument_parser" )
include_directories( "../../lib/common/private" )
include_directories( "../../lib/common/public" )
include_directories( "../../lib/vc5_common" )
include_directories( "../../lib/vc5_encoder" )
include_directories( "../../lib/md5_lib" )
add_definitions("-DGPR_WRITING=1")
# add executable
add_executable( ${EXE_NAME} ${ENCODER_SRC_FILES} ${ENCODER_INC_FILES} ${COMMON_SRC_FILES} ${COMMON_INC_FILES} )
target_link_libraries( ${EXE_NAME} vc5_encoder vc5_common common md5_lib argument_parser )
# set the folder where to place the projects
set_target_properties( ${EXE_NAME} PROPERTIES FOLDER app )

Wyświetl plik

@ -0,0 +1,283 @@
/*! @file main.cpp
*
* @brief Main program file for the sample vc5 encoder.
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "stdc_includes.h"
#include "stdcpp_includes.h"
#include "vc5_encoder.h"
#include "argument_parser.h"
#include "timer.h"
#include "gpr_buffer.h"
#include "md5.h"
#include "log.h"
#include "logcurve.h"
#include "common_app_def.h"
using namespace std;
class my_argument_parser : public argument_parser
{
protected:
bool help;
bool verbose;
public:
bool validate;
bool dump_info;
int input_width;
int input_height;
int input_pitch;
int input_skip_rows;
string log_curve_file_path;
string input_pixel_format;
string input_file_path;
string output_file_path;
public:
bool get_verbose() { return verbose; }
bool get_help() { return help; }
void set_options()
{
command_options.addOptions()
/* long and short name */ /* variable to update */ /* default value */ /* help text */
("help", help, false, "Prints this help text")
("verbose", verbose, false, "Verbosity of the output")
("InputFilePath,i", input_file_path, string(""), "Input file path")
("InputWidth,w", input_width, 4000, "Input image width in pixel samples e.g. 4000")
("InputHeight,h", input_height, 3000, "Input image height in pixel samples e.g. 3000")
("InputPitch,p", input_pitch, -1, "Input image pitch in bytes e.g. 8000")
("InputPixelFormat,x", input_pixel_format, string("rggb14"), "Input pixel format [rggb12, rggb12p, rggb14, gbrg12, gbrg12p]")
("OutputFilePath,o", output_file_path, string(""), "Output file path")
("PrintLogCurve,l", log_curve_file_path, string(""), "File for encoding log curve output");
;
}
};
/*!
@brief Main entry point for the reference encoder
Usage: encoder [options] input output
The input argument is the pathname to a file that contains a single image that
is the input the image unpacking process (see @ref ImageUnpackingProcess). The output argument is
the pathname to a file that will contain the encoded bitstream_file. Media containers are not
currently supported by the reference encoder. The command-line options are described in @ref ParseParameters.
*/
int main(int argc, char *argv[])
{
my_argument_parser args;
LogInit();
char line[MAX_STDOUT_LINE];
sprintf( line, "VC5 Encoder Version %d.%d.%d [%s @ %s] ", VC5_VERSION_MAJOR, VC5_VERSION_MINOR, VC5_VERSION_REVISION, GIT_BRANCH, GIT_COMMIT_HASH );
if( args.parse(argc, argv, line, "[0000000000]") )
return -1;
int encoder_run;
int encoder_run_count = 1;
CODEC_ERROR error = CODEC_ERROR_OKAY;
vc5_encoder_parameters vc5_encoder_params;
vc5_encoder_parameters_set_default(&vc5_encoder_params);
vc5_encoder_params.enabled_parts = VC5_ENABLED_PARTS;
vc5_encoder_params.input_width = args.input_width;
vc5_encoder_params.input_height = args.input_height;
vc5_encoder_params.input_pitch = args.input_pitch;
vc5_encoder_params.mem_alloc = malloc;
vc5_encoder_params.mem_free = free;
if( strcmp(args.input_pixel_format.c_str(), "rggb12") == 0 )
{
vc5_encoder_params.pixel_format = VC5_ENCODER_PIXEL_FORMAT_RGGB_12;
if( args.input_pitch == -1 )
vc5_encoder_params.input_pitch = args.input_width * 2;
}
if( strcmp(args.input_pixel_format.c_str(), "rggb12p") == 0 )
{
vc5_encoder_params.pixel_format = VC5_ENCODER_PIXEL_FORMAT_RGGB_12P;
if( args.input_pitch == -1 )
vc5_encoder_params.input_pitch = (args.input_width * 3 / 4) * 2;
}
else if( strcmp(args.input_pixel_format.c_str(), "rggb14") == 0 )
{
vc5_encoder_params.pixel_format = VC5_ENCODER_PIXEL_FORMAT_RGGB_14;
if( args.input_pitch == -1 )
args.input_pitch = args.input_width * 2;
}
else if( strcmp(args.input_pixel_format.c_str(), "gbrg12") == 0 )
{
vc5_encoder_params.pixel_format = VC5_ENCODER_PIXEL_FORMAT_GBRG_12;
if( args.input_pitch == -1 )
args.input_pitch = args.input_width * 2;
}
else if( strcmp(args.input_pixel_format.c_str(), "gbrg12p") == 0 )
{
vc5_encoder_params.pixel_format = VC5_ENCODER_PIXEL_FORMAT_GBRG_12P;
if( args.input_pitch == -1 )
args.input_pitch = (args.input_width * 3 / 4) * 2;
}
else
{
LogPrint("Invalid input format: %s", args.input_pixel_format.c_str());
return -1;
}
gpr_buffer raw_image = { NULL, 0 };
// Print the flags indicating which parts are enabled for this encoder
LogPrint("Raw Input image: %s", args.input_file_path.c_str() );
LogPrint("Vc5 Output file: %s", args.output_file_path.c_str() );
if( read_from_file( &raw_image, args.input_file_path.c_str(), vc5_encoder_params.mem_alloc, vc5_encoder_params.mem_free ) )
{
LogPrint("Could not read input file: %s", args.input_file_path.c_str());
return -1;
}
TIMER timer;
InitTimer(&timer);
unsigned char old_digest[MD5_DIGEST_SIZE];
for (encoder_run = 0; encoder_run < encoder_run_count; encoder_run++)
{
gpr_buffer vc5_image = { NULL, 0 };
StartTimer(&timer);
vc5_encoder_process( &vc5_encoder_params, &raw_image, &vc5_image, NULL );
StopTimer(&timer);
assert( vc5_image.buffer && vc5_image.size > 0 );
if( write_to_file( &vc5_image, args.output_file_path.c_str() ) )
{
LogPrint("Error writing bitstream to location %s", args.output_file_path.c_str() );
return -1;
}
{
static const char* hex = "0123456789ABCDEF";
unsigned char digest[MD5_DIGEST_SIZE];
context_md5_t ctx;
MD5Init(&ctx);
MD5Update(&ctx, (unsigned char *)vc5_image.buffer, vc5_image.size );
MD5Final(digest, &ctx);
{
int i;
unsigned char logged_digest[MD5_DIGEST_SIZE * 2 + 1];
for (i = 0; i < MD5_DIGEST_SIZE; i++)
{
logged_digest[i * 2 + 0] = hex[ digest[i] >> 4 ];
logged_digest[i * 2 + 1] = hex[ digest[i] & 0xf ];
}
logged_digest[i * 2] = '\0';
LogPrint("%d %s", encoder_run, logged_digest);
}
if( encoder_run > 0 )
{
if( memcmp(old_digest, digest, sizeof(digest) ) )
{
LogPrint("ERROR digests in run %d and %d do not match", encoder_run, encoder_run - 1 );
return -1;
}
}
memcpy(old_digest, digest, sizeof(digest));
}
vc5_encoder_params.mem_free(vc5_image.buffer);
}
LogPrint("Encoding %.3f secs per frame", TimeSecs(&timer) / encoder_run_count );
if( args.log_curve_file_path != "" )
{
LogPrint("Printing log curve to %s", args.log_curve_file_path.c_str() );
ofstream file;
file.open ( args.log_curve_file_path.c_str() );
for( int i = 0; i < LOG_CURVE_TABLE_LENGTH; i++ )
{
file.fill( '0' );
file.width( 4 );
file << i;
file << ": ";
file.fill( '0' );
file.width( 4 );
file << EncoderLogCurve[i];
file << endl;
}
file.close();
}
if( raw_image.buffer )
{
vc5_encoder_params.mem_free( raw_image.buffer );
}
LogUninit();
return error;
}

Wyświetl plik

@ -0,0 +1,18 @@
# library
set( LIB_NAME common )
# get source files
file( GLOB SRC_FILES "private/*.cpp" "private/*.c" )
# get include files
file( GLOB INC_FILES "private/*.h" "public/*.h" )
include_directories( "./public" )
# library
add_library( ${LIB_NAME} STATIC ${SRC_FILES} ${INC_FILES} )
target_link_libraries( ${LIB_NAME} )
# set the folder where to place the projects
set_target_properties( ${LIB_NAME} PROPERTIES FOLDER lib )

Wyświetl plik

@ -0,0 +1,44 @@
/*! @file gpr_allocator.c
*
* @brief Implementation of the global memory allocation functions.
* In order to customize memory allocation and deallocation, applications
* can implement these functions in additional files and include in
* build process
*
* @version 1.0.0
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "gpr_allocator.h"
/*!
@brief Allocate a block with the specified size
*/
void* gpr_global_malloc(size_t size)
{
return malloc(size);
}
/*!
@brief Free a block that was allocated by the specified allocator
It is an error to free a block allocated by one allocator using a
different allocator.
*/
void gpr_global_free(void *block)
{
free(block);
}

Wyświetl plik

@ -0,0 +1,97 @@
/*! @file gpr_buffer.c
*
* @brief Implementation of gpr_buffer object and functions that work on buffer
*
* @version 1.0.0
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "gpr_buffer.h"
#include "macros.h"
#include "stdc_includes.h"
int read_from_file(gpr_buffer* buffer, const char* file_path, gpr_malloc malloc_function, gpr_free free_function)
{
assert( buffer != NULL );
FILE *fIN = fopen(file_path, "rb");
if (fIN == NULL)
{
fprintf (stderr, "Error while reading file: %s", file_path);
return -1;
}
fseek (fIN, 0, SEEK_END);
buffer->size = (int32_t) ftell(fIN);
rewind (fIN);
buffer->buffer = malloc_function(buffer->size);
if ( buffer->buffer == NULL)
{
fputs ("Memory error", stderr);
return -1;
}
long result = fread(buffer->buffer, 1, buffer->size, fIN);
if (result != buffer->size)
{
free_function(buffer->buffer);
fputs ("Reading error", stderr);
return -1;
}
fclose(fIN);
return 0;
}
int write_to_file(const gpr_buffer* buffer, const char* file_path)
{
unsigned int bytes_written;
FILE *fOUT = fopen(file_path, "wb");
if (fOUT == NULL)
{
fprintf (stderr, "Error while writing file: %s", file_path);
return -1;
}
bytes_written = fwrite(buffer->buffer, 1, buffer->size, fOUT);
if( bytes_written != buffer->size ) {
fputs("Could not write bytes \n", stderr);
perror("fwrite()");
return -2;
}
fclose(fOUT);
return 0;
}
#include "gpr_rgb_buffer.h"
void gpr_rgb_gain_set_defaults(gpr_rgb_gain* x)
{
x->r_gain_num = 30;
x->r_gain_pow2_den = 4;
x->g_gain_num = 1;
x->g_gain_pow2_den = 0;
x->b_gain_num = 7;
x->b_gain_pow2_den = 2;
}

Wyświetl plik

@ -0,0 +1,45 @@
/*! @file gpr_buffer_auto.cpp
*
* @brief Implementation of gpr_buffer_auto object.
*
* @version 1.0.0
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "gpr_buffer.h"
#include "gpr_buffer_auto.h"
#include <stdlib.h>
int gpr_buffer_auto::read_from_file(const char* file_path)
{
assert( is_valid() == false );
int return_code = ::read_from_file(&buffer, file_path, mem_alloc, mem_free );
if( return_code == 0 )
{
free_in_destructor = true;
}
return return_code;
}
int gpr_buffer_auto::write_to_file(const char* file_path)
{
assert( is_valid() );
return ::write_to_file(&buffer, file_path);
}

Wyświetl plik

@ -0,0 +1,148 @@
/*! @file gpr_internal_buffer
*
* @brief Declaration of gpr_buffer_auto object. This object
* implements a buffer that carries size information. gpr_buffer_auto can
* deallocate itself in destructor (depending on free_in_destructor member)
*
* @version 1.0.0
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GPR_INTERNAL_BUFFER_H
#define GPR_INTERNAL_BUFFER_H
#include "gpr_allocator.h"
#include "gpr_buffer.h"
#include "gpr_platform.h"
#include "stdc_includes.h"
class gpr_buffer_auto
{
private:
gpr_buffer buffer;
bool free_in_destructor;
gpr_malloc mem_alloc;
gpr_free mem_free;
public:
void reset()
{
buffer.buffer = NULL;
buffer.size = 0;
free_in_destructor = false;
}
gpr_buffer_auto(gpr_malloc malloc_function, gpr_free free_function)
{
reset();
mem_alloc = malloc_function;
mem_free = free_function;
}
~gpr_buffer_auto()
{
deallocate();
}
void allocate(size_t size_of_memory)
{
assert(buffer.buffer == NULL);
assert(buffer.size == 0);
buffer.size = size_of_memory;
if(buffer.size > 0)
{
buffer.buffer = mem_alloc(buffer.size);
assert(buffer.buffer);
free_in_destructor = true;
}
}
void deallocate()
{
if(buffer.buffer && free_in_destructor)
mem_free( (char*)buffer.buffer );
reset();
}
void resize( size_t new_size )
{
buffer.size = new_size;
assert(buffer.buffer);
assert(buffer.size);
}
void set(void* _buffer, size_t _size, bool _free_in_destructor = false )
{
assert(buffer.buffer == NULL);
assert(buffer.size == 0);
buffer.buffer = _buffer;
buffer.size = _size;
free_in_destructor = _free_in_destructor;
assert(buffer.buffer);
assert(buffer.size);
}
void zero()
{
// Cant call zero for the case when buffer has been preallocated
// Call deallocate()
assert( free_in_destructor == false );
buffer.buffer = NULL;
buffer.size = 0;
}
bool is_valid() const
{
return ( buffer.buffer != NULL ) && buffer.size > 0;
}
// Accessors
void* get_buffer() const { return buffer.buffer; }
char* to_char() const { return (char*)buffer.buffer; }
unsigned char* to_uchar() const { return (unsigned char*)buffer.buffer; }
unsigned short* to_ushort() const { return (unsigned short*)buffer.buffer; }
uint16_t* to_uint16_t() const { return (uint16_t*)buffer.buffer; }
size_t get_size() const { return buffer.size; }
gpr_malloc get_malloc() const { return mem_alloc; }
gpr_free get_free() const { return mem_free; }
// Operations
int read_from_file(const char* file_path);
int write_to_file(const char* file_path);
const gpr_buffer& get_gpr_buffer() { return buffer; }
};
#endif // GPR_INTERNAL_BUFFER_H

Wyświetl plik

@ -0,0 +1,60 @@
/*! @file gpr_log.c
*
* @brief Implementation of functions used for logging
*
* @version 1.0.0
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "timer.h"
#include "stdc_includes.h"
TIMER LogTimer;
bool LogInit()
{
InitTimer(&LogTimer);
return true;
}
#ifndef LogPrint
int LogPrint(const char* format, ... )
{
StopTimer(&LogTimer);
printf("[%5d-ms] ", (unsigned int)TimeMSecs(&LogTimer));
{
va_list argptr;
va_start(argptr, format);
vfprintf(stdout, format, argptr);
va_end(argptr);
}
printf( "%c", '\n' );
StartTimer(&LogTimer);
return 0;
}
#endif // LogPrint
bool LogUninit()
{
return true;
}

Wyświetl plik

@ -0,0 +1,60 @@
/*! @file gpr_log.h
*
* @brief Declatation of functions used for logging
*
* @version 1.0.0
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GPR_LOG_H
#define GPR_LOG_H
#ifdef __cplusplus
extern "C" {
#endif
bool LogInit();
#ifndef LogPrint
int LogPrint(const char* format, ... );
#endif
bool LogUninit();
#define TIMESTAMP(x, y) TIMESTAMP_##y(x)
#if GPR_TIMING == 0
#define TIMESTAMP_3(x)
#define TIMESTAMP_2(x)
#define TIMESTAMP_1(x)
#elif GPR_TIMING == 1
#define TIMESTAMP_3(x)
#define TIMESTAMP_2(x)
#define TIMESTAMP_1(x) LogPrint("%s %s() %s (line %d)", x, __FUNCTION__, __FILE__, __LINE__);
#elif GPR_TIMING == 2
#define TIMESTAMP_3(x)
#define TIMESTAMP_2(x) LogPrint("%s %s() %s (line %d)", x, __FUNCTION__, __FILE__, __LINE__);
#define TIMESTAMP_1(x) LogPrint("%s %s() %s (line %d)", x, __FUNCTION__, __FILE__, __LINE__);
#elif GPR_TIMING == 3
#define TIMESTAMP_3(x) LogPrint("%s %s() %s (line %d)", x, __FUNCTION__, __FILE__, __LINE__);
#define TIMESTAMP_2(x) LogPrint("%s %s() %s (line %d)", x, __FUNCTION__, __FILE__, __LINE__);
#define TIMESTAMP_1(x) LogPrint("%s %s() %s (line %d)", x, __FUNCTION__, __FILE__, __LINE__);
#endif
#ifdef __cplusplus
}
#endif
#endif // GPR_LOG_H

Wyświetl plik

@ -0,0 +1,84 @@
/*! @file gpr_macros.h
*
* @brief Definitions of useful inline functions that are used everywhere in code.
*
* @version 1.0.0
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GPR_MACROS_H
#define GPR_MACROS_H
#ifndef neg
#define neg(x) (-(x))
#endif
#define DivideByShift(x, s) ((x) >> (s))
STATIC_INLINE uint16_t clamp_uint(int32_t value, uint32_t precision)
{
const int32_t limit = ((1 << precision) - 1);
if (value < 0)
value = 0;
else if (value > limit)
value = limit;
return (uint16_t)value;
}
STATIC_INLINE uint16_t clamp_uint16(int32_t value)
{
return (uint16_t)clamp_uint( value, 16);
}
STATIC_INLINE uint16_t clamp_uint14(int32_t value)
{
return (uint16_t)clamp_uint( value, 14);
}
STATIC_INLINE uint16_t clamp_uint12(int32_t value)
{
return (uint16_t)clamp_uint( value, 12);
}
STATIC_INLINE uint8_t clamp_uint8(int32_t value)
{
return (uint8_t)clamp_uint( value, 8);
}
STATIC_INLINE int minimum(int a, int b)
{
return (a < b) ? a : b;
}
STATIC_INLINE int maximum(int a, int b)
{
return (a < b) ? b : a;
}
STATIC_INLINE int absolute(int a)
{
return (a < 0) ? -a : a;
}
STATIC_INLINE uint32_t Swap32(uint32_t value)
{
value = (value & 0x0000FFFF) << 16 | (value & 0xFFFF0000) >> 16;
value = (value & 0x00FF00FF) << 8 | (value & 0xFF00FF00) >> 8;
return value;
}
#endif // GPR_MACROS_H

Wyświetl plik

@ -0,0 +1,33 @@
/*! @file stdc_includes.h
*
* @brief Standard C include files used by package
*
* @version 1.0.0
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <ctype.h>
#include <assert.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>

Wyświetl plik

@ -0,0 +1,22 @@
/*! @file stdcpp_includes.h
*
* @brief Standard C++ include files used by package
*
* @version 1.0.0
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <fstream>

Wyświetl plik

@ -0,0 +1,54 @@
/*! @file gpr_timer.c
*
* @brief Implementation of a high-resolution performance timer.
*
* @version 1.0.0
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "timer.h"
/*!
@brief Initialize a timer
The frequency of the performance timer is determined if it has not
already been obtained.
*/
void InitTimer(TIMER *timer)
{
timer->begin = 0;
timer->elapsed = 0;
}
void StartTimer(TIMER *timer)
{
timer->begin = clock();
}
void StopTimer(TIMER *timer)
{
timer->elapsed += (clock() - timer->begin);
}
float TimeSecs(TIMER *timer)
{
return (float)(timer->elapsed) / CLOCKS_PER_SEC;
}
float TimeMSecs(TIMER *timer)
{
return (float)(TimeSecs(timer) * 1000);
}

Wyświetl plik

@ -0,0 +1,51 @@
/*! @file gpr_timer.h
*
* @brief Declaration of a high-resolution performance timer.
*
* @version 1.0.0
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GPR_TIMER_H
#define GPR_TIMER_H
#include <time.h>
typedef struct timer
{
clock_t begin;
clock_t elapsed;
} TIMER;
#ifdef __cplusplus
extern "C" {
#endif
void InitTimer(TIMER *timer);
void StartTimer(TIMER *timer);
void StopTimer(TIMER *timer);
float TimeSecs(TIMER *timer);
float TimeMSecs(TIMER *timer);
#ifdef __cplusplus
}
#endif
#endif // GPR_TIMER_H

Wyświetl plik

@ -0,0 +1,50 @@
/*! @file gpr_allocator.h
*
* @brief The API for memory allocation and deallocation functions.
*
* @version 1.0.0
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GPR_ALLOCATOR_H
#define GPR_ALLOCATOR_H
#include "gpr_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
extern void* gpr_global_malloc(size_t size);
extern void gpr_global_free(void *block);
typedef void* (*gpr_malloc)(size_t size); /* Malloc callback function typedef */
typedef void (*gpr_free)(void* p); /* Free callback function typedef */
typedef struct
{
gpr_malloc Alloc; // Callback function to allocate memory
gpr_free Free; // Callback function to free memory
} gpr_allocator;
#ifdef __cplusplus
}
#endif
#endif // GPR_ALLOCATOR_H

Wyświetl plik

@ -0,0 +1,47 @@
/*! @file gpr_buffer.h
*
* @brief Declaration of gpr_buffer object and functions that work on buffer
*
* @version 1.0.0
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GPR_BUFFER_H
#define GPR_BUFFER_H
#include "gpr_allocator.h"
#include "gpr_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
void* buffer; /* Address to the memory location that this buffer points to */
size_t size; /* Size of the memory block */
} gpr_buffer;
int read_from_file(gpr_buffer* buffer, const char* file_path, gpr_malloc malloc_function, gpr_free free_function);
int write_to_file(const gpr_buffer* buffer, const char* file_path);
#ifdef __cplusplus
}
#endif
#endif // GPR_BUFFER_H

Wyświetl plik

@ -0,0 +1,162 @@
/*! @file gpr_platform.h
*
* @brief Definitions of platform related settings
*
* @version 1.0.0
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GPR_PLATFORM_H
#define GPR_PLATFORM_H
// =================================================================================================
// Timing output. Define to:
// 0 for applications (disabled all timing code)
// 1 to enable top level timing
// 2 to enable low level timing
// =================================================================================================
#ifndef GPR_TIMING
#define GPR_TIMING 1
#endif
// =================================================================================================
// Defines to enable encoder and decoder API in GPR-SDK
// =================================================================================================
#ifndef GPR_WRITING
#define GPR_WRITING 1
#endif
#ifndef GPR_READING
#define GPR_READING 1
#endif
#ifndef GPR_JPEG_AVAILABLE
#define GPR_JPEG_AVAILABLE 1
#endif
// =================================================================================================
// Flags to enable/disable SIMD code
// =================================================================================================
// Neon code is implemented for encoder
#ifndef NEON
#define NEON 0
#endif
// SSE code is not implemented yet
#ifndef SSE
#define SSE 0
#endif
// =================================================================================================
// Do not change lines below
// =================================================================================================
// =================================================================================================
// Common header files needed by GPR-SDK
// =================================================================================================
#include <stdlib.h>
#include <stdint.h>
#ifndef float_t
typedef float float_t;
#endif
#ifdef _WIN32
// Turn off warnings about deprecated functions
#pragma warning(disable: 4996)
#define INLINE __inline
#else
#define INLINE inline
#endif // _WIN32
#define STATIC static
#define STATIC_INLINE STATIC INLINE
#define ENABLED(x) (x)
// =================================================================================================
// Determine the Platform
// =================================================================================================
#ifdef _WIN32
#define qWinOS 1
#define qMacOS 0
#define qLinux 0
#define qiPhone 0
#define qAndroid 0
#elif __APPLE__
#include "TargetConditionals.h"
#define qEnableCarbon 0 // Disable Carbon API because it is old and deprecated by Apple
#if TARGET_OS_IPHONE
#define qWinOS 0
#define qMacOS 0
#define qLinux 0
#define qiPhone 1
#define qAndroid 0
#else
#define qWinOS 0
#define qMacOS 1
#define qLinux 0
#define qiPhone 0
#define qAndroid 0
#endif
#elif __ANDROID__
#define qWinOS 0
#define qMacOS 0
#define qLinux 0
#define qiPhone 0
#define qAndroid 1
#elif __linux__ || __unix__
#define qWinOS 0
#define qMacOS 0
#define qLinux 1
#define qiPhone 0
#define qAndroid 0
#else
#error "XMP environment error - Unknown compiler"
#endif
// =================================================================================================
// GPR version numbering
// =================================================================================================
#define GPR_VERSION_MAJOR 1
#define GPR_VERSION_MINOR 0
#define GPR_VERSION_REVISION 0
#endif // GPR_PLATFORM_H

Wyświetl plik

@ -0,0 +1,77 @@
/*! @file gpr_buffer.h
*
* @brief Declaration of gpr_rgb_buffer object and enums/functions that work on it
*
* @version 1.0.0
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GPR_RGB_BUFFER_H
#define GPR_RGB_BUFFER_H
#include "gpr_allocator.h"
#include "gpr_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum
{
GPR_RGB_RESOLUTION_SIXTEENTH = 1,
GPR_RGB_RESOLUTION_EIGHTH = 2,
GPR_RGB_RESOLUTION_QUARTER = 3,
GPR_RGB_RESOLUTION_HALF = 4,
GPR_RGB_RESOLUTION_FULL = 5,
GPR_RGB_RESOLUTION_NONE = 6,
GPR_RGB_RESOLUTION_DEFAULT = GPR_RGB_RESOLUTION_QUARTER,
} GPR_RGB_RESOLUTION;
typedef struct
{
int r_gain_num;
int r_gain_pow2_den;
int g_gain_num;
int g_gain_pow2_den;
int b_gain_num;
int b_gain_pow2_den;
} gpr_rgb_gain;
void gpr_rgb_gain_set_defaults(gpr_rgb_gain* x);
typedef struct
{
void* buffer; /* Address to the memory location that this buffer points to */
size_t size; /* Size of the memory block */
size_t width;
size_t height;
} gpr_rgb_buffer;
#ifdef __cplusplus
}
#endif
#endif // GPR_RGB_BUFFER_H

Wyświetl plik

@ -0,0 +1,32 @@
The BSD License
Copyright (c) 1999 - 2014, Adobe Systems Incorporated
All rights reserved.
Redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of Adobe Systems Incorporated, nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Wyświetl plik

@ -0,0 +1,21 @@
# library
set( LIB_NAME dng_sdk )
# get source files
file( GLOB SRC_FILES "*.cpp" )
# get include files
file( GLOB INC_FILES "*.h" )
# add include files from other folders
include_directories( "../common/private" )
include_directories( "../common/public" )
include_directories( "../xmp_core/public/include" )
# library
add_library( ${LIB_NAME} STATIC ${SRC_FILES} ${INC_FILES} )
target_link_libraries( ${LIB_NAME} )
# set the folder where to place the projects
set_target_properties( ${LIB_NAME} PROPERTIES FOLDER lib )

Wyświetl plik

@ -0,0 +1,12 @@
/*
*
* ARM Cortex Environment
*
*
*/
#ifndef __RawEnvironment_
#define qDNGLittleEndian 1
#endif // __RawEnvironment

Wyświetl plik

@ -0,0 +1,195 @@
/*****************************************************************************/
// Copyright 2006 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_1d_function.cpp#1 $ */
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */
/*****************************************************************************/
#include "dng_1d_function.h"
#include "dng_utils.h"
/*****************************************************************************/
dng_1d_function::~dng_1d_function ()
{
}
/*****************************************************************************/
bool dng_1d_function::IsIdentity () const
{
return false;
}
/*****************************************************************************/
real64 dng_1d_function::EvaluateInverse (real64 y) const
{
const uint32 kMaxIterations = 30;
const real64 kNearZero = 1.0e-10;
real64 x0 = 0.0;
real64 y0 = Evaluate (x0);
real64 x1 = 1.0;
real64 y1 = Evaluate (x1);
for (uint32 iteration = 0; iteration < kMaxIterations; iteration++)
{
if (Abs_real64 (y1 - y0) < kNearZero)
{
break;
}
real64 x2 = Pin_real64 (0.0,
x1 + (y - y1) * (x1 - x0) / (y1 - y0),
1.0);
real64 y2 = Evaluate (x2);
x0 = x1;
y0 = y1;
x1 = x2;
y1 = y2;
}
return x1;
}
/*****************************************************************************/
bool dng_1d_identity::IsIdentity () const
{
return true;
}
/*****************************************************************************/
real64 dng_1d_identity::Evaluate (real64 x) const
{
return x;
}
/*****************************************************************************/
real64 dng_1d_identity::EvaluateInverse (real64 x) const
{
return x;
}
/*****************************************************************************/
const dng_1d_function & dng_1d_identity::Get ()
{
static dng_1d_identity static_function;
return static_function;
}
/*****************************************************************************/
dng_1d_concatenate::dng_1d_concatenate (const dng_1d_function &function1,
const dng_1d_function &function2)
: fFunction1 (function1)
, fFunction2 (function2)
{
}
/*****************************************************************************/
bool dng_1d_concatenate::IsIdentity () const
{
return fFunction1.IsIdentity () &&
fFunction2.IsIdentity ();
}
/*****************************************************************************/
real64 dng_1d_concatenate::Evaluate (real64 x) const
{
real64 y = Pin_real64 (0.0, fFunction1.Evaluate (x), 1.0);
return fFunction2.Evaluate (y);
}
/*****************************************************************************/
real64 dng_1d_concatenate::EvaluateInverse (real64 x) const
{
real64 y = fFunction2.EvaluateInverse (x);
return fFunction1.EvaluateInverse (y);
}
/*****************************************************************************/
dng_1d_inverse::dng_1d_inverse (const dng_1d_function &f)
: fFunction (f)
{
}
/*****************************************************************************/
bool dng_1d_inverse::IsIdentity () const
{
return fFunction.IsIdentity ();
}
/*****************************************************************************/
real64 dng_1d_inverse::Evaluate (real64 x) const
{
return fFunction.EvaluateInverse (x);
}
/*****************************************************************************/
real64 dng_1d_inverse::EvaluateInverse (real64 y) const
{
return fFunction.Evaluate (y);
}
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,159 @@
/*****************************************************************************/
// Copyright 2006 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_1d_function.h#1 $ */
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */
/** \file
* Classes for a 1D floating-point to floating-point function abstraction.
*/
/*****************************************************************************/
#ifndef __dng_1d_function__
#define __dng_1d_function__
/*****************************************************************************/
#include "dng_classes.h"
#include "dng_types.h"
/*****************************************************************************/
/// \brief A 1D floating-point function.
///
/// The domain (input) is always from 0.0 to 1.0, while the range (output) can be an arbitrary interval.
class dng_1d_function
{
public:
virtual ~dng_1d_function ();
/// Returns true if this function is the map x -> y such that x == y for all x . That is if Evaluate(x) == x for all x.
virtual bool IsIdentity () const;
/// Return the mapping for value x.
/// This method must be implemented by a derived class of dng_1d_function and the derived class determines the
/// lookup method and function used.
/// \param x A value between 0.0 and 1.0 (inclusive).
/// \retval Mapped value for x
virtual real64 Evaluate (real64 x) const = 0;
/// Return the reverse mapped value for y.
/// This method can be implemented by derived classes. The default implementation uses Newton's method to solve
/// for x such that Evaluate(x) == y.
/// \param y A value to reverse map. Should be within the range of the function implemented by this dng_1d_function .
/// \retval A value x such that Evaluate(x) == y (to very close approximation).
virtual real64 EvaluateInverse (real64 y) const;
};
/*****************************************************************************/
/// An identity (x -> y such that x == y for all x) mapping function.
class dng_1d_identity: public dng_1d_function
{
public:
/// Always returns true for this class.
virtual bool IsIdentity () const;
/// Always returns x for this class.
virtual real64 Evaluate (real64 x) const;
/// Always returns y for this class.
virtual real64 EvaluateInverse (real64 y) const;
/// This class is a singleton, and is entirely threadsafe. Use this method to get an instance of the class.
static const dng_1d_function & Get ();
};
/*****************************************************************************/
/// A dng_1d_function that represents the composition (curry) of two other dng_1d_functions.
class dng_1d_concatenate: public dng_1d_function
{
protected:
const dng_1d_function &fFunction1;
const dng_1d_function &fFunction2;
public:
/// Create a dng_1d_function which computes y = function2.Evaluate(function1.Evaluate(x)).
/// Compose function1 and function2 to compute y = function2.Evaluate(function1.Evaluate(x)). The range of function1.Evaluate must be a subset of 0.0 to 1.0 inclusive,
/// otherwise the result of function1(x) will be pinned (clipped) to 0.0 if <0.0 and to 1.0 if > 1.0 .
/// \param function1 Inner function of composition.
/// \param function2 Outer function of composition.
dng_1d_concatenate (const dng_1d_function &function1,
const dng_1d_function &function2);
/// Only true if both function1 and function2 have IsIdentity equal to true.
virtual bool IsIdentity () const;
/// Return the composed mapping for value x.
/// \param x A value between 0.0 and 1.0 (inclusive).
/// \retval function2.Evaluate(function1.Evaluate(x)).
virtual real64 Evaluate (real64 x) const;
/// Return the reverse mapped value for y.
/// Be careful using this method with compositions where the inner function does not have a range 0.0 to 1.0 . (Or better yet, do not use such functions.)
/// \param y A value to reverse map. Should be within the range of function2.Evaluate.
/// \retval A value x such that function2.Evaluate(function1.Evaluate(x)) == y (to very close approximation).
virtual real64 EvaluateInverse (real64 y) const;
};
/*****************************************************************************/
/// A dng_1d_function that represents the inverse of another dng_1d_function.
class dng_1d_inverse: public dng_1d_function
{
protected:
const dng_1d_function &fFunction;
public:
dng_1d_inverse (const dng_1d_function &f);
virtual bool IsIdentity () const;
virtual real64 Evaluate (real64 x) const;
virtual real64 EvaluateInverse (real64 y) const;
};
/*****************************************************************************/
#endif
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,195 @@
/*****************************************************************************/
// Copyright 2006-2008 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_1d_table.cpp#1 $ */
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */
/*****************************************************************************/
#include "dng_1d_table.h"
#include "dng_1d_function.h"
#include "dng_memory.h"
#include "dng_utils.h"
/*****************************************************************************/
dng_1d_table::dng_1d_table ()
: fBuffer ()
, fTable (NULL)
{
}
/*****************************************************************************/
dng_1d_table::~dng_1d_table ()
{
}
/*****************************************************************************/
void dng_1d_table::SubDivide (const dng_1d_function &function,
uint32 lower,
uint32 upper,
real32 maxDelta)
{
uint32 range = upper - lower;
bool subDivide = (range > (kTableSize >> 8));
if (!subDivide)
{
real32 delta = Abs_real32 (fTable [upper] -
fTable [lower]);
if (delta > maxDelta)
{
subDivide = true;
}
}
if (subDivide)
{
uint32 middle = (lower + upper) >> 1;
fTable [middle] = (real32) function.Evaluate (middle * (1.0 / (real64) kTableSize));
if (range > 2)
{
SubDivide (function, lower, middle, maxDelta);
SubDivide (function, middle, upper, maxDelta);
}
}
else
{
real64 y0 = fTable [lower];
real64 y1 = fTable [upper];
real64 delta = (y1 - y0) / (real64) range;
for (uint32 j = lower + 1; j < upper; j++)
{
y0 += delta;
fTable [j] = (real32) y0;
}
}
}
/*****************************************************************************/
void dng_1d_table::Initialize (dng_memory_allocator &allocator,
const dng_1d_function &function,
bool subSample)
{
fBuffer.Reset (allocator.Allocate ((kTableSize + 2) * sizeof (real32)));
fTable = fBuffer->Buffer_real32 ();
if (subSample)
{
fTable [0 ] = (real32) function.Evaluate (0.0);
fTable [kTableSize] = (real32) function.Evaluate (1.0);
real32 maxDelta = Max_real32 (Abs_real32 (fTable [kTableSize] -
fTable [0 ]), 1.0f) *
(1.0f / 256.0f);
SubDivide (function,
0,
kTableSize,
maxDelta);
}
else
{
for (uint32 j = 0; j <= kTableSize; j++)
{
real64 x = j * (1.0 / (real64) kTableSize);
real64 y = function.Evaluate (x);
fTable [j] = (real32) y;
}
}
fTable [kTableSize + 1] = fTable [kTableSize];
}
/*****************************************************************************/
void dng_1d_table::Expand16 (uint16 *table16) const
{
real64 step = (real64) kTableSize / 65535.0;
real64 y0 = fTable [0];
real64 y1 = fTable [1];
real64 base = y0 * 65535.0 + 0.5;
real64 slope = (y1 - y0) * 65535.0;
uint32 index = 1;
real64 fract = 0.0;
for (uint32 j = 0; j < 0x10000; j++)
{
table16 [j] = (uint16) (base + slope * fract);
fract += step;
if (fract > 1.0)
{
index += 1;
fract -= 1.0;
y0 = y1;
y1 = fTable [index];
base = y0 * 65535.0 + 0.5;
slope = (y1 - y0) * 65535.0;
}
}
}
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,122 @@
/*****************************************************************************/
// Copyright 2006-2008 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_1d_table.h#1 $ */
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */
/** \file
* Definition of a lookup table based 1D floating-point to floating-point function abstraction using linear interpolation.
*/
/*****************************************************************************/
#ifndef __dng_1d_table__
#define __dng_1d_table__
/*****************************************************************************/
#include "dng_assertions.h"
#include "dng_auto_ptr.h"
#include "dng_classes.h"
#include "dng_types.h"
/*****************************************************************************/
/// \brief A 1D floating-point lookup table using linear interpolation.
class dng_1d_table
{
public:
/// Constants denoting size of table.
enum
{
kTableBits = 12, //< Table is always a power of 2 in size. This is log2(kTableSize).
kTableSize = (1 << kTableBits) //< Number of entries in table.
};
protected:
AutoPtr<dng_memory_block> fBuffer;
real32 *fTable;
public:
dng_1d_table ();
virtual ~dng_1d_table ();
/// Set up table, initialize entries using functiion.
/// This method can throw an exception, e.g. if there is not enough memory.
/// \param allocator Memory allocator from which table memory is allocated.
/// \param function Table is initialized with values of finction.Evalluate(0.0) to function.Evaluate(1.0).
/// \param subSample If true, only sample the function a limited number of times and interpolate.
void Initialize (dng_memory_allocator &allocator,
const dng_1d_function &function,
bool subSample = false);
/// Lookup and interpolate mapping for an input.
/// \param x value from 0.0 to 1.0 used as input for mapping
/// \retval Approximation of function.Evaluate(x)
real32 Interpolate (real32 x) const
{
real32 y = x * (real32) kTableSize;
int32 index = (int32) y;
DNG_ASSERT (index >= 0 && index <= kTableSize,
"dng_1d_table::Interpolate parameter out of range");
real32 z = (real32) index;
real32 fract = y - z;
return fTable [index ] * (1.0f - fract) +
fTable [index + 1] * ( fract);
}
/// Direct access function for table data.
const real32 * Table () const
{
return fTable;
}
/// Expand the table to a 16-bit to 16-bit table.
void Expand16 (uint16 *table16) const;
private:
void SubDivide (const dng_1d_function &function,
uint32 lower,
uint32 upper,
real32 maxDelta);
// Hidden copy constructor and assignment operator.
dng_1d_table (const dng_1d_table &table);
dng_1d_table & operator= (const dng_1d_table &table);
};
/*****************************************************************************/
#endif
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,242 @@
/*****************************************************************************/
// Copyright 2006-2008 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_abort_sniffer.cpp#1 $ */
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */
/*****************************************************************************/
#include "dng_abort_sniffer.h"
#include "dng_mutex.h"
/*****************************************************************************/
#if qDNGThreadSafe
/*****************************************************************************/
class dng_priority_manager
{
private:
dng_mutex fMutex;
dng_condition fCondition;
uint32 fCounter [dng_priority_count];
public:
dng_priority_manager ();
void Increment (dng_priority priority);
void Decrement (dng_priority priority);
void Wait (dng_priority priority);
private:
dng_priority MinPriority ()
{
// Assumes mutex is locked.
for (uint32 level = dng_priority_maximum;
level > dng_priority_minimum;
level--)
{
if (fCounter [level])
{
return (dng_priority) level;
}
}
return dng_priority_minimum;
}
};
/*****************************************************************************/
dng_priority_manager::dng_priority_manager ()
: fMutex ("dng_priority_manager::fMutex")
, fCondition ()
{
for (uint32 level = dng_priority_minimum;
level <= dng_priority_maximum;
level++)
{
fCounter [level] = 0;
}
}
/*****************************************************************************/
void dng_priority_manager::Increment (dng_priority priority)
{
dng_lock_mutex lock (&fMutex);
fCounter [priority] += 1;
}
/*****************************************************************************/
void dng_priority_manager::Decrement (dng_priority priority)
{
dng_lock_mutex lock (&fMutex);
dng_priority oldMin = MinPriority ();
fCounter [priority] -= 1;
dng_priority newMin = MinPriority ();
if (newMin < oldMin)
{
fCondition.Broadcast ();
}
}
/*****************************************************************************/
void dng_priority_manager::Wait (dng_priority priority)
{
if (priority < dng_priority_maximum)
{
dng_lock_mutex lock (&fMutex);
while (priority < MinPriority ())
{
fCondition.Wait (fMutex);
}
}
}
/*****************************************************************************/
static dng_priority_manager gPriorityManager;
/*****************************************************************************/
#endif
/*****************************************************************************/
dng_set_minimum_priority::dng_set_minimum_priority (dng_priority priority)
: fPriority (priority)
{
#if qDNGThreadSafe
gPriorityManager.Increment (fPriority);
#endif
}
/*****************************************************************************/
dng_set_minimum_priority::~dng_set_minimum_priority ()
{
#if qDNGThreadSafe
gPriorityManager.Decrement (fPriority);
#endif
}
/*****************************************************************************/
dng_abort_sniffer::dng_abort_sniffer ()
: fPriority (dng_priority_maximum)
{
}
/*****************************************************************************/
dng_abort_sniffer::~dng_abort_sniffer ()
{
}
/*****************************************************************************/
void dng_abort_sniffer::SniffForAbort (dng_abort_sniffer *sniffer)
{
if (sniffer)
{
#if qDNGThreadSafe
gPriorityManager.Wait (sniffer->Priority ());
#endif
sniffer->Sniff ();
}
}
/*****************************************************************************/
void dng_abort_sniffer::StartTask (const char * /* name */,
real64 /* fract */)
{
}
/*****************************************************************************/
void dng_abort_sniffer::EndTask ()
{
}
/*****************************************************************************/
void dng_abort_sniffer::UpdateProgress (real64 /* fract */)
{
}
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,244 @@
/*****************************************************************************/
// Copyright 2006-2008 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_abort_sniffer.h#2 $ */
/* $DateTime: 2012/07/11 10:36:56 $ */
/* $Change: 838485 $ */
/* $Author: tknoll $ */
/** \file
* Classes supporting user cancellation and progress tracking.
*/
/*****************************************************************************/
#ifndef __dng_abort_sniffer__
#define __dng_abort_sniffer__
/*****************************************************************************/
#include "dng_flags.h"
#include "dng_types.h"
/*****************************************************************************/
/// \brief Thread priority level.
enum dng_priority
{
dng_priority_low,
dng_priority_medium,
dng_priority_high,
dng_priority_count,
dng_priority_minimum = dng_priority_low,
dng_priority_maximum = dng_priority_high
};
/*****************************************************************************/
/// \brief Convenience class for setting thread priority level to minimum.
class dng_set_minimum_priority
{
private:
dng_priority fPriority;
public:
dng_set_minimum_priority (dng_priority priority);
~dng_set_minimum_priority ();
};
/*****************************************************************************/
/** \brief Class for signaling user cancellation and receiving progress updates.
*
* DNG SDK clients should derive a host application specific implementation
* from this class.
*/
class dng_abort_sniffer
{
friend class dng_sniffer_task;
private:
dng_priority fPriority;
public:
dng_abort_sniffer ();
virtual ~dng_abort_sniffer ();
/// Getter for priority level.
dng_priority Priority () const
{
return fPriority;
}
/// Setter for priority level.
void SetPriority (dng_priority priority)
{
fPriority = priority;
}
/// Check for pending user cancellation or other abort. ThrowUserCanceled
/// will be called if one is pending. This static method is provided as a
/// convenience for quickly testing for an abort and throwing an exception
/// if one is pending.
/// \param sniffer The dng_sniffer to test for a pending abort. Can be NULL,
/// in which case there an abort is never signalled.
static void SniffForAbort (dng_abort_sniffer *sniffer);
// A way to call Sniff while bypassing the priority wait.
void SniffNoPriorityWait ()
{
Sniff ();
}
// Specifies whether or not the sniffer may be called by multiple threads
// in parallel. Default result is false. Subclass must override to return
// true.
virtual bool ThreadSafe () const
{
return false;
}
protected:
/// Should be implemented by derived classes to check for an user
/// cancellation.
virtual void Sniff () = 0;
/// Signals the start of a named task withn processing in the DNG SDK.
/// Tasks may be nested.
/// \param name of the task
/// \param fract Percentage of total processing this task is expected to
/// take. From 0.0 to 1.0 .
virtual void StartTask (const char *name,
real64 fract);
/// Signals the end of the innermost task that has been started.
virtual void EndTask ();
/// Signals progress made on current task.
/// \param fract percentage of processing completed on current task.
/// From 0.0 to 1.0 .
virtual void UpdateProgress (real64 fract);
};
/******************************************************************************/
/// \brief Class to establish scope of a named subtask in DNG processing.
///
/// Instances of this class are intended to be stack allocated.
class dng_sniffer_task
{
private:
dng_abort_sniffer *fSniffer;
public:
/// Inform a sniffer of a subtask in DNG processing.
/// \param sniffer The sniffer associated with the host on which this
/// processing is occurring.
/// \param name The name of this subtask as a NUL terminated string.
/// \param fract Percentage of total processing this task is expected
/// to take, from 0.0 to 1.0 .
dng_sniffer_task (dng_abort_sniffer *sniffer,
const char *name = NULL,
real64 fract = 0.0)
: fSniffer (sniffer)
{
if (fSniffer)
fSniffer->StartTask (name, fract);
}
~dng_sniffer_task ()
{
if (fSniffer)
fSniffer->EndTask ();
}
/// Check for pending user cancellation or other abort. ThrowUserCanceled
/// will be called if one is pending.
void Sniff ()
{
dng_abort_sniffer::SniffForAbort (fSniffer);
}
/// Update progress on this subtask.
/// \param fract Percentage of processing completed on current task,
/// from 0.0 to 1.0 .
void UpdateProgress (real64 fract)
{
if (fSniffer)
fSniffer->UpdateProgress (fract);
}
/// Update progress on this subtask.
/// \param done Amount of task completed in arbitrary integer units.
/// \param total Total size of task in same arbitrary integer units as done.
void UpdateProgress (uint32 done,
uint32 total)
{
UpdateProgress ((real64) done /
(real64) total);
}
/// Signal task completed for progress purposes.
void Finish ()
{
UpdateProgress (1.0);
}
private:
// Hidden copy constructor and assignment operator.
dng_sniffer_task (const dng_sniffer_task &task);
dng_sniffer_task & operator= (const dng_sniffer_task &task);
};
/*****************************************************************************/
#endif
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,270 @@
/*****************************************************************************/
// Copyright 2006-2012 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_area_task.cpp#1 $ */
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */
/*****************************************************************************/
#include "dng_area_task.h"
#include "dng_abort_sniffer.h"
#include "dng_flags.h"
#include "dng_sdk_limits.h"
#include "dng_tile_iterator.h"
#include "dng_utils.h"
#if qImagecore
extern bool gPrintTimings;
#endif
/*****************************************************************************/
dng_area_task::dng_area_task ()
: fMaxThreads (kMaxMPThreads)
, fMinTaskArea (256 * 256)
, fUnitCell (1, 1)
, fMaxTileSize (256, 256)
{
}
/*****************************************************************************/
dng_area_task::~dng_area_task ()
{
}
/*****************************************************************************/
dng_rect dng_area_task::RepeatingTile1 () const
{
return dng_rect ();
}
/*****************************************************************************/
dng_rect dng_area_task::RepeatingTile2 () const
{
return dng_rect ();
}
/*****************************************************************************/
dng_rect dng_area_task::RepeatingTile3 () const
{
return dng_rect ();
}
/*****************************************************************************/
void dng_area_task::Start (uint32 /* threadCount */,
const dng_point & /* tileSize */,
dng_memory_allocator * /* allocator */,
dng_abort_sniffer * /* sniffer */)
{
}
/*****************************************************************************/
void dng_area_task::Finish (uint32 /* threadCount */)
{
}
/*****************************************************************************/
dng_point dng_area_task::FindTileSize (const dng_rect &area) const
{
dng_rect repeatingTile1 = RepeatingTile1 ();
dng_rect repeatingTile2 = RepeatingTile2 ();
dng_rect repeatingTile3 = RepeatingTile3 ();
if (repeatingTile1.IsEmpty ())
{
repeatingTile1 = area;
}
if (repeatingTile2.IsEmpty ())
{
repeatingTile2 = area;
}
if (repeatingTile3.IsEmpty ())
{
repeatingTile3 = area;
}
uint32 repeatV = Min_uint32 (Min_uint32 (repeatingTile1.H (),
repeatingTile2.H ()),
repeatingTile3.H ());
uint32 repeatH = Min_uint32 (Min_uint32 (repeatingTile1.W (),
repeatingTile2.W ()),
repeatingTile3.W ());
dng_point maxTileSize = MaxTileSize ();
dng_point tileSize;
tileSize.v = Min_int32 (repeatV, maxTileSize.v);
tileSize.h = Min_int32 (repeatH, maxTileSize.h);
// What this is doing is, if the smallest repeating image tile is larger than the
// maximum tile size, adjusting the tile size down so that the tiles are as small
// as possible while still having the same number of tiles covering the
// repeat area. This makes the areas more equal in size, making MP
// algorithms work better.
// The image core team did not understand this code, and disabled it.
// Really stupid idea to turn off code you don't understand!
// I'm undoing this removal, because I think the code is correct and useful.
uint32 countV = (repeatV + tileSize.v - 1) / tileSize.v;
uint32 countH = (repeatH + tileSize.h - 1) / tileSize.h;
tileSize.v = (repeatV + countV - 1) / countV;
tileSize.h = (repeatH + countH - 1) / countH;
// Round up to unit cell size.
dng_point unitCell = UnitCell ();
if (unitCell.h != 1 || unitCell.v != 1)
{
tileSize.v = ((tileSize.v + unitCell.v - 1) / unitCell.v) * unitCell.v;
tileSize.h = ((tileSize.h + unitCell.h - 1) / unitCell.h) * unitCell.h;
}
// But if that is larger than maximum tile size, round down to unit cell size.
if (tileSize.v > maxTileSize.v)
{
tileSize.v = (maxTileSize.v / unitCell.v) * unitCell.v;
}
if (tileSize.h > maxTileSize.h)
{
tileSize.h = (maxTileSize.h / unitCell.h) * unitCell.h;
}
#if qImagecore
if (gPrintTimings)
{
fprintf (stdout, "\nRender tile for below: %d x %d\n", (int32) tileSize.h, (int32) tileSize.v);
}
#endif
return tileSize;
}
/*****************************************************************************/
void dng_area_task::ProcessOnThread (uint32 threadIndex,
const dng_rect &area,
const dng_point &tileSize,
dng_abort_sniffer *sniffer)
{
dng_rect repeatingTile1 = RepeatingTile1 ();
dng_rect repeatingTile2 = RepeatingTile2 ();
dng_rect repeatingTile3 = RepeatingTile3 ();
if (repeatingTile1.IsEmpty ())
{
repeatingTile1 = area;
}
if (repeatingTile2.IsEmpty ())
{
repeatingTile2 = area;
}
if (repeatingTile3.IsEmpty ())
{
repeatingTile3 = area;
}
dng_rect tile1;
dng_tile_iterator iter1 (repeatingTile3, area);
while (iter1.GetOneTile (tile1))
{
dng_rect tile2;
dng_tile_iterator iter2 (repeatingTile2, tile1);
while (iter2.GetOneTile (tile2))
{
dng_rect tile3;
dng_tile_iterator iter3 (repeatingTile1, tile2);
while (iter3.GetOneTile (tile3))
{
dng_rect tile4;
dng_tile_iterator iter4 (tileSize, tile3);
while (iter4.GetOneTile (tile4))
{
dng_abort_sniffer::SniffForAbort (sniffer);
Process (threadIndex, tile4, sniffer);
}
}
}
}
}
/*****************************************************************************/
void dng_area_task::Perform (dng_area_task &task,
const dng_rect &area,
dng_memory_allocator *allocator,
dng_abort_sniffer *sniffer)
{
dng_point tileSize (task.FindTileSize (area));
task.Start (1, tileSize, allocator, sniffer);
task.ProcessOnThread (0, area, tileSize, sniffer);
task.Finish (1);
}
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,198 @@
/*****************************************************************************/
// Copyright 2006 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_area_task.h#1 $ */
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */
/** \file
* Class to handle partitioning a rectangular image processing operation taking into account multiple processing resources and memory constraints.
*/
/*****************************************************************************/
#ifndef __dng_area_task__
#define __dng_area_task__
/*****************************************************************************/
#include "dng_classes.h"
#include "dng_point.h"
#include "dng_types.h"
/*****************************************************************************/
/// \brief Abstract class for rectangular processing operations with support for partitioning across multiple processing resources and observing memory constraints.
class dng_area_task
{
protected:
uint32 fMaxThreads;
uint32 fMinTaskArea;
dng_point fUnitCell;
dng_point fMaxTileSize;
public:
dng_area_task ();
virtual ~dng_area_task ();
/// Getter for the maximum number of threads (resources) that can be used for processing
///
/// \retval Number of threads, minimum of 1, that can be used for this task.
virtual uint32 MaxThreads () const
{
return fMaxThreads;
}
/// Getter for minimum area of a partitioned rectangle.
/// Often it is not profitable to use more resources if it requires partitioning the input into chunks that are too small,
/// as the overhead increases more than the speedup. This method can be ovreridden for a specific task to indicate the smallest
/// area for partitioning. Default is 256x256 pixels.
///
/// \retval Minimum area for a partitoned tile in order to give performant operation. (Partitions can be smaller due to small inputs and edge cases.)
virtual uint32 MinTaskArea () const
{
return fMinTaskArea;
}
/// Getter for dimensions of which partitioned tiles should be a multiple.
/// Various methods of processing prefer certain alignments. The partitioning attempts to construct tiles such that the
/// sizes are a multiple of the dimensions of this point.
///
/// \retval a point giving preferred alignment in x and y
virtual dng_point UnitCell () const
{
return fUnitCell;
}
/// Getter for maximum size of a tile for processing.
/// Often processing will need to allocate temporary buffers or use other resources that are either fixed or in limited supply.
/// The maximum tile size forces further partitioning if the tile is bigger than this size.
///
/// \retval Maximum tile size allowed for this area task.
virtual dng_point MaxTileSize () const
{
return fMaxTileSize;
}
/// Getter for RepeatingTile1.
/// RepeatingTile1, RepeatingTile2, and RepeatingTile3 are used to establish a set of 0 to 3 tile patterns for which
/// the resulting partitions that the final Process method is called on will not cross tile boundaries in any of the
/// tile patterns. This can be used for a processing routine that needs to read from two tiles and write to a third
/// such that all the tiles are aligned and sized in a certain way. A RepeatingTile value is valid if it is non-empty.
/// Higher numbered RepeatingTile patterns are only used if all lower ones are non-empty. A RepeatingTile pattern must
/// be a multiple of UnitCell in size for all constraints of the partitionerr to be met.
virtual dng_rect RepeatingTile1 () const;
/// Getter for RepeatingTile2.
/// RepeatingTile1, RepeatingTile2, and RepeatingTile3 are used to establish a set of 0 to 3 tile patterns for which
/// the resulting partitions that the final Process method is called on will not cross tile boundaries in any of the
/// tile patterns. This can be used for a processing routine that needs to read from two tiles and write to a third
/// such that all the tiles are aligned and sized in a certain way. A RepeatingTile value is valid if it is non-empty.
/// Higher numbered RepeatingTile patterns are only used if all lower ones are non-empty. A RepeatingTile pattern must
/// be a multiple of UnitCell in size for all constraints of the partitionerr to be met.
virtual dng_rect RepeatingTile2 () const;
/// Getter for RepeatingTile3.
/// RepeatingTile1, RepeatingTile2, and RepeatingTile3 are used to establish a set of 0 to 3 tile patterns for which
/// the resulting partitions that the final Process method is called on will not cross tile boundaries in any of the
/// tile patterns. This can be used for a processing routine that needs to read from two tiles and write to a third
/// such that all the tiles are aligned and sized in a certain way. A RepeatingTile value is valid if it is non-empty.
/// Higher numbered RepeatingTile patterns are only used if all lower ones are non-empty. A RepeatingTile pattern must
/// be a multiple of UnitCell in size for all constraints of the partitionerr to be met.
virtual dng_rect RepeatingTile3 () const;
/// Task startup method called before any processing is done on partitions.
/// The Start method is called before any processing is done and can be overridden to allocate temporary buffers, etc.
///
/// \param threadCount Total number of threads that will be used for processing. Less than or equal to MaxThreads.
/// \param tileSize Size of source tiles which will be processed. (Not all tiles will be this size due to edge conditions.)
/// \param allocator dng_memory_allocator to use for allocating temporary buffers, etc.
/// \param sniffer Sniffer to test for user cancellation and to set up progress.
virtual void Start (uint32 threadCount,
const dng_point &tileSize,
dng_memory_allocator *allocator,
dng_abort_sniffer *sniffer);
/// Process one tile or fully partitioned area.
/// This method is overridden by derived classes to implement the actual image processing. Note that the sniffer can be ignored if it is certain that a
/// processing task will complete very quickly.
/// This method should never be called directly but rather accessed via Process.
/// There is no allocator parameter as all allocation should be done in Start.
///
/// \param threadIndex 0 to threadCount - 1 index indicating which thread this is. (Can be used to get a thread-specific buffer allocated in the Start method.)
/// \param tile Area to process.
/// \param sniffer dng_abort_sniffer to use to check for user cancellation and progress updates.
virtual void Process (uint32 threadIndex,
const dng_rect &tile,
dng_abort_sniffer *sniffer) = 0;
/// Task computation finalization and teardown method.
/// Called after all resources have completed processing. Can be overridden to accumulate results and free resources allocated in Start.
///
/// \param threadCount Number of threads used for processing. Same as value passed to Start.
virtual void Finish (uint32 threadCount);
/// Find tile size taking into account repeating tiles, unit cell, and maximum tile size.
/// \param area Computation area for which to find tile size.
/// \retval Tile size as height and width in point.
dng_point FindTileSize (const dng_rect &area) const;
/// Handle one resource's worth of partitioned tiles.
/// Called after thread partitioning has already been done. Area may be further subdivided to handle maximum tile size, etc.
/// It will be rare to override this method.
///
/// \param threadIndex 0 to threadCount - 1 index indicating which thread this is.
/// \param area Tile area partitioned to this resource.
/// \param tileSize
/// \param sniffer dng_abort_sniffer to use to check for user cancellation and progress updates.
void ProcessOnThread (uint32 threadIndex,
const dng_rect &area,
const dng_point &tileSize,
dng_abort_sniffer *sniffer);
/// Default resource partitioner that assumes a single resource to be used for processing.
/// Implementations that are aware of multiple processing resources should override (replace) this method.
/// This is usually done in dng_host::PerformAreaTask .
/// \param task The task to perform.
/// \param area The area on which mage processing should be performed.
/// \param allocator dng_memory_allocator to use for allocating temporary buffers, etc.
/// \param sniffer dng_abort_sniffer to use to check for user cancellation and progress updates.
static void Perform (dng_area_task &task,
const dng_rect &area,
dng_memory_allocator *allocator,
dng_abort_sniffer *sniffer);
};
/*****************************************************************************/
#endif
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,133 @@
/*****************************************************************************/
// Copyright 2006-2007 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_assertions.h#3 $ */
/* $DateTime: 2012/09/05 12:31:51 $ */
/* $Change: 847652 $ */
/* $Author: tknoll $ */
/** \file
* Conditionally compiled assertion check support.
*/
/*****************************************************************************/
#ifndef __dng_assertions__
#define __dng_assertions__
/*****************************************************************************/
#include "dng_exceptions.h"
#include "dng_flags.h"
/*****************************************************************************/
#if qDNGDebug
/// Platform-specific function to display an assert.
void dng_show_message (const char *s);
/// Show a formatted error message.
void dng_show_message_f (const char *fmt, ...);
#endif
/*****************************************************************************/
#ifndef DNG_ASSERT
#if qDNGDebug
/// Conditionally compiled macro to check an assertion and display a message if
/// it fails and assertions are compiled in via qDNGDebug
/// \param x Predicate which must be true.
/// \param y String to display if x is not true.
#define DNG_ASSERT(x,y) { if (!(x)) dng_show_message (y); }
#else
/// Conditionally compiled macro to check an assertion and display a message if
/// it fails and assertions are compiled in via qDNGDebug
/// \param x Predicate which must be true.
/// \param y String to display if x is not true.
#define DNG_ASSERT(x,y)
#endif
#endif
/*****************************************************************************/
#ifndef DNG_REQUIRE
#if qDNGDebug
/// Conditionally compiled macro to check an assertion, display a message, and throw
/// an exception if it fails and assertions are compiled in via qDNGDebug
/// \param condition Predicate which must be true.
/// \param msg String to display if condition is not true.
#define DNG_REQUIRE(condition,msg) \
do \
{ \
\
if (!(condition)) \
{ \
\
DNG_ASSERT(condition, msg); \
\
ThrowProgramError (msg); \
\
} \
\
} \
while (0)
#else
/// Conditionally compiled macro to check an assertion, display a message, and throw
/// an exception if it fails and assertions are compiled in via qDNGDebug
/// \param condition Predicate which must be true.
/// \param msg String to display if condition is not true.
#define DNG_REQUIRE(condition,msg) \
do \
{ \
\
if (!(condition)) \
{ \
\
ThrowProgramError (msg); \
\
} \
\
} \
while (0)
#endif
#endif
/*****************************************************************************/
#ifndef DNG_REPORT
/// Macro to display an informational message
/// \param x String to display.
#define DNG_REPORT(x) DNG_ASSERT (false, x)
#endif
/*****************************************************************************/
#endif
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,259 @@
/*****************************************************************************/
// Copyright 2006 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_auto_ptr.h#2 $ */
/* $DateTime: 2012/07/11 10:36:56 $ */
/* $Change: 838485 $ */
/* $Author: tknoll $ */
/** \file
* Class to implement std::auto_ptr like functionality even on platforms which do not
* have a full Standard C++ library.
*/
/*****************************************************************************/
#ifndef __dng_auto_ptr__
#define __dng_auto_ptr__
#include <stddef.h>
/*****************************************************************************/
// The following template has similar functionality to the STL auto_ptr, without
// requiring all the weight of STL.
/*****************************************************************************/
/// \brief A class intended to be used in stack scope to hold a pointer from new. The
/// held pointer will be deleted automatically if the scope is left without calling
/// Release on the AutoPtr first.
template<class T>
class AutoPtr
{
private:
T *p_;
public:
/// Construct an AutoPtr with no referent.
AutoPtr () : p_ (0) { }
/// Construct an AutoPtr which owns the argument pointer.
/// \param p pointer which constructed AutoPtr takes ownership of. p will be
/// deleted on destruction or Reset unless Release is called first.
explicit AutoPtr (T *p) : p_( p ) { }
/// Reset is called on destruction.
~AutoPtr ();
/// Call Reset with a pointer from new. Uses T's default constructor.
void Alloc ();
/// Return the owned pointer of this AutoPtr, NULL if none. No change in
/// ownership or other effects occur.
T *Get () const { return p_; }
/// Return the owned pointer of this AutoPtr, NULL if none. The AutoPtr gives
/// up ownership and takes NULL as its value.
T *Release ();
/// If a pointer is owned, it is deleted. Ownership is taken of passed in
/// pointer.
/// \param p pointer which constructed AutoPtr takes ownership of. p will be
/// deleted on destruction or Reset unless Release is called first.
void Reset (T *p);
/// If a pointer is owned, it is deleted and the AutoPtr takes NULL as its
/// value.
void Reset ();
/// Allows members of the owned pointer to be accessed directly. It is an
/// error to call this if the AutoPtr has NULL as its value.
T *operator-> () const { return p_; }
/// Returns a reference to the object that the owned pointer points to. It is
/// an error to call this if the AutoPtr has NULL as its value.
T &operator* () const { return *p_; }
/// Swap with another auto ptr.
friend inline void Swap (AutoPtr< T > &x, AutoPtr< T > &y)
{
T* temp = x.p_;
x.p_ = y.p_;
y.p_ = temp;
}
private:
// Hidden copy constructor and assignment operator. I don't think the STL
// "feature" of grabbing ownership of the pointer is a good idea.
AutoPtr (AutoPtr<T> &rhs);
AutoPtr<T> & operator= (AutoPtr<T> &rhs);
};
/*****************************************************************************/
template<class T>
AutoPtr<T>::~AutoPtr ()
{
delete p_;
p_ = 0;
}
/*****************************************************************************/
template<class T>
T *AutoPtr<T>::Release ()
{
T *result = p_;
p_ = 0;
return result;
}
/*****************************************************************************/
template<class T>
void AutoPtr<T>::Reset (T *p)
{
if (p_ != p)
{
if (p_ != 0)
delete p_;
p_ = p;
}
}
/*****************************************************************************/
template<class T>
void AutoPtr<T>::Reset ()
{
if (p_ != 0)
{
delete p_;
p_ = 0;
}
}
/*****************************************************************************/
template<class T>
void AutoPtr<T>::Alloc ()
{
this->Reset (new T);
}
/*****************************************************************************/
/// \brief A class intended to be used similarly to AutoPtr but for arrays.
template<typename T>
class AutoArray
{
public:
/// Construct an AutoArray which owns the argument pointer.
/// \param p array pointer which constructed AutoArray takes ownership of. p
/// will be deleted on destruction or Reset unless Release is called first.
explicit AutoArray (T *p_ = 0) : p (p_) { }
/// Reset is called on destruction.
~AutoArray ()
{
delete [] p;
p = 0;
}
/// Return the owned array pointer of this AutoArray, NULL if none. The
/// AutoArray gives up ownership and takes NULL as its value.
T *Release ()
{
T *p_ = p;
p = 0;
return p_;
}
/// If a pointer is owned, it is deleted. Ownership is taken of passed in
/// pointer.
/// \param p array pointer which constructed AutoArray takes ownership of. p
/// will be deleted on destruction or Reset unless Release is called first.
void Reset (T *p_ = 0)
{
if (p != p_)
{
delete [] p;
p = p_;
}
}
/// Allows indexing into the AutoArray. It is an error to call this if the
/// AutoArray has NULL as its value.
T &operator[] (ptrdiff_t i) const
{
return p [i];
}
/// Return the owned pointer of this AutoArray, NULL if none. No change in
/// ownership or other effects occur.
T *Get () const
{
return p;
}
private:
// Hidden copy constructor and assignment operator.
AutoArray (const AutoArray &);
const AutoArray & operator= (const AutoArray &);
private:
// Owned pointer or NULL.
T *p;
};
/*****************************************************************************/
#endif
/*****************************************************************************/

Plik diff jest za duży Load Diff

Wyświetl plik

@ -0,0 +1,307 @@
/*****************************************************************************/
// Copyright 2008 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_bad_pixels.h#3 $ */
/* $DateTime: 2012/07/11 10:36:56 $ */
/* $Change: 838485 $ */
/* $Author: tknoll $ */
/** \file
* Opcodes to fix defective pixels, including individual pixels and regions (such as
* defective rows and columns).
*/
/*****************************************************************************/
#ifndef __dng_bad_pixels__
#define __dng_bad_pixels__
/*****************************************************************************/
#include "dng_opcodes.h"
#include <vector>
/*****************************************************************************/
/// \brief An opcode to fix individual bad pixels that are marked with a constant
/// value (e.g., 0) in a Bayer image.
class dng_opcode_FixBadPixelsConstant: public dng_filter_opcode
{
private:
uint32 fConstant;
uint32 fBayerPhase;
public:
/// Construct an opcode to fix an individual bad pixels that are marked with
/// a constant value in a Bayer image.
/// \param constant The constant value that indicates a bad pixel.
/// \param bayerPhase The phase of the Bayer mosaic pattern (0, 1, 2, 3).
dng_opcode_FixBadPixelsConstant (uint32 constant,
uint32 bayerPhase);
dng_opcode_FixBadPixelsConstant (dng_stream &stream);
virtual void PutData (dng_stream &stream) const;
virtual dng_point SrcRepeat ();
virtual dng_rect SrcArea (const dng_rect &dstArea,
const dng_rect &imageBounds);
virtual void Prepare (dng_negative &negative,
uint32 threadCount,
const dng_point &tileSize,
const dng_rect &imageBounds,
uint32 imagePlanes,
uint32 bufferPixelType,
dng_memory_allocator &allocator);
virtual void ProcessArea (dng_negative &negative,
uint32 threadIndex,
dng_pixel_buffer &srcBuffer,
dng_pixel_buffer &dstBuffer,
const dng_rect &dstArea,
const dng_rect &imageBounds);
protected:
bool IsGreen (int32 row, int32 col) const
{
return (((uint32) row + (uint32) col + fBayerPhase + (fBayerPhase >> 1)) & 1) == 0;
}
};
/*****************************************************************************/
/// \brief A list of bad pixels and rectangles (usually single rows or columns).
class dng_bad_pixel_list
{
public:
enum
{
kNoIndex = 0xFFFFFFFF
};
private:
// List of bad single pixels.
std::vector<dng_point> fBadPoints;
// List of bad rectangles (usually single rows or columns).
std::vector<dng_rect> fBadRects;
public:
/// Create an empty bad pixel list.
dng_bad_pixel_list ();
/// Returns the number of bad single pixels.
uint32 PointCount () const
{
return (uint32) fBadPoints.size ();
}
/// Retrieves the bad single pixel coordinate via the specified list index.
///
/// \param index The list index from which to retrieve the bad single pixel
/// coordinate.
const dng_point & Point (uint32 index) const
{
return fBadPoints [index];
}
/// Returns the number of bad rectangles.
uint32 RectCount () const
{
return (uint32) fBadRects.size ();
}
/// Retrieves the bad rectangle via the specified list index.
///
/// \param index The list index from which to retrieve the bad rectangle
/// coordinates.
const dng_rect & Rect (uint32 index) const
{
return fBadRects [index];
}
/// Returns true iff there are zero bad single pixels and zero bad
/// rectangles.
bool IsEmpty () const
{
return PointCount () == 0 &&
RectCount () == 0;
}
/// Returns true iff there is at least one bad single pixel or at least one
/// bad rectangle.
bool NotEmpty () const
{
return !IsEmpty ();
}
/// Add the specified coordinate to the list of bad single pixels.
///
/// \param pt The bad single pixel to add.
void AddPoint (const dng_point &pt);
/// Add the specified rectangle to the list of bad rectangles.
///
/// \param pt The bad rectangle to add.
void AddRect (const dng_rect &r);
/// Sort the bad single pixels and bad rectangles by coordinates (top to
/// bottom, then left to right).
void Sort ();
/// Returns true iff the specified bad single pixel is isolated, i.e., there
/// is no other bad single pixel or bad rectangle that lies within radius
/// pixels of this bad single pixel.
///
/// \param index The index of the bad single pixel to test.
/// \param radius The pixel radius to test for isolation.
bool IsPointIsolated (uint32 index,
uint32 radius) const;
/// Returns true iff the specified bad rectangle is isolated, i.e., there
/// is no other bad single pixel or bad rectangle that lies within radius
/// pixels of this bad rectangle.
///
/// \param index The index of the bad rectangle to test.
/// \param radius The pixel radius to test for isolation.
bool IsRectIsolated (uint32 index,
uint32 radius) const;
/// Returns true iff the specified point is valid, i.e., lies within the
/// specified image bounds, is different from all other bad single pixels,
/// and is not contained in any bad rectangle. The second and third
/// conditions are only checked if provided with a starting search index.
///
/// \param pt The point to test for validity.
/// \param imageBounds The pt must lie within imageBounds to be valid.
/// \index The search index to use (or kNoIndex, to avoid a search) for
/// checking for validity.
bool IsPointValid (const dng_point &pt,
const dng_rect &imageBounds,
uint32 index = kNoIndex) const;
};
/*****************************************************************************/
/// \brief An opcode to fix lists of bad pixels (indicated by position) in a Bayer
/// image.
class dng_opcode_FixBadPixelsList: public dng_filter_opcode
{
protected:
enum
{
kBadPointPadding = 2,
kBadRectPadding = 4
};
private:
AutoPtr<dng_bad_pixel_list> fList;
uint32 fBayerPhase;
public:
/// Construct an opcode to fix lists of bad pixels (indicated by position) in
/// a Bayer image.
/// \param list The list of bad pixels to fix.
/// \param bayerPhase The phase of the Bayer mosaic pattern (0, 1, 2, 3).
dng_opcode_FixBadPixelsList (AutoPtr<dng_bad_pixel_list> &list,
uint32 bayerPhase);
dng_opcode_FixBadPixelsList (dng_stream &stream);
virtual void PutData (dng_stream &stream) const;
virtual dng_point SrcRepeat ();
virtual dng_rect SrcArea (const dng_rect &dstArea,
const dng_rect &imageBounds);
virtual void Prepare (dng_negative &negative,
uint32 threadCount,
const dng_point &tileSize,
const dng_rect &imageBounds,
uint32 imagePlanes,
uint32 bufferPixelType,
dng_memory_allocator &allocator);
virtual void ProcessArea (dng_negative &negative,
uint32 threadIndex,
dng_pixel_buffer &srcBuffer,
dng_pixel_buffer &dstBuffer,
const dng_rect &dstArea,
const dng_rect &imageBounds);
protected:
bool IsGreen (int32 row, int32 col) const
{
return ((row + col + fBayerPhase + (fBayerPhase >> 1)) & 1) == 0;
}
virtual void FixIsolatedPixel (dng_pixel_buffer &buffer,
dng_point &badPoint);
virtual void FixClusteredPixel (dng_pixel_buffer &buffer,
uint32 pointIndex,
const dng_rect &imageBounds);
virtual void FixSingleColumn (dng_pixel_buffer &buffer,
const dng_rect &badRect);
virtual void FixSingleRow (dng_pixel_buffer &buffer,
const dng_rect &badRect);
virtual void FixClusteredRect (dng_pixel_buffer &buffer,
const dng_rect &badRect,
const dng_rect &imageBounds);
};
/*****************************************************************************/
#endif
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,72 @@
/*****************************************************************************/
// Copyright 2006-2009 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_bottlenecks.cpp#1 $ */
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */
/*****************************************************************************/
#include "dng_bottlenecks.h"
#include "dng_reference.h"
/*****************************************************************************/
dng_suite gDNGSuite =
{
RefZeroBytes,
RefCopyBytes,
RefSwapBytes16,
RefSwapBytes32,
RefSetArea8,
RefSetArea16,
RefSetArea32,
RefCopyArea8,
RefCopyArea16,
RefCopyArea32,
RefCopyArea8_16,
RefCopyArea8_S16,
RefCopyArea8_32,
RefCopyArea16_S16,
RefCopyArea16_32,
RefCopyArea8_R32,
RefCopyArea16_R32,
RefCopyAreaS16_R32,
RefCopyAreaR32_8,
RefCopyAreaR32_16,
RefCopyAreaR32_S16,
RefRepeatArea8,
RefRepeatArea16,
RefRepeatArea32,
RefShiftRight16,
RefBilinearRow16,
RefBilinearRow32,
RefBaselineABCtoRGB,
RefBaselineABCDtoRGB,
RefBaselineHueSatMap,
RefBaselineRGBtoGray,
RefBaselineRGBtoRGB,
RefBaseline1DTable,
RefBaselineRGBTone,
RefResampleDown16,
RefResampleDown32,
RefResampleAcross16,
RefResampleAcross32,
RefEqualBytes,
RefEqualArea8,
RefEqualArea16,
RefEqualArea32,
RefVignetteMask16,
RefVignette16,
RefVignette32,
RefMapArea16
};
/*****************************************************************************/

Plik diff jest za duży Load Diff

Wyświetl plik

@ -0,0 +1,878 @@
/******************************************************************************/
// Copyright 2006-2007 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/******************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_camera_profile.h#2 $ */
/* $DateTime: 2012/07/11 10:36:56 $ */
/* $Change: 838485 $ */
/* $Author: tknoll $ */
/** \file
* Support for DNG camera color profile information.
* Per the \ref spec_dng "DNG 1.1.0 specification", a DNG file can store up to
* two sets of color profile information for a camera in the DNG file from that
* camera. The second set is optional and when there are two sets, they represent
* profiles made under different illumination.
*
* Profiling information is optionally separated into two parts. One part represents
* a profile for a reference camera. (ColorMatrix1 and ColorMatrix2 here.) The
* second is a per-camera calibration that takes into account unit-to-unit variation.
* This is designed to allow replacing the reference color matrix with one of one's
* own construction while maintaining any unit-specific calibration the camera
* manufacturer may have provided.
*
* See Appendix 6 of the \ref spec_dng "DNG 1.1.0 specification" for more information.
*/
#ifndef __dng_camera_profile__
#define __dng_camera_profile__
/******************************************************************************/
#include "dng_auto_ptr.h"
#include "dng_assertions.h"
#include "dng_classes.h"
#include "dng_fingerprint.h"
#include "dng_hue_sat_map.h"
#include "dng_matrix.h"
#include "dng_string.h"
#include "dng_tag_values.h"
#include "dng_tone_curve.h"
/******************************************************************************/
extern const char * kProfileName_Embedded;
extern const char * kAdobeCalibrationSignature;
/******************************************************************************/
/// \brief An ID for a camera profile consisting of a name and optional fingerprint.
class dng_camera_profile_id
{
private:
dng_string fName;
dng_fingerprint fFingerprint;
public:
/// Construct an invalid camera profile ID (empty name and fingerprint).
dng_camera_profile_id ()
: fName ()
, fFingerprint ()
{
}
/// Construct a camera profile ID with the specified name and no fingerprint.
/// \param name The name of the camera profile ID.
dng_camera_profile_id (const char *name)
: fName ()
, fFingerprint ()
{
fName.Set (name);
}
/// Construct a camera profile ID with the specified name and no fingerprint.
/// \param name The name of the camera profile ID.
dng_camera_profile_id (const dng_string &name)
: fName (name)
, fFingerprint ()
{
}
/// Construct a camera profile ID with the specified name and fingerprint.
/// \param name The name of the camera profile ID.
/// \param fingerprint The fingerprint of the camera profile ID.
dng_camera_profile_id (const char *name,
const dng_fingerprint &fingerprint)
: fName ()
, fFingerprint (fingerprint)
{
fName.Set (name);
DNG_ASSERT (!fFingerprint.IsValid () || fName.NotEmpty (),
"Cannot have profile fingerprint without name");
}
/// Construct a camera profile ID with the specified name and fingerprint.
/// \param name The name of the camera profile ID.
/// \param fingerprint The fingerprint of the camera profile ID.
dng_camera_profile_id (const dng_string &name,
const dng_fingerprint &fingerprint)
: fName (name)
, fFingerprint (fingerprint)
{
DNG_ASSERT (!fFingerprint.IsValid () || fName.NotEmpty (),
"Cannot have profile fingerprint without name");
}
/// Getter for the name of the camera profile ID.
/// \retval The name of the camera profile ID.
const dng_string & Name () const
{
return fName;
}
/// Getter for the fingerprint of the camera profile ID.
/// \retval The fingerprint of the camera profile ID.
const dng_fingerprint & Fingerprint () const
{
return fFingerprint;
}
/// Test for equality of two camera profile IDs.
/// \param The id of the camera profile ID to compare.
bool operator== (const dng_camera_profile_id &id) const
{
return fName == id.fName &&
fFingerprint == id.fFingerprint;
}
/// Test for inequality of two camera profile IDs.
/// \param The id of the camera profile ID to compare.
bool operator!= (const dng_camera_profile_id &id) const
{
return !(*this == id);
}
/// Returns true iff the camera profile ID is valid.
bool IsValid () const
{
return fName.NotEmpty (); // Fingerprint is optional.
}
/// Resets the name and fingerprint, thereby making this camera profile ID
/// invalid.
void Clear ()
{
*this = dng_camera_profile_id ();
}
};
/******************************************************************************/
/// \brief Container for DNG camera color profile and calibration data.
class dng_camera_profile
{
protected:
// Name of this camera profile.
dng_string fName;
// Light sources for up to two calibrations. These use the EXIF
// encodings for illuminant and are used to distinguish which
// matrix to use.
uint32 fCalibrationIlluminant1;
uint32 fCalibrationIlluminant2;
// Color matrices for up to two calibrations.
// These matrices map XYZ values to non-white balanced camera values.
// Adobe needs to go that direction in order to determine the clipping
// points for highlight recovery logic based on the white point. If
// cameras were all 3-color, the matrix could be stored as a forward matrix,
// but we need the backwards matrix to deal with 4-color cameras.
dng_matrix fColorMatrix1;
dng_matrix fColorMatrix2;
// These matrices map white balanced camera values to XYZ chromatically
// adapted to D50 (the ICC profile PCS white point). If the matrices
// exist, then this implies that white balancing should be done by scaling
// camera values with a diagonal matrix.
dng_matrix fForwardMatrix1;
dng_matrix fForwardMatrix2;
// Dimensionality reduction hints for more than three color cameras.
// This is an optional matrix that maps the camera's color components
// to 3 components. These are only used if the forward matrices don't
// exist, and are used invert the color matrices.
dng_matrix fReductionMatrix1;
dng_matrix fReductionMatrix2;
// MD5 hash for all data bits of the profile.
mutable dng_fingerprint fFingerprint;
// Copyright notice from creator of profile.
dng_string fCopyright;
// Rules for how this profile can be embedded and/or copied.
uint32 fEmbedPolicy;
// 2-D (or 3-D) hue/sat tables to modify colors.
dng_hue_sat_map fHueSatDeltas1;
dng_hue_sat_map fHueSatDeltas2;
// Value (V of HSV) encoding for hue/sat tables.
uint32 fHueSatMapEncoding;
// 3-D hue/sat table to apply a "look".
dng_hue_sat_map fLookTable;
// Value (V of HSV) encoding for look table.
uint32 fLookTableEncoding;
// Baseline exposure offset. When using this profile, this offset value is
// added to the BaselineExposure value for the negative to determine the
// overall baseline exposure to apply.
dng_srational fBaselineExposureOffset;
// Default black rendering.
uint32 fDefaultBlackRender;
// The "as shot" tone curve for this profile. Check IsValid method
// to tell if one exists in profile.
dng_tone_curve fToneCurve;
// If this string matches the fCameraCalibrationSignature of the
// negative, then use the calibration matrix values from the negative.
dng_string fProfileCalibrationSignature;
// If non-empty, only allow use of this profile with camera having
// same unique model name.
dng_string fUniqueCameraModelRestriction;
// Was this profile read from inside a DNG file? (If so, we wnat
// to be sure to include it again when writing out an updated
// DNG file)
bool fWasReadFromDNG;
// Was this profile read from disk (i.e., an external profile)? (If so, we
// may need to refresh when changes are made externally to the profile
// directory.)
bool fWasReadFromDisk;
// Was this profile a built-in "Matrix" profile? (If so, we may need to
// refresh -- i.e., remove it from the list of available profiles -- when
// changes are made externally to the profile directory.)
bool fWasBuiltinMatrix;
// Was this profile stubbed to save memory (and no longer valid
// for building color conversion tables)?
bool fWasStubbed;
public:
dng_camera_profile ();
virtual ~dng_camera_profile ();
// API for profile name:
/// Setter for camera profile name.
/// \param name Name to use for this camera profile.
void SetName (const char *name)
{
fName.Set (name);
ClearFingerprint ();
}
/// Getter for camera profile name.
/// \retval Name of profile.
const dng_string & Name () const
{
return fName;
}
/// Test if this name is embedded.
/// \retval true if the name matches the name of the embedded camera profile.
bool NameIsEmbedded () const
{
return fName.Matches (kProfileName_Embedded, true);
}
// API for calibration illuminants:
/// Setter for first of up to two light sources used for calibration.
/// Uses the EXIF encodings for illuminant and is used to distinguish which
/// matrix to use.
/// Corresponds to the DNG CalibrationIlluminant1 tag.
void SetCalibrationIlluminant1 (uint32 light)
{
fCalibrationIlluminant1 = light;
ClearFingerprint ();
}
/// Setter for second of up to two light sources used for calibration.
/// Uses the EXIF encodings for illuminant and is used to distinguish which
/// matrix to use.
/// Corresponds to the DNG CalibrationIlluminant2 tag.
void SetCalibrationIlluminant2 (uint32 light)
{
fCalibrationIlluminant2 = light;
ClearFingerprint ();
}
/// Getter for first of up to two light sources used for calibration.
/// Uses the EXIF encodings for illuminant and is used to distinguish which
/// matrix to use.
/// Corresponds to the DNG CalibrationIlluminant1 tag.
uint32 CalibrationIlluminant1 () const
{
return fCalibrationIlluminant1;
}
/// Getter for second of up to two light sources used for calibration.
/// Uses the EXIF encodings for illuminant and is used to distinguish which
/// matrix to use.
/// Corresponds to the DNG CalibrationIlluminant2 tag.
uint32 CalibrationIlluminant2 () const
{
return fCalibrationIlluminant2;
}
/// Getter for first of up to two light sources used for calibration, returning
/// result as color temperature.
real64 CalibrationTemperature1 () const
{
return IlluminantToTemperature (CalibrationIlluminant1 ());
}
/// Getter for second of up to two light sources used for calibration, returning
/// result as color temperature.
real64 CalibrationTemperature2 () const
{
return IlluminantToTemperature (CalibrationIlluminant2 ());
}
// API for color matrices:
/// Utility function to normalize the scale of the color matrix.
static void NormalizeColorMatrix (dng_matrix &m);
/// Setter for first of up to two color matrices used for reference camera calibrations.
/// These matrices map XYZ values to camera values. The DNG SDK needs to map colors
/// that direction in order to determine the clipping points for
/// highlight recovery logic based on the white point. If cameras
/// were all three-color, the matrix could be stored as a forward matrix.
/// The inverse matrix is requried to support four-color cameras.
void SetColorMatrix1 (const dng_matrix &m);
/// Setter for second of up to two color matrices used for reference camera calibrations.
/// These matrices map XYZ values to camera values. The DNG SDK needs to map colors
/// that direction in order to determine the clipping points for
/// highlight recovery logic based on the white point. If cameras
/// were all three-color, the matrix could be stored as a forward matrix.
/// The inverse matrix is requried to support four-color cameras.
void SetColorMatrix2 (const dng_matrix &m);
/// Predicate to test if first camera matrix is set
bool HasColorMatrix1 () const;
/// Predicate to test if second camera matrix is set
bool HasColorMatrix2 () const;
/// Getter for first of up to two color matrices used for calibrations.
const dng_matrix & ColorMatrix1 () const
{
return fColorMatrix1;
}
/// Getter for second of up to two color matrices used for calibrations.
const dng_matrix & ColorMatrix2 () const
{
return fColorMatrix2;
}
// API for forward matrices:
/// Utility function to normalize the scale of the forward matrix.
static void NormalizeForwardMatrix (dng_matrix &m);
/// Setter for first of up to two forward matrices used for calibrations.
void SetForwardMatrix1 (const dng_matrix &m);
/// Setter for second of up to two forward matrices used for calibrations.
void SetForwardMatrix2 (const dng_matrix &m);
/// Getter for first of up to two forward matrices used for calibrations.
const dng_matrix & ForwardMatrix1 () const
{
return fForwardMatrix1;
}
/// Getter for second of up to two forward matrices used for calibrations.
const dng_matrix & ForwardMatrix2 () const
{
return fForwardMatrix2;
}
// API for reduction matrices:
/// Setter for first of up to two dimensionality reduction hints for four-color cameras.
/// This is an optional matrix that maps four components to three.
/// See Appendix 6 of the \ref spec_dng "DNG 1.1.0 specification."
void SetReductionMatrix1 (const dng_matrix &m);
/// Setter for second of up to two dimensionality reduction hints for four-color cameras.
/// This is an optional matrix that maps four components to three.
/// See Appendix 6 of the \ref spec_dng "DNG 1.1.0 specification."
void SetReductionMatrix2 (const dng_matrix &m);
/// Getter for first of up to two dimensionality reduction hints for four color cameras.
const dng_matrix & ReductionMatrix1 () const
{
return fReductionMatrix1;
}
/// Getter for second of up to two dimensionality reduction hints for four color cameras.
const dng_matrix & ReductionMatrix2 () const
{
return fReductionMatrix2;
}
/// Getter function from profile fingerprint.
const dng_fingerprint &Fingerprint () const
{
if (!fFingerprint.IsValid ())
CalculateFingerprint ();
return fFingerprint;
}
/// Getter for camera profile id.
/// \retval ID of profile.
dng_camera_profile_id ProfileID () const
{
return dng_camera_profile_id (Name (), Fingerprint ());
}
/// Setter for camera profile copyright.
/// \param copyright Copyright string to use for this camera profile.
void SetCopyright (const char *copyright)
{
fCopyright.Set (copyright);
ClearFingerprint ();
}
/// Getter for camera profile copyright.
/// \retval Copyright string for profile.
const dng_string & Copyright () const
{
return fCopyright;
}
// Accessors for embed policy.
/// Setter for camera profile embed policy.
/// \param policy Policy to use for this camera profile.
void SetEmbedPolicy (uint32 policy)
{
fEmbedPolicy = policy;
ClearFingerprint ();
}
/// Getter for camera profile embed policy.
/// \param Policy for profile.
uint32 EmbedPolicy () const
{
return fEmbedPolicy;
}
/// Returns true iff the profile is legal to embed in a DNG, per the
/// profile's embed policy.
bool IsLegalToEmbed () const
{
return WasReadFromDNG () ||
EmbedPolicy () == pepAllowCopying ||
EmbedPolicy () == pepEmbedIfUsed ||
EmbedPolicy () == pepNoRestrictions;
}
// Accessors for hue sat maps.
/// Returns true iff the profile has a valid HueSatMap color table.
bool HasHueSatDeltas () const
{
return fHueSatDeltas1.IsValid ();
}
/// Getter for first HueSatMap color table (for calibration illuminant 1).
const dng_hue_sat_map & HueSatDeltas1 () const
{
return fHueSatDeltas1;
}
/// Setter for first HueSatMap color table (for calibration illuminant 1).
void SetHueSatDeltas1 (const dng_hue_sat_map &deltas1);
/// Getter for second HueSatMap color table (for calibration illuminant 2).
const dng_hue_sat_map & HueSatDeltas2 () const
{
return fHueSatDeltas2;
}
/// Setter for second HueSatMap color table (for calibration illuminant 2).
void SetHueSatDeltas2 (const dng_hue_sat_map &deltas2);
// Accessors for hue sat map encoding.
/// Returns the hue sat map encoding (see ProfileHueSatMapEncoding tag).
uint32 HueSatMapEncoding () const
{
return fHueSatMapEncoding;
}
/// Sets the hue sat map encoding (see ProfileHueSatMapEncoding tag) to the
/// specified encoding.
void SetHueSatMapEncoding (uint32 encoding)
{
fHueSatMapEncoding = encoding;
ClearFingerprint ();
}
// Accessors for look table.
/// Returns true if the profile has a LookTable.
bool HasLookTable () const
{
return fLookTable.IsValid ();
}
/// Getter for LookTable.
const dng_hue_sat_map & LookTable () const
{
return fLookTable;
}
/// Setter for LookTable.
void SetLookTable (const dng_hue_sat_map &table);
// Accessors for look table encoding.
/// Returns the LookTable encoding (see ProfileLookTableEncoding tag).
uint32 LookTableEncoding () const
{
return fLookTableEncoding;
}
/// Sets the LookTable encoding (see ProfileLookTableEncoding tag) to the
/// specified encoding.
void SetLookTableEncoding (uint32 encoding)
{
fLookTableEncoding = encoding;
ClearFingerprint ();
}
// Accessors for baseline exposure offset.
/// Sets the baseline exposure offset of the profile (see
/// BaselineExposureOffset tag) to the specified value.
void SetBaselineExposureOffset (real64 exposureOffset)
{
fBaselineExposureOffset.Set_real64 (exposureOffset, 100);
ClearFingerprint ();
}
/// Returns the baseline exposure offset of the profile (see
/// BaselineExposureOffset tag).
const dng_srational & BaselineExposureOffset () const
{
return fBaselineExposureOffset;
}
// Accessors for default black render.
/// Sets the default black render of the profile (see DefaultBlackRender tag)
/// to the specified option.
void SetDefaultBlackRender (uint32 defaultBlackRender)
{
fDefaultBlackRender = defaultBlackRender;
ClearFingerprint ();
}
/// Returns the default black render of the profile (see DefaultBlackRender
/// tag).
uint32 DefaultBlackRender () const
{
return fDefaultBlackRender;
}
// Accessors for tone curve.
/// Returns the tone curve of the profile.
const dng_tone_curve & ToneCurve () const
{
return fToneCurve;
}
/// Sets the tone curve of the profile to the specified curve.
void SetToneCurve (const dng_tone_curve &curve)
{
fToneCurve = curve;
ClearFingerprint ();
}
// Accessors for profile calibration signature.
/// Sets the profile calibration signature (see ProfileCalibrationSignature
/// tag) to the specified string.
void SetProfileCalibrationSignature (const char *signature)
{
fProfileCalibrationSignature.Set (signature);
}
/// Returns the profile calibration signature (see ProfileCalibrationSignature
/// tag) of the profile.
const dng_string & ProfileCalibrationSignature () const
{
return fProfileCalibrationSignature;
}
/// Setter for camera unique model name to restrict use of this profile.
/// \param camera Camera unique model name designating only camera this
/// profile can be used with. (Empty string for no restriction.)
void SetUniqueCameraModelRestriction (const char *camera)
{
fUniqueCameraModelRestriction.Set (camera);
// Not included in fingerprint, so don't need ClearFingerprint ().
}
/// Getter for camera unique model name to restrict use of this profile.
/// \retval Unique model name of only camera this profile can be used with
/// or empty if no restriction.
const dng_string & UniqueCameraModelRestriction () const
{
return fUniqueCameraModelRestriction;
}
// Accessors for was read from DNG flag.
/// Sets internal flag to indicate this profile was originally read from a
/// DNG file.
void SetWasReadFromDNG (bool state = true)
{
fWasReadFromDNG = state;
}
/// Was this profile read from a DNG?
bool WasReadFromDNG () const
{
return fWasReadFromDNG;
}
// Accessors for was read from disk flag.
/// Sets internal flag to indicate this profile was originally read from
/// disk.
void SetWasReadFromDisk (bool state = true)
{
fWasReadFromDisk = state;
}
/// Was this profile read from disk?
bool WasReadFromDisk () const
{
return fWasReadFromDisk;
}
// Accessors for was built-in matrix flag.
/// Sets internal flag to indicate this profile was originally a built-in
/// matrix profile.
void SetWasBuiltinMatrix (bool state = true)
{
fWasBuiltinMatrix = state;
}
/// Was this profile a built-in matrix profile?
bool WasBuiltinMatrix () const
{
return fWasBuiltinMatrix;
}
/// Determines if this a valid profile for this number of color channels?
/// \retval true if the profile is valid.
bool IsValid (uint32 channels) const;
/// Predicate to check if two camera profiles are colorwise equal, thus ignores
/// the profile name.
/// \param profile Camera profile to compare to.
bool EqualData (const dng_camera_profile &profile) const;
/// Parse profile from dng_camera_profile_info data.
void Parse (dng_stream &stream,
dng_camera_profile_info &profileInfo);
/// Parse from an extended profile stream, which is similar to stand alone
/// TIFF file.
bool ParseExtended (dng_stream &stream);
/// Convert from a three-color to a four-color Bayer profile.
virtual void SetFourColorBayer ();
/// Find the hue/sat table to use for a given white point, if any.
/// The calling routine owns the resulting table.
dng_hue_sat_map * HueSatMapForWhite (const dng_xy_coord &white) const;
/// Stub out the profile (free memory used by large tables).
void Stub ();
/// Was this profile stubbed?
bool WasStubbed () const
{
return fWasStubbed;
}
protected:
static real64 IlluminantToTemperature (uint32 light);
void ClearFingerprint ()
{
fFingerprint.Clear ();
}
void CalculateFingerprint () const;
static bool ValidForwardMatrix (const dng_matrix &m);
static void ReadHueSatMap (dng_stream &stream,
dng_hue_sat_map &hueSatMap,
uint32 hues,
uint32 sats,
uint32 vals,
bool skipSat0);
};
/******************************************************************************/
void SplitCameraProfileName (const dng_string &name,
dng_string &baseName,
int32 &version);
/*****************************************************************************/
void BuildHueSatMapEncodingTable (dng_memory_allocator &allocator,
uint32 encoding,
AutoPtr<dng_1d_table> &encodeTable,
AutoPtr<dng_1d_table> &decodeTable,
bool subSample);
/******************************************************************************/
#endif
/******************************************************************************/

Wyświetl plik

@ -0,0 +1,100 @@
/*****************************************************************************/
// Copyright 2006-2008 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_classes.h#1 $ */
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */
/*** \file
* Forward class declarations to avoid having to include many .h files in most places.
*/
/*****************************************************************************/
#ifndef __dng_classes__
#define __dng_classes__
/*****************************************************************************/
class dng_1d_function;
class dng_1d_table;
class dng_abort_sniffer;
class dng_area_task;
class dng_basic_tag_set;
class dng_camera_profile;
class dng_camera_profile_id;
class dng_camera_profile_info;
class dng_color_space;
class dng_color_spec;
class dng_date_time;
class dng_date_time_info;
class dng_exif;
class dng_fingerprint;
class dng_host;
class dng_hue_sat_map;
class dng_ifd;
class dng_image;
class dng_image_preview;
class dng_image_writer;
class dng_info;
class dng_iptc;
class dng_jpeg_image;
class dng_jpeg_preview;
class dng_linearization_info;
class dng_matrix;
class dng_matrix_3by3;
class dng_matrix_4by3;
class dng_md5_printer;
class dng_memory_allocator;
class dng_memory_block;
class dng_memory_data;
class dng_memory_stream;
class dng_metadata;
class dng_mosaic_info;
class dng_mutex;
class dng_noise_function;
class dng_noise_profile;
class dng_opcode;
class dng_opcode_list;
class dng_orientation;
class dng_negative;
class dng_pixel_buffer;
class dng_point;
class dng_point_real64;
class dng_preview;
class dng_preview_info;
class dng_preview_list;
class dng_raw_preview;
class dng_read_image;
class dng_rect;
class dng_rect_real64;
class dng_render;
class dng_resolution;
class dng_shared;
class dng_spline_solver;
class dng_srational;
class dng_stream;
class dng_string;
class dng_string_list;
class dng_tiff_directory;
class dng_tile_buffer;
class dng_time_zone;
class dng_tone_curve;
class dng_urational;
class dng_vector;
class dng_vector_3;
class dng_xmp;
class dng_xmp_sdk;
class dng_xy_coord;
/*****************************************************************************/
#endif
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,351 @@
/*****************************************************************************/
// Copyright 2006 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_color_space.h#2 $ */
/* $DateTime: 2012/07/11 10:36:56 $ */
/* $Change: 838485 $ */
/* $Author: tknoll $ */
/** \file
* Standard gamma functions and color spaces used within the DNG SDK.
*/
#ifndef __dng_color_space__
#define __dng_color_space__
/*****************************************************************************/
#include "dng_1d_function.h"
#include "dng_classes.h"
#include "dng_matrix.h"
#include "dng_types.h"
/*****************************************************************************/
/// \brief A dng_1d_function for gamma encoding in sRGB color space
class dng_function_GammaEncode_sRGB: public dng_1d_function
{
public:
virtual real64 Evaluate (real64 x) const;
virtual real64 EvaluateInverse (real64 y) const;
static const dng_1d_function & Get ();
};
/*****************************************************************************/
/// \brief A dng_1d_function for gamma encoding with 1.8 gamma.
class dng_function_GammaEncode_1_8: public dng_1d_function
{
public:
virtual real64 Evaluate (real64 x) const;
virtual real64 EvaluateInverse (real64 y) const;
static const dng_1d_function & Get ();
};
/*****************************************************************************/
/// \brief A dng_1d_function for gamma encoding with 2.2 gamma.
class dng_function_GammaEncode_2_2: public dng_1d_function
{
public:
virtual real64 Evaluate (real64 x) const;
virtual real64 EvaluateInverse (real64 y) const;
static const dng_1d_function & Get ();
};
/*****************************************************************************/
/// \brief An abstract color space
class dng_color_space
{
protected:
dng_matrix fMatrixToPCS;
dng_matrix fMatrixFromPCS;
public:
virtual ~dng_color_space ();
/// Return a matrix which transforms source data in this color space into the
/// Profile Connection Space.
const dng_matrix & MatrixToPCS () const
{
return fMatrixToPCS;
}
/// Return a matrix which transforms Profile Connection Space data into this
/// color space.
const dng_matrix & MatrixFromPCS () const
{
return fMatrixFromPCS;
}
/// Predicate which is true if this color space is monochrome (has only a
/// single column).
bool IsMonochrome () const
{
return fMatrixToPCS.Cols () == 1;
}
/// Getter for the gamma function for this color space.
virtual const dng_1d_function & GammaFunction () const;
/// Returns true if this color space is linear. (I.e. has gamma 1.0.)
bool IsLinear () const
{
return GammaFunction ().IsIdentity ();
}
/// Map an input value through this color space's encoding gamma.
real64 GammaEncode (real64 x) const
{
return GammaFunction ().Evaluate (x);
}
/// Map an input value through this color space's decoding gamma (inverse of
/// the encoding gamma).
real64 GammaDecode (real64 y) const
{
return GammaFunction ().EvaluateInverse (y);
}
/// Getter for ICC profile, if this color space has one.
/// \param size Out parameter which receives size on return.
/// \param data Receives bytes of profile.
/// \retval Returns true if this color space has an ICC profile, false otherwise.
virtual bool ICCProfile (uint32 &size,
const uint8 *&data) const;
protected:
dng_color_space ();
void SetMonochrome ();
void SetMatrixToPCS (const dng_matrix_3by3 &M);
};
/*****************************************************************************/
/// Singleton class for sRGB color space.
class dng_space_sRGB: public dng_color_space
{
protected:
dng_space_sRGB ();
public:
/// Returns dng_function_GammaEncode_sRGB
virtual const dng_1d_function & GammaFunction () const;
/// Returns sRGB IEC61966-2.1 ICC profile
virtual bool ICCProfile (uint32 &size,
const uint8 *&data) const;
/// Static method for getting single global instance of this color space.
static const dng_color_space & Get ();
};
/*****************************************************************************/
/// \brief Singleton class for AdobeRGB color space.
class dng_space_AdobeRGB: public dng_color_space
{
protected:
dng_space_AdobeRGB ();
public:
/// Returns dng_function_GammaEncode_1_8
virtual const dng_1d_function & GammaFunction () const;
/// Returns AdobeRGB (1998) ICC profile
virtual bool ICCProfile (uint32 &size,
const uint8 *&data) const;
/// Static method for getting single global instance of this color space.
static const dng_color_space & Get ();
};
/*****************************************************************************/
/// \brief Singleton class for ColorMatch color space.
class dng_space_ColorMatch: public dng_color_space
{
protected:
dng_space_ColorMatch ();
public:
/// Returns dng_function_GammaEncode_1_8
virtual const dng_1d_function & GammaFunction () const;
/// Returns ColorMatch RGB ICC profile
virtual bool ICCProfile (uint32 &size,
const uint8 *&data) const;
/// Static method for getting single global instance of this color space.
static const dng_color_space & Get ();
};
/*****************************************************************************/
/// \brief Singleton class for ProPhoto RGB color space.
class dng_space_ProPhoto: public dng_color_space
{
protected:
dng_space_ProPhoto ();
public:
/// Returns dng_function_GammaEncode_1_8
virtual const dng_1d_function & GammaFunction () const;
/// Returns ProPhoto RGB ICC profile
virtual bool ICCProfile (uint32 &size,
const uint8 *&data) const;
/// Static method for getting single global instance of this color space.
static const dng_color_space & Get ();
};
/*****************************************************************************/
/// \brief Singleton class for gamma 1.8 grayscale color space.
class dng_space_GrayGamma18: public dng_color_space
{
protected:
dng_space_GrayGamma18 ();
public:
/// Returns dng_function_GammaEncode_1_8
virtual const dng_1d_function & GammaFunction () const;
/// Returns simple grayscale gamma 1.8 ICC profile
virtual bool ICCProfile (uint32 &size,
const uint8 *&data) const;
/// Static method for getting single global instance of this color space.
static const dng_color_space & Get ();
};
/*****************************************************************************/
/// \brief Singleton class for gamma 2.2 grayscale color space.
class dng_space_GrayGamma22: public dng_color_space
{
protected:
dng_space_GrayGamma22 ();
public:
/// Returns dng_function_GammaEncode_2_2
virtual const dng_1d_function & GammaFunction () const;
/// Returns simple grayscale gamma 2.2 ICC profile
virtual bool ICCProfile (uint32 &size,
const uint8 *&data) const;
/// Static method for getting single global instance of this color space.
static const dng_color_space & Get ();
};
/*****************************************************************************/
class dng_space_fakeRGB: public dng_color_space
{
protected:
dng_space_fakeRGB ();
public:
static const dng_color_space & Get ();
};
/*****************************************************************************/
#endif
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,559 @@
/*****************************************************************************/
// Copyright 2006-2008 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_color_spec.cpp#1 $ */
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */
#include "dng_color_spec.h"
#include "dng_assertions.h"
#include "dng_camera_profile.h"
#include "dng_exceptions.h"
#include "dng_matrix.h"
#include "dng_negative.h"
#include "dng_temperature.h"
#include "dng_utils.h"
#include "dng_xy_coord.h"
/*****************************************************************************/
dng_matrix_3by3 MapWhiteMatrix (const dng_xy_coord &white1,
const dng_xy_coord &white2)
{
// Use the linearized Bradford adaptation matrix.
dng_matrix_3by3 Mb ( 0.8951, 0.2664, -0.1614,
-0.7502, 1.7135, 0.0367,
0.0389, -0.0685, 1.0296);
dng_vector_3 w1 = Mb * XYtoXYZ (white1);
dng_vector_3 w2 = Mb * XYtoXYZ (white2);
// Negative white coordinates are kind of meaningless.
w1 [0] = Max_real64 (w1 [0], 0.0);
w1 [1] = Max_real64 (w1 [1], 0.0);
w1 [2] = Max_real64 (w1 [2], 0.0);
w2 [0] = Max_real64 (w2 [0], 0.0);
w2 [1] = Max_real64 (w2 [1], 0.0);
w2 [2] = Max_real64 (w2 [2], 0.0);
// Limit scaling to something reasonable.
dng_matrix_3by3 A;
A [0] [0] = Pin_real64 (0.1, w1 [0] > 0.0 ? w2 [0] / w1 [0] : 10.0, 10.0);
A [1] [1] = Pin_real64 (0.1, w1 [1] > 0.0 ? w2 [1] / w1 [1] : 10.0, 10.0);
A [2] [2] = Pin_real64 (0.1, w1 [2] > 0.0 ? w2 [2] / w1 [2] : 10.0, 10.0);
dng_matrix_3by3 B = Invert (Mb) * A * Mb;
return B;
}
/******************************************************************************/
dng_color_spec::dng_color_spec (const dng_negative &negative,
const dng_camera_profile *profile)
: fChannels (negative.ColorChannels ())
, fTemperature1 (0.0)
, fTemperature2 (0.0)
, fColorMatrix1 ()
, fColorMatrix2 ()
, fForwardMatrix1 ()
, fForwardMatrix2 ()
, fReductionMatrix1 ()
, fReductionMatrix2 ()
, fCameraCalibration1 ()
, fCameraCalibration2 ()
, fAnalogBalance ()
, fWhiteXY ()
, fCameraWhite ()
, fCameraToPCS ()
, fPCStoCamera ()
{
if (fChannels > 1)
{
if (!profile || !profile->IsValid (fChannels))
{
ThrowBadFormat ();
}
if (profile->WasStubbed ())
{
ThrowProgramError ("Using stubbed profile");
}
fTemperature1 = profile->CalibrationTemperature1 ();
fTemperature2 = profile->CalibrationTemperature2 ();
fColorMatrix1 = profile->ColorMatrix1 ();
fColorMatrix2 = profile->ColorMatrix2 ();
fForwardMatrix1 = profile->ForwardMatrix1 ();
fForwardMatrix2 = profile->ForwardMatrix2 ();
fReductionMatrix1 = profile->ReductionMatrix1 ();
fReductionMatrix2 = profile->ReductionMatrix2 ();
fCameraCalibration1.SetIdentity (fChannels);
fCameraCalibration2.SetIdentity (fChannels);
if (negative. CameraCalibrationSignature () ==
profile->ProfileCalibrationSignature ())
{
if (negative.CameraCalibration1 ().Rows () == fChannels &&
negative.CameraCalibration1 ().Cols () == fChannels)
{
fCameraCalibration1 = negative.CameraCalibration1 ();
}
if (negative.CameraCalibration2 ().Rows () == fChannels &&
negative.CameraCalibration2 ().Cols () == fChannels)
{
fCameraCalibration2 = negative.CameraCalibration2 ();
}
}
fAnalogBalance = dng_matrix (fChannels, fChannels);
for (uint32 j = 0; j < fChannels; j++)
{
fAnalogBalance [j] [j] = negative.AnalogBalance (j);
}
dng_camera_profile::NormalizeForwardMatrix (fForwardMatrix1);
fColorMatrix1 = fAnalogBalance * fCameraCalibration1 * fColorMatrix1;
if (!profile->HasColorMatrix2 () ||
fTemperature1 <= 0.0 ||
fTemperature2 <= 0.0 ||
fTemperature1 == fTemperature2)
{
fTemperature1 = 5000.0;
fTemperature2 = 5000.0;
fColorMatrix2 = fColorMatrix1;
fForwardMatrix2 = fForwardMatrix1;
fReductionMatrix2 = fReductionMatrix1;
fCameraCalibration2 = fCameraCalibration1;
}
else
{
dng_camera_profile::NormalizeForwardMatrix (fForwardMatrix2);
fColorMatrix2 = fAnalogBalance * fCameraCalibration2 * fColorMatrix2;
// Swap values if temperatures are out of order.
if (fTemperature1 > fTemperature2)
{
real64 temp = fTemperature1;
fTemperature1 = fTemperature2;
fTemperature2 = temp;
dng_matrix T = fColorMatrix1;
fColorMatrix1 = fColorMatrix2;
fColorMatrix2 = T;
T = fForwardMatrix1;
fForwardMatrix1 = fForwardMatrix2;
fForwardMatrix2 = T;
T = fReductionMatrix1;
fReductionMatrix1 = fReductionMatrix2;
fReductionMatrix2 = T;
T = fCameraCalibration1;
fCameraCalibration1 = fCameraCalibration2;
fCameraCalibration2 = T;
}
}
}
}
/*****************************************************************************/
dng_matrix dng_color_spec::FindXYZtoCamera (const dng_xy_coord &white,
dng_matrix *forwardMatrix,
dng_matrix *reductionMatrix,
dng_matrix *cameraCalibration)
{
// Convert to temperature/offset space.
dng_temperature td (white);
// Find fraction to weight the first calibration.
real64 g;
if (td.Temperature () <= fTemperature1)
g = 1.0;
else if (td.Temperature () >= fTemperature2)
g = 0.0;
else
{
real64 invT = 1.0 / td.Temperature ();
g = (invT - (1.0 / fTemperature2)) /
((1.0 / fTemperature1) - (1.0 / fTemperature2));
}
// Interpolate the color matrix.
dng_matrix colorMatrix;
if (g >= 1.0)
colorMatrix = fColorMatrix1;
else if (g <= 0.0)
colorMatrix = fColorMatrix2;
else
colorMatrix = (g ) * fColorMatrix1 +
(1.0 - g) * fColorMatrix2;
// Interpolate forward matrix, if any.
if (forwardMatrix)
{
bool has1 = fForwardMatrix1.NotEmpty ();
bool has2 = fForwardMatrix2.NotEmpty ();
if (has1 && has2)
{
if (g >= 1.0)
*forwardMatrix = fForwardMatrix1;
else if (g <= 0.0)
*forwardMatrix = fForwardMatrix2;
else
*forwardMatrix = (g ) * fForwardMatrix1 +
(1.0 - g) * fForwardMatrix2;
}
else if (has1)
{
*forwardMatrix = fForwardMatrix1;
}
else if (has2)
{
*forwardMatrix = fForwardMatrix2;
}
else
{
forwardMatrix->Clear ();
}
}
// Interpolate reduction matrix, if any.
if (reductionMatrix)
{
bool has1 = fReductionMatrix1.NotEmpty ();
bool has2 = fReductionMatrix2.NotEmpty ();
if (has1 && has2)
{
if (g >= 1.0)
*reductionMatrix = fReductionMatrix1;
else if (g <= 0.0)
*reductionMatrix = fReductionMatrix2;
else
*reductionMatrix = (g ) * fReductionMatrix1 +
(1.0 - g) * fReductionMatrix2;
}
else if (has1)
{
*reductionMatrix = fReductionMatrix1;
}
else if (has2)
{
*reductionMatrix = fReductionMatrix2;
}
else
{
reductionMatrix->Clear ();
}
}
// Interpolate camera calibration matrix.
if (cameraCalibration)
{
if (g >= 1.0)
*cameraCalibration = fCameraCalibration1;
else if (g <= 0.0)
*cameraCalibration = fCameraCalibration2;
else
*cameraCalibration = (g ) * fCameraCalibration1 +
(1.0 - g) * fCameraCalibration2;
}
// Return the interpolated color matrix.
return colorMatrix;
}
/*****************************************************************************/
void dng_color_spec::SetWhiteXY (const dng_xy_coord &white)
{
fWhiteXY = white;
// Deal with monochrome cameras.
if (fChannels == 1)
{
fCameraWhite.SetIdentity (1);
fCameraToPCS = PCStoXYZ ().AsColumn ();
return;
}
// Interpolate an matric values for this white point.
dng_matrix colorMatrix;
dng_matrix forwardMatrix;
dng_matrix reductionMatrix;
dng_matrix cameraCalibration;
colorMatrix = FindXYZtoCamera (fWhiteXY,
&forwardMatrix,
&reductionMatrix,
&cameraCalibration);
// Find the camera white values.
fCameraWhite = colorMatrix * XYtoXYZ (fWhiteXY);
real64 whiteScale = 1.0 / MaxEntry (fCameraWhite);
for (uint32 j = 0; j < fChannels; j++)
{
// We don't support non-positive values for camera neutral values.
fCameraWhite [j] = Pin_real64 (0.001,
whiteScale * fCameraWhite [j],
1.0);
}
// Find PCS to Camera transform. Scale matrix so PCS white can just be
// reached when the first camera channel saturates
fPCStoCamera = colorMatrix * MapWhiteMatrix (PCStoXY (), fWhiteXY);
real64 scale = MaxEntry (fPCStoCamera * PCStoXYZ ());
fPCStoCamera = (1.0 / scale) * fPCStoCamera;
// If we have a forward matrix, then just use that.
if (forwardMatrix.NotEmpty ())
{
dng_matrix individualToReference = Invert (fAnalogBalance * cameraCalibration);
dng_vector refCameraWhite = individualToReference * fCameraWhite;
fCameraToPCS = forwardMatrix *
Invert (refCameraWhite.AsDiagonal ()) *
individualToReference;
}
// Else we need to use the adapt in XYZ method.
else
{
// Invert this PCS to camera matrix. Note that if there are more than three
// camera channels, this inversion is non-unique.
fCameraToPCS = Invert (fPCStoCamera, reductionMatrix);
}
}
/*****************************************************************************/
const dng_xy_coord & dng_color_spec::WhiteXY () const
{
DNG_ASSERT (fWhiteXY.IsValid (), "Using invalid WhiteXY");
return fWhiteXY;
}
/*****************************************************************************/
const dng_vector & dng_color_spec::CameraWhite () const
{
DNG_ASSERT (fCameraWhite.NotEmpty (), "Using invalid CameraWhite");
return fCameraWhite;
}
/*****************************************************************************/
const dng_matrix & dng_color_spec::CameraToPCS () const
{
DNG_ASSERT (fCameraToPCS.NotEmpty (), "Using invalid CameraToPCS");
return fCameraToPCS;
}
/*****************************************************************************/
const dng_matrix & dng_color_spec::PCStoCamera () const
{
DNG_ASSERT (fPCStoCamera.NotEmpty (), "Using invalid PCStoCamera");
return fPCStoCamera;
}
/*****************************************************************************/
dng_xy_coord dng_color_spec::NeutralToXY (const dng_vector &neutral)
{
const uint32 kMaxPasses = 30;
if (fChannels == 1)
{
return PCStoXY ();
}
dng_xy_coord last = D50_xy_coord ();
for (uint32 pass = 0; pass < kMaxPasses; pass++)
{
dng_matrix xyzToCamera = FindXYZtoCamera (last);
dng_xy_coord next = XYZtoXY (Invert (xyzToCamera) * neutral);
if (Abs_real64 (next.x - last.x) +
Abs_real64 (next.y - last.y) < 0.0000001)
{
return next;
}
// If we reach the limit without converging, we are most likely
// in a two value oscillation. So take the average of the last
// two estimates and give up.
if (pass == kMaxPasses - 1)
{
next.x = (last.x + next.x) * 0.5;
next.y = (last.y + next.y) * 0.5;
}
last = next;
}
return last;
}
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,146 @@
/*****************************************************************************/
// Copyright 2006-2008 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_color_spec.h#1 $ */
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */
/** \file
* Class for holding a specific color transform.
*/
#ifndef __dng_color_spec__
#define __dng_color_spec__
/*****************************************************************************/
#include "dng_classes.h"
#include "dng_matrix.h"
#include "dng_types.h"
#include "dng_xy_coord.h"
/*****************************************************************************/
/// \brief Compute a 3x3 matrix which maps colors from white point white1 to
/// white point white2
///
/// Uses linearized Bradford adaptation matrix to compute a mapping from
/// colors measured with one white point (white1) to another (white2).
dng_matrix_3by3 MapWhiteMatrix (const dng_xy_coord &white1,
const dng_xy_coord &white2);
/*****************************************************************************/
/// Color transform taking into account white point and camera calibration and
/// individual calibration from DNG negative.
class dng_color_spec
{
private:
uint32 fChannels;
real64 fTemperature1;
real64 fTemperature2;
dng_matrix fColorMatrix1;
dng_matrix fColorMatrix2;
dng_matrix fForwardMatrix1;
dng_matrix fForwardMatrix2;
dng_matrix fReductionMatrix1;
dng_matrix fReductionMatrix2;
dng_matrix fCameraCalibration1;
dng_matrix fCameraCalibration2;
dng_matrix fAnalogBalance;
dng_xy_coord fWhiteXY;
dng_vector fCameraWhite;
dng_matrix fCameraToPCS;
dng_matrix fPCStoCamera;
public:
/// Read calibration info from DNG negative and construct a
/// dng_color_spec.
dng_color_spec (const dng_negative &negative,
const dng_camera_profile *profile);
virtual ~dng_color_spec ()
{
}
/// Number of channels used for this color transform. Three
/// for most cameras.
uint32 Channels () const
{
return fChannels;
}
/// Setter for white point. Value is as XY colorspace coordinate.
/// \param white White point to set as an XY value.
void SetWhiteXY (const dng_xy_coord &white);
/// Getter for white point. Value is as XY colorspace coordinate.
/// \retval XY value of white point.
const dng_xy_coord & WhiteXY () const;
/// Return white point in camera native color coordinates.
/// \retval A dng_vector with components ranging from 0.0 to 1.0
/// that is normalized such that one component is equal to 1.0 .
const dng_vector & CameraWhite () const;
/// Getter for camera to Profile Connection Space color transform.
/// \retval A transform that takes into account all camera calibration
/// transforms and white point.
const dng_matrix & CameraToPCS () const;
/// Getter for Profile Connection Space to camera color transform.
/// \retval A transform that takes into account all camera calibration
/// transforms and white point.
const dng_matrix & PCStoCamera () const;
/// Return the XY value to use for SetWhiteXY for a given camera color
/// space coordinate as the white point.
/// \param neutral A camera color space value to use for white point.
/// Components range from 0.0 to 1.0 and should be normalized such that
/// the largest value is 1.0 .
/// \retval White point in XY space that makes neutral map to this
/// XY value as closely as possible.
dng_xy_coord NeutralToXY (const dng_vector &neutral);
private:
dng_matrix FindXYZtoCamera (const dng_xy_coord &white,
dng_matrix *forwardMatrix = NULL,
dng_matrix *reductionMatrix = NULL,
dng_matrix *cameraCalibration = NULL);
};
/*****************************************************************************/
#endif
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,961 @@
/*****************************************************************************/
// Copyright 2006-2008 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_date_time.cpp#2 $ */
/* $DateTime: 2012/06/01 07:28:57 $ */
/* $Change: 832715 $ */
/* $Author: tknoll $ */
/*****************************************************************************/
#include "dng_date_time.h"
#include "dng_exceptions.h"
#include "dng_mutex.h"
#include "dng_stream.h"
#include "dng_string.h"
#include "dng_utils.h"
#include <time.h>
#include "stdc_includes.h"
#if qMacOS && qEnableCarbon
#include <CoreServices/CoreServices.h>
#endif
#if qWinOS
#include <windows.h>
#endif
/******************************************************************************/
// MWG says don't use fake time zones in XMP, but there is some
// old software that requires them to work correctly.
bool gDNGUseFakeTimeZonesInXMP = false;
/******************************************************************************/
dng_date_time::dng_date_time ()
: fYear (0)
, fMonth (0)
, fDay (0)
, fHour (0)
, fMinute (0)
, fSecond (0)
{
}
/******************************************************************************/
dng_date_time::dng_date_time (uint32 year,
uint32 month,
uint32 day,
uint32 hour,
uint32 minute,
uint32 second)
: fYear (year)
, fMonth (month)
, fDay (day)
, fHour (hour)
, fMinute (minute)
, fSecond (second)
{
}
/******************************************************************************/
bool dng_date_time::IsValid () const
{
return fYear >= 1 && fYear <= 9999 &&
fMonth >= 1 && fMonth <= 12 &&
fDay >= 1 && fDay <= 31 &&
fHour <= 23 &&
fMinute <= 59 &&
fSecond <= 59;
}
/*****************************************************************************/
void dng_date_time::Clear ()
{
*this = dng_date_time ();
}
/*****************************************************************************/
static uint32 DateTimeParseU32 (const char *&s)
{
uint32 x = 0;
while (*s == ' ' || *s == ':')
s++;
while (*s >= '0' && *s <= '9')
{
x = x * 10 + (uint32) (*(s++) - '0');
}
return x;
}
/*****************************************************************************/
bool dng_date_time::Parse (const char *s)
{
fYear = DateTimeParseU32 (s);
fMonth = DateTimeParseU32 (s);
fDay = DateTimeParseU32 (s);
fHour = DateTimeParseU32 (s);
fMinute = DateTimeParseU32 (s);
fSecond = DateTimeParseU32 (s);
return IsValid ();
}
/*****************************************************************************/
dng_string dng_time_zone::Encode_ISO_8601 () const
{
dng_string result;
if (IsValid ())
{
if (OffsetMinutes () == 0)
{
result.Set ("Z");
}
else
{
char s [64];
int offset = OffsetMinutes ();
if (offset > 0)
{
sprintf (s, "+%02d:%02d", offset / 60, offset % 60);
}
else
{
offset = -offset;
sprintf (s, "-%02d:%02d", offset / 60, offset % 60);
}
result.Set (s);
}
}
return result;
}
/*****************************************************************************/
dng_date_time_info::dng_date_time_info ()
: fDateOnly (true)
, fDateTime ()
, fSubseconds ()
, fTimeZone ()
{
}
/*****************************************************************************/
bool dng_date_time_info::IsValid () const
{
return fDateTime.IsValid ();
}
/*****************************************************************************/
void dng_date_time_info::SetDate (uint32 year,
uint32 month,
uint32 day)
{
fDateTime.fYear = year;
fDateTime.fMonth = month;
fDateTime.fDay = day;
}
/*****************************************************************************/
void dng_date_time_info::SetTime (uint32 hour,
uint32 minute,
uint32 second)
{
fDateOnly = false;
fDateTime.fHour = hour;
fDateTime.fMinute = minute;
fDateTime.fSecond = second;
}
/*****************************************************************************/
void dng_date_time_info::Decode_ISO_8601 (const char *s)
{
Clear ();
uint32 len = (uint32) strlen (s);
if (!len)
{
return;
}
unsigned year = 0;
unsigned month = 0;
unsigned day = 0;
if (sscanf (s,
"%u-%u-%u",
&year,
&month,
&day) != 3)
{
return;
}
SetDate ((uint32) year,
(uint32) month,
(uint32) day);
if (fDateTime.NotValid ())
{
Clear ();
return;
}
for (uint32 j = 0; j < len; j++)
{
if (s [j] == 'T')
{
unsigned hour = 0;
unsigned minute = 0;
unsigned second = 0;
int items = sscanf (s + j + 1,
"%u:%u:%u",
&hour,
&minute,
&second);
if (items >= 2 && items <= 3)
{
SetTime ((uint32) hour,
(uint32) minute,
(uint32) second);
if (fDateTime.NotValid ())
{
Clear ();
return;
}
if (items == 3)
{
for (uint32 k = j + 1; k < len; k++)
{
if (s [k] == '.')
{
while (++k < len && s [k] >= '0' && s [k] <= '9')
{
char ss [2];
ss [0] = s [k];
ss [1] = 0;
fSubseconds.Append (ss);
}
break;
}
}
}
for (uint32 k = j + 1; k < len; k++)
{
if (s [k] == 'Z')
{
fTimeZone.SetOffsetMinutes (0);
break;
}
if (s [k] == '+' || s [k] == '-')
{
int32 sign = (s [k] == '-' ? -1 : 1);
unsigned tzhour = 0;
unsigned tzmin = 0;
if (sscanf (s + k + 1,
"%u:%u",
&tzhour,
&tzmin) > 0)
{
fTimeZone.SetOffsetMinutes (sign * (tzhour * 60 + tzmin));
}
break;
}
}
}
break;
}
}
}
/*****************************************************************************/
dng_string dng_date_time_info::Encode_ISO_8601 () const
{
dng_string result;
if (IsValid ())
{
char s [256];
sprintf (s,
"%04u-%02u-%02u",
(unsigned) fDateTime.fYear,
(unsigned) fDateTime.fMonth,
(unsigned) fDateTime.fDay);
result.Set (s);
if (!fDateOnly)
{
sprintf (s,
"T%02u:%02u:%02u",
(unsigned) fDateTime.fHour,
(unsigned) fDateTime.fMinute,
(unsigned) fDateTime.fSecond);
result.Append (s);
if (fSubseconds.NotEmpty ())
{
bool subsecondsValid = true;
uint32 len = fSubseconds.Length ();
for (uint32 index = 0; index < len; index++)
{
if (fSubseconds.Get () [index] < '0' ||
fSubseconds.Get () [index] > '9')
{
subsecondsValid = false;
break;
}
}
if (subsecondsValid)
{
result.Append (".");
result.Append (fSubseconds.Get ());
}
}
if (gDNGUseFakeTimeZonesInXMP)
{
// Kludge: Early versions of the XMP toolkit assume Zulu time
// if the time zone is missing. It is safer for fill in the
// local time zone.
dng_time_zone tempZone = fTimeZone;
if (tempZone.NotValid ())
{
tempZone = LocalTimeZone (fDateTime);
}
result.Append (tempZone.Encode_ISO_8601 ().Get ());
}
else
{
// MWG: Now we don't fill in the local time zone. So only
// add the time zone if it is known and valid.
if (fTimeZone.IsValid ())
{
result.Append (fTimeZone.Encode_ISO_8601 ().Get ());
}
}
}
}
return result;
}
/*****************************************************************************/
void dng_date_time_info::Decode_IPTC_Date (const char *s)
{
if (strlen (s) == 8)
{
unsigned year = 0;
unsigned month = 0;
unsigned day = 0;
if (sscanf (s,
"%4u%2u%2u",
&year,
&month,
&day) == 3)
{
SetDate ((uint32) year,
(uint32) month,
(uint32) day);
}
}
}
/*****************************************************************************/
dng_string dng_date_time_info::Encode_IPTC_Date () const
{
dng_string result;
if (IsValid ())
{
char s [64];
sprintf (s,
"%04u%02u%02u",
(unsigned) fDateTime.fYear,
(unsigned) fDateTime.fMonth,
(unsigned) fDateTime.fDay);
result.Set (s);
}
return result;
}
/*****************************************************************************/
void dng_date_time_info::Decode_IPTC_Time (const char *s)
{
if (strlen (s) == 11)
{
char time [12];
memcpy (time, s, sizeof (time));
if (time [6] == '+' ||
time [6] == '-')
{
int tzsign = (time [6] == '-') ? -1 : 1;
time [6] = 0;
unsigned hour = 0;
unsigned minute = 0;
unsigned second = 0;
unsigned tzhour = 0;
unsigned tzmin = 0;
if (sscanf (time,
"%2u%2u%2u",
&hour,
&minute,
&second) == 3 &&
sscanf (time + 7,
"%2u%2u",
&tzhour,
&tzmin) == 2)
{
dng_time_zone zone;
zone.SetOffsetMinutes (tzsign * (tzhour * 60 + tzmin));
if (zone.IsValid ())
{
SetTime ((uint32) hour,
(uint32) minute,
(uint32) second);
SetZone (zone);
}
}
}
}
else if (strlen (s) == 6)
{
unsigned hour = 0;
unsigned minute = 0;
unsigned second = 0;
if (sscanf (s,
"%2u%2u%2u",
&hour,
&minute,
&second) == 3)
{
SetTime ((uint32) hour,
(uint32) minute,
(uint32) second);
}
}
else if (strlen (s) == 4)
{
unsigned hour = 0;
unsigned minute = 0;
if (sscanf (s,
"%2u%2u",
&hour,
&minute) == 2)
{
SetTime ((uint32) hour,
(uint32) minute,
0);
}
}
}
/*****************************************************************************/
dng_string dng_date_time_info::Encode_IPTC_Time () const
{
dng_string result;
if (IsValid () && !fDateOnly)
{
char s [64];
if (fTimeZone.IsValid ())
{
sprintf (s,
"%02u%02u%02u%c%02u%02u",
(unsigned) fDateTime.fHour,
(unsigned) fDateTime.fMinute,
(unsigned) fDateTime.fSecond,
(int) (fTimeZone.OffsetMinutes () >= 0 ? '+' : '-'),
(unsigned) (Abs_int32 (fTimeZone.OffsetMinutes ()) / 60),
(unsigned) (Abs_int32 (fTimeZone.OffsetMinutes ()) % 60));
}
else
{
sprintf (s,
"%02u%02u%02u",
(unsigned) fDateTime.fHour,
(unsigned) fDateTime.fMinute,
(unsigned) fDateTime.fSecond);
}
result.Set (s);
}
return result;
}
/*****************************************************************************/
static dng_mutex gDateTimeMutex ("gDateTimeMutex");
/*****************************************************************************/
void CurrentDateTimeAndZone (dng_date_time_info &info)
{
time_t sec;
time (&sec);
tm t;
tm zt;
{
dng_lock_mutex lock (&gDateTimeMutex);
t = *localtime (&sec);
zt = *gmtime (&sec);
}
dng_date_time dt;
dt.fYear = t.tm_year + 1900;
dt.fMonth = t.tm_mon + 1;
dt.fDay = t.tm_mday;
dt.fHour = t.tm_hour;
dt.fMinute = t.tm_min;
dt.fSecond = t.tm_sec;
info.SetDateTime (dt);
int tzHour = t.tm_hour - zt.tm_hour;
int tzMin = t.tm_min - zt.tm_min;
bool zonePositive = (t.tm_year > zt.tm_year) ||
(t.tm_year == zt.tm_year && t.tm_yday > zt.tm_yday) ||
(t.tm_year == zt.tm_year && t.tm_yday == zt.tm_yday && tzHour > 0) ||
(t.tm_year == zt.tm_year && t.tm_yday == zt.tm_yday && tzHour == 0 && tzMin >= 0);
tzMin += tzHour * 60;
if (zonePositive)
{
while (tzMin < 0)
tzMin += 24 * 60;
}
else
{
while (tzMin > 0)
tzMin -= 24 * 60;
}
dng_time_zone zone;
zone.SetOffsetMinutes (tzMin);
info.SetZone (zone);
}
/*****************************************************************************/
void DecodeUnixTime (uint32 unixTime, dng_date_time &dt)
{
time_t sec = (time_t) unixTime;
tm t;
{
dng_lock_mutex lock (&gDateTimeMutex);
#if qMacOS && !defined(__MACH__)
// Macintosh CFM stores time in local time zone.
tm *tp = localtime (&sec);
#else
// Macintosh Mach-O and Windows stores time in Zulu time.
tm *tp = gmtime (&sec);
#endif
if (!tp)
{
dt.Clear ();
return;
}
t = *tp;
}
dt.fYear = t.tm_year + 1900;
dt.fMonth = t.tm_mon + 1;
dt.fDay = t.tm_mday;
dt.fHour = t.tm_hour;
dt.fMinute = t.tm_min;
dt.fSecond = t.tm_sec;
}
/*****************************************************************************/
dng_time_zone LocalTimeZone (const dng_date_time &dt)
{
dng_time_zone result;
if (dt.IsValid ())
{
#if qMacOS && qEnableCarbon
CFTimeZoneRef zoneRef = CFTimeZoneCopyDefault ();
if (zoneRef)
{
CFGregorianDate gregDate;
gregDate.year = dt.fYear;
gregDate.month = (SInt8) dt.fMonth;
gregDate.day = (SInt8) dt.fDay;
gregDate.hour = (SInt8) dt.fHour;
gregDate.minute = (SInt8) dt.fMinute;
gregDate.second = (SInt8) dt.fSecond;
CFAbsoluteTime absTime = CFGregorianDateGetAbsoluteTime (gregDate, zoneRef);
CFTimeInterval secondsDelta = CFTimeZoneGetSecondsFromGMT (zoneRef, absTime);
CFRelease (zoneRef);
result.SetOffsetSeconds (Round_int32 (secondsDelta));
if (result.IsValid ())
{
return result;
}
}
#endif
#if qWinOS
if (GetTimeZoneInformation != NULL &&
SystemTimeToTzSpecificLocalTime != NULL &&
SystemTimeToFileTime != NULL)
{
TIME_ZONE_INFORMATION tzInfo;
DWORD x = GetTimeZoneInformation (&tzInfo);
SYSTEMTIME localST;
memset (&localST, 0, sizeof (localST));
localST.wYear = (WORD) dt.fYear;
localST.wMonth = (WORD) dt.fMonth;
localST.wDay = (WORD) dt.fDay;
localST.wHour = (WORD) dt.fHour;
localST.wMinute = (WORD) dt.fMinute;
localST.wSecond = (WORD) dt.fSecond;
SYSTEMTIME utcST;
if (TzSpecificLocalTimeToSystemTime (&tzInfo, &localST, &utcST))
{
FILETIME localFT;
FILETIME utcFT;
(void) SystemTimeToFileTime (&localST, &localFT);
(void) SystemTimeToFileTime (&utcST , &utcFT );
uint64 time1 = (((uint64) localFT.dwHighDateTime) << 32) + localFT.dwLowDateTime;
uint64 time2 = (((uint64) utcFT .dwHighDateTime) << 32) + utcFT .dwLowDateTime;
// FILETIMEs are in units to 100 ns. Convert to seconds.
int64 time1Sec = time1 / 10000000;
int64 time2Sec = time2 / 10000000;
int32 delta = (int32) (time1Sec - time2Sec);
result.SetOffsetSeconds (delta);
if (result.IsValid ())
{
return result;
}
}
}
#endif
}
// Figure out local time zone.
dng_date_time_info current_info;
CurrentDateTimeAndZone (current_info);
result = current_info.TimeZone ();
return result;
}
/*****************************************************************************/
dng_date_time_storage_info::dng_date_time_storage_info ()
: fOffset (kDNGStreamInvalidOffset )
, fFormat (dng_date_time_format_unknown)
{
}
/*****************************************************************************/
dng_date_time_storage_info::dng_date_time_storage_info (uint64 offset,
dng_date_time_format format)
: fOffset (offset)
, fFormat (format)
{
}
/*****************************************************************************/
bool dng_date_time_storage_info::IsValid () const
{
return fOffset != kDNGStreamInvalidOffset;
}
/*****************************************************************************/
uint64 dng_date_time_storage_info::Offset () const
{
if (!IsValid ())
ThrowProgramError ();
return fOffset;
}
/*****************************************************************************/
dng_date_time_format dng_date_time_storage_info::Format () const
{
if (!IsValid ())
ThrowProgramError ();
return fFormat;
}
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,385 @@
/*****************************************************************************/
// Copyright 2006-2008 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_date_time.h#1 $ */
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */
/** \file
* Functions and classes for working with dates and times in DNG files.
*/
/*****************************************************************************/
#ifndef __dng_date_time__
#define __dng_date_time__
/*****************************************************************************/
#include "dng_classes.h"
#include "dng_string.h"
#include "dng_types.h"
/*****************************************************************************/
/// \brief Class for holding a date/time and converting to and from relevant
/// date/time formats
class dng_date_time
{
public:
uint32 fYear;
uint32 fMonth;
uint32 fDay;
uint32 fHour;
uint32 fMinute;
uint32 fSecond;
public:
/// Construct an invalid date/time
dng_date_time ();
/// Construct a date/time with specific values.
/// \param year Year to use as actual integer value, such as 2006.
/// \param month Month to use from 1 - 12, where 1 is January.
/// \param day Day of month to use from 1 -31, where 1 is the first.
/// \param hour Hour of day to use from 0 - 23, where 0 is midnight.
/// \param minute Minute of hour to use from 0 - 59.
/// \param second Second of minute to use from 0 - 59.
dng_date_time (uint32 year,
uint32 month,
uint32 day,
uint32 hour,
uint32 minute,
uint32 second);
/// Predicate to determine if a date is valid.
/// \retval true if all fields are within range.
bool IsValid () const;
/// Predicate to determine if a date is invalid.
/// \retval true if any field is out of range.
bool NotValid () const
{
return !IsValid ();
}
/// Equal operator.
bool operator== (const dng_date_time &dt) const
{
return fYear == dt.fYear &&
fMonth == dt.fMonth &&
fDay == dt.fDay &&
fHour == dt.fHour &&
fMinute == dt.fMinute &&
fSecond == dt.fSecond;
}
// Not-equal operator.
bool operator!= (const dng_date_time &dt) const
{
return !(*this == dt);
}
/// Set date to an invalid value.
void Clear ();
/// Parse an EXIF format date string.
/// \param s Input date string to parse.
/// \retval true if date was parsed successfully and date is valid.
bool Parse (const char *s);
};
/*****************************************************************************/
/// \brief Class for holding a time zone.
class dng_time_zone
{
private:
enum
{
kMaxOffsetHours = 15,
kMinOffsetHours = -kMaxOffsetHours,
kMaxOffsetMinutes = kMaxOffsetHours * 60,
kMinOffsetMinutes = kMinOffsetHours * 60,
kInvalidOffset = kMinOffsetMinutes - 1
};
// Offset from GMT in minutes. Positive numbers are
// ahead of GMT, negative number are behind GMT.
int32 fOffsetMinutes;
public:
dng_time_zone ()
: fOffsetMinutes (kInvalidOffset)
{
}
void Clear ()
{
fOffsetMinutes = kInvalidOffset;
}
void SetOffsetHours (int32 offset)
{
fOffsetMinutes = offset * 60;
}
void SetOffsetMinutes (int32 offset)
{
fOffsetMinutes = offset;
}
void SetOffsetSeconds (int32 offset)
{
fOffsetMinutes = (offset > 0) ? ((offset + 30) / 60)
: ((offset - 30) / 60);
}
bool IsValid () const
{
return fOffsetMinutes >= kMinOffsetMinutes &&
fOffsetMinutes <= kMaxOffsetMinutes;
}
bool NotValid () const
{
return !IsValid ();
}
int32 OffsetMinutes () const
{
return fOffsetMinutes;
}
bool IsExactHourOffset () const
{
return IsValid () && ((fOffsetMinutes % 60) == 0);
}
int32 ExactHourOffset () const
{
return fOffsetMinutes / 60;
}
dng_string Encode_ISO_8601 () const;
};
/*****************************************************************************/
/// \brief Class for holding complete data/time/zone information.
class dng_date_time_info
{
private:
// Is only the date valid and not the time?
bool fDateOnly;
// Date and time.
dng_date_time fDateTime;
// Subseconds string (stored in a separate tag in EXIF).
dng_string fSubseconds;
// Time zone, if known.
dng_time_zone fTimeZone;
public:
dng_date_time_info ();
bool IsValid () const;
bool NotValid () const
{
return !IsValid ();
}
void Clear ()
{
*this = dng_date_time_info ();
}
const dng_date_time & DateTime () const
{
return fDateTime;
}
void SetDateTime (const dng_date_time &dt)
{
fDateOnly = false;
fDateTime = dt;
}
const dng_string & Subseconds () const
{
return fSubseconds;
}
void SetSubseconds (const dng_string &s)
{
fSubseconds = s;
}
const dng_time_zone & TimeZone () const
{
return fTimeZone;
}
void SetZone (const dng_time_zone &zone)
{
fTimeZone = zone;
}
void Decode_ISO_8601 (const char *s);
dng_string Encode_ISO_8601 () const;
void Decode_IPTC_Date (const char *s);
dng_string Encode_IPTC_Date () const;
void Decode_IPTC_Time (const char *s);
dng_string Encode_IPTC_Time () const;
private:
void SetDate (uint32 year,
uint32 month,
uint32 day);
void SetTime (uint32 hour,
uint32 minute,
uint32 second);
};
/*****************************************************************************/
/// Get the current date/time and timezone.
/// \param info Receives current data/time/zone.
void CurrentDateTimeAndZone (dng_date_time_info &info);
/*****************************************************************************/
/// Convert UNIX "seconds since Jan 1, 1970" time to a dng_date_time
void DecodeUnixTime (uint32 unixTime, dng_date_time &dt);
/*****************************************************************************/
/// Return timezone of current location at a given date.
/// \param dt Date at which to compute timezone difference. (For example, used
/// to determine Daylight Savings, etc.)
/// \retval Time zone for date/time dt.
dng_time_zone LocalTimeZone (const dng_date_time &dt);
/*****************************************************************************/
/// Tag to encode date represenation format
enum dng_date_time_format
{
dng_date_time_format_unknown = 0, /// Date format not known
dng_date_time_format_exif = 1, /// EXIF date string
dng_date_time_format_unix_little_endian = 2, /// 32-bit UNIX time as 4-byte little endian
dng_date_time_format_unix_big_endian = 3 /// 32-bit UNIX time as 4-byte big endian
};
/*****************************************************************************/
/// \brief Store file offset from which date was read.
///
/// Used internally by Adobe to update date in original file.
/// \warning Use at your own risk.
class dng_date_time_storage_info
{
private:
uint64 fOffset;
dng_date_time_format fFormat;
public:
/// The default constructor initializes to an invalid state.
dng_date_time_storage_info ();
/// Construct with file offset and date format.
dng_date_time_storage_info (uint64 offset,
dng_date_time_format format);
/// Predicate to determine if an offset is valid.
/// \retval true if offset is valid.
bool IsValid () const;
// The accessors throw if the data is not valid.
/// Getter for offset in file.
/// \exception dng_exception with fErrorCode equal to dng_error_unknown
/// if offset is not valid.
uint64 Offset () const;
/// Get for format date was originally stored in file. Throws a
/// dng_error_unknown exception if offset is invalid.
/// \exception dng_exception with fErrorCode equal to dng_error_unknown
/// if offset is not valid.
dng_date_time_format Format () const;
};
/*****************************************************************************/
// Kludge: Global boolean to turn on fake time zones in XMP for old software.
extern bool gDNGUseFakeTimeZonesInXMP;
/*****************************************************************************/
#endif
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,58 @@
/*****************************************************************************/
// Copyright 2006-2009 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_errors.h#2 $ */
/* $DateTime: 2012/07/11 10:36:56 $ */
/* $Change: 838485 $ */
/* $Author: tknoll $ */
/** \file
* Error code values.
*/
/*****************************************************************************/
#ifndef __dng_errors__
#define __dng_errors__
/*****************************************************************************/
#include "dng_types.h"
/*****************************************************************************/
/// Type for all errors used in DNG SDK. Generally held inside a dng_exception.
typedef int32 dng_error_code;
enum
{
dng_error_none = 0, //!< No error. Success.
dng_error_unknown = 100000, //!< Logic or program error or other unclassifiable error.
dng_error_not_yet_implemented, //!< Functionality requested is not yet implemented.
dng_error_silent, //!< An error which should not be signalled to user.
dng_error_user_canceled, //!< Processing stopped by user (or host application) request
dng_error_host_insufficient, //!< Necessary host functionality is not present.
dng_error_memory, //!< Out of memory.
dng_error_bad_format, //!< File format is not valid.
dng_error_matrix_math, //!< Matrix has wrong shape, is badly conditioned, or similar problem.
dng_error_open_file, //!< Could not open file.
dng_error_read_file, //!< Error reading file.
dng_error_write_file, //!< Error writing file.
dng_error_end_of_file, //!< Unexpected end of file.
dng_error_file_is_damaged, //!< File is damaged in some way.
dng_error_image_too_big_dng, //!< Image is too big to save as DNG.
dng_error_image_too_big_tiff, //!< Image is too big to save as TIFF.
dng_error_unsupported_dng //!< DNG version is unsupported.
};
/*****************************************************************************/
#endif
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,205 @@
/*****************************************************************************/
// Copyright 2006-2007 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_exceptions.cpp#2 $ */
/* $DateTime: 2012/06/06 12:08:58 $ */
/* $Change: 833617 $ */
/* $Author: tknoll $ */
/*****************************************************************************/
#include "dng_exceptions.h"
#include "dng_flags.h"
#include "dng_globals.h"
/*****************************************************************************/
#ifndef qDNGReportErrors
// assuming this isn't enable on Win, because it's using printf, but an app can redirect that to console
#define qDNGReportErrors ((qDNGDebug && qMacOS) || qDNGValidate)
#endif
/*****************************************************************************/
void ReportWarning (const char *message,
const char *sub_message)
{
#if qDNGReportErrors
if (sub_message)
fprintf (stderr, "*** Warning: %s (%s) ***\n", message, sub_message);
else
fprintf (stderr, "*** Warning: %s ***\n", message);
#else
(void) message;
(void) sub_message;
#endif
}
/*****************************************************************************/
void ReportError (const char *message,
const char *sub_message)
{
#if qDNGReportErrors
if (sub_message)
fprintf (stderr, "*** Error: %s (%s) ***\n", message, sub_message);
else
fprintf (stderr, "*** Error: %s ***\n", message);
#else
(void) message;
(void) sub_message;
#endif
}
/*****************************************************************************/
void Throw_dng_error (dng_error_code err,
const char *message,
const char *sub_message,
bool silent)
{
#if qDNGReportErrors
{
if (!message)
{
switch (err)
{
case dng_error_none:
case dng_error_silent:
case dng_error_user_canceled:
{
break;
}
case dng_error_not_yet_implemented:
{
message = "Not yet implemented";
break;
}
case dng_error_host_insufficient:
{
message = "Host insufficient";
break;
}
case dng_error_memory:
{
message = "Unable to allocate memory";
break;
}
case dng_error_bad_format:
{
message = "File format is invalid";
break;
}
case dng_error_matrix_math:
{
message = "Matrix math error";
break;
}
case dng_error_open_file:
{
message = "Unable to open file";
break;
}
case dng_error_read_file:
{
message = "File read error";
break;
}
case dng_error_write_file:
{
message = "File write error";
break;
}
case dng_error_end_of_file:
{
message = "Unexpected end-of-file";
break;
}
case dng_error_file_is_damaged:
{
message = "File is damaged";
break;
}
case dng_error_image_too_big_dng:
{
message = "Image is too big to save as DNG";
break;
}
case dng_error_image_too_big_tiff:
{
message = "Image is too big to save as TIFF";
break;
}
case dng_error_unsupported_dng:
{
message = "DNG version is unsupported";
break;
}
default:
{
message = "Unknown error";
break;
}
}
}
if (message && !silent)
{
ReportError (message, sub_message);
}
}
#else
(void) message;
(void) sub_message;
(void) silent;
#endif
throw dng_exception (err);
}
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,301 @@
/*****************************************************************************/
// Copyright 2006-2007 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_exceptions.h#1 $ */
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */
/** \file
* C++ exception support for DNG SDK.
*/
/*****************************************************************************/
#ifndef __dng_exceptions__
#define __dng_exceptions__
/*****************************************************************************/
#include "dng_errors.h"
#include "dng_flags.h"
/*****************************************************************************/
/// Display a warning message. Note that this may just eat the message.
void ReportWarning (const char *message,
const char *sub_message = NULL);
/*****************************************************************************/
/// Display an error message. Note that this may just eat the message.
void ReportError (const char *message,
const char *sub_message = NULL);
/*****************************************************************************/
/// \brief All exceptions thrown by the DNG SDK use this exception class.
class dng_exception
{
private:
dng_error_code fErrorCode;
public:
/// Construct an exception representing the given error code.
/// \param code Error code this exception is for.
dng_exception (dng_error_code code)
: fErrorCode (code)
{
}
virtual ~dng_exception ()
{
}
/// Getter for error code of this exception
/// \retval The error code of this exception.
dng_error_code ErrorCode () const
{
return fErrorCode;
}
};
/******************************************************************************/
/// \brief Throw an exception based on an arbitrary error code.
void Throw_dng_error (dng_error_code err,
const char * message = NULL,
const char * sub_message = NULL,
bool silent = false);
/******************************************************************************/
/// \brief Convenience function to throw dng_exception with error code if
/// error_code is not dng_error_none .
inline void Fail_dng_error (dng_error_code err)
{
if (err != dng_error_none)
{
Throw_dng_error (err);
}
}
/*****************************************************************************/
/// \brief Convenience function to throw dng_exception with error code
/// dng_error_unknown .
inline void ThrowProgramError (const char * sub_message = NULL)
{
Throw_dng_error (dng_error_unknown, NULL, sub_message);
}
/*****************************************************************************/
/// \brief Convenience function to throw dng_exception with error code
/// dng_error_not_yet_implemented .
inline void ThrowNotYetImplemented (const char * sub_message = NULL)
{
Throw_dng_error (dng_error_not_yet_implemented, NULL, sub_message);
}
/*****************************************************************************/
/// \brief Convenience function to throw dng_exception with error code
/// dng_error_silent .
inline void ThrowSilentError ()
{
Throw_dng_error (dng_error_silent);
}
/*****************************************************************************/
/// \brief Convenience function to throw dng_exception with error code
/// dng_error_user_canceled .
inline void ThrowUserCanceled ()
{
Throw_dng_error (dng_error_user_canceled);
}
/*****************************************************************************/
/// \brief Convenience function to throw dng_exception with error code
/// dng_error_host_insufficient .
inline void ThrowHostInsufficient (const char * sub_message = NULL)
{
Throw_dng_error (dng_error_host_insufficient, NULL, sub_message);
}
/*****************************************************************************/
/// \brief Convenience function to throw dng_exception with error code
/// dng_error_memory .
inline void ThrowMemoryFull (const char * sub_message = NULL)
{
Throw_dng_error (dng_error_memory, NULL, sub_message);
}
/*****************************************************************************/
/// \brief Convenience function to throw dng_exception with error code
/// dng_error_bad_format .
inline void ThrowBadFormat (const char * sub_message = NULL)
{
Throw_dng_error (dng_error_bad_format, NULL, sub_message);
}
/*****************************************************************************/
/// \brief Convenience function to throw dng_exception with error code
/// dng_error_matrix_math .
inline void ThrowMatrixMath (const char * sub_message = NULL)
{
Throw_dng_error (dng_error_matrix_math, NULL, sub_message);
}
/*****************************************************************************/
/// \brief Convenience function to throw dng_exception with error code
/// dng_error_open_file .
inline void ThrowOpenFile (const char * sub_message = NULL, bool silent = false)
{
Throw_dng_error (dng_error_open_file, NULL, sub_message, silent);
}
/*****************************************************************************/
/// \brief Convenience function to throw dng_exception with error code
/// dng_error_read_file .
inline void ThrowReadFile (const char *sub_message = NULL)
{
Throw_dng_error (dng_error_read_file, NULL, sub_message);
}
/*****************************************************************************/
/// \brief Convenience function to throw dng_exception with error code
/// dng_error_write_file .
inline void ThrowWriteFile (const char *sub_message = NULL)
{
Throw_dng_error (dng_error_write_file, NULL, sub_message);
}
/*****************************************************************************/
/// \brief Convenience function to throw dng_exception with error code
/// dng_error_end_of_file .
inline void ThrowEndOfFile (const char *sub_message = NULL)
{
Throw_dng_error (dng_error_end_of_file, NULL, sub_message);
}
/*****************************************************************************/
/// \brief Convenience function to throw dng_exception with error code
/// dng_error_file_is_damaged .
inline void ThrowFileIsDamaged ()
{
Throw_dng_error (dng_error_file_is_damaged);
}
/*****************************************************************************/
/// \brief Convenience function to throw dng_exception with error code
/// dng_error_image_too_big_dng .
inline void ThrowImageTooBigDNG ()
{
Throw_dng_error (dng_error_image_too_big_dng);
}
/*****************************************************************************/
/// \brief Convenience function to throw dng_exception with error code
/// dng_error_image_too_big_tiff .
inline void ThrowImageTooBigTIFF ()
{
Throw_dng_error (dng_error_image_too_big_tiff);
}
/*****************************************************************************/
/// \brief Convenience function to throw dng_exception with error code
/// dng_error_unsupported_dng .
inline void ThrowUnsupportedDNG ()
{
Throw_dng_error (dng_error_unsupported_dng);
}
/*****************************************************************************/
#endif
/*****************************************************************************/

Plik diff jest za duży Load Diff

Wyświetl plik

@ -0,0 +1,351 @@
/*****************************************************************************/
// Copyright 2006-2008 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_exif.h#2 $ */
/* $DateTime: 2012/07/11 10:36:56 $ */
/* $Change: 838485 $ */
/* $Author: tknoll $ */
/** \file
* EXIF read access support. See the \ref spec_exif "EXIF specification" for full
* description of tags.
*/
/*****************************************************************************/
#ifndef __dng_exif__
#define __dng_exif__
/*****************************************************************************/
#include "dng_classes.h"
#include "dng_date_time.h"
#include "dng_fingerprint.h"
#include "dng_types.h"
#include "dng_matrix.h"
#include "dng_rational.h"
#include "dng_string.h"
#include "dng_stream.h"
#include "dng_sdk_limits.h"
/*****************************************************************************/
/// \brief Container class for parsing and holding EXIF tags.
///
/// Public member fields are documented in \ref spec_exif "EXIF specification."
class dng_exif
{
public:
dng_string fImageDescription;
dng_string fMake;
dng_string fModel;
dng_string fSoftware;
dng_string fArtist;
dng_string fCopyright;
dng_string fCopyright2;
dng_string fUserComment;
dng_date_time_info fDateTime;
dng_date_time_storage_info fDateTimeStorageInfo;
dng_date_time_info fDateTimeOriginal;
dng_date_time_storage_info fDateTimeOriginalStorageInfo;
dng_date_time_info fDateTimeDigitized;
dng_date_time_storage_info fDateTimeDigitizedStorageInfo;
uint32 fTIFF_EP_StandardID;
uint32 fExifVersion;
uint32 fFlashPixVersion;
dng_urational fExposureTime;
dng_urational fFNumber;
dng_srational fShutterSpeedValue;
dng_urational fApertureValue;
dng_srational fBrightnessValue;
dng_srational fExposureBiasValue;
dng_urational fMaxApertureValue;
dng_urational fFocalLength;
dng_urational fDigitalZoomRatio;
dng_urational fExposureIndex;
dng_urational fSubjectDistance;
dng_urational fGamma;
dng_urational fBatteryLevelR;
dng_string fBatteryLevelA;
uint32 fExposureProgram;
uint32 fMeteringMode;
uint32 fLightSource;
uint32 fFlash;
uint32 fFlashMask;
uint32 fSensingMethod;
uint32 fColorSpace;
uint32 fFileSource;
uint32 fSceneType;
uint32 fCustomRendered;
uint32 fExposureMode;
uint32 fWhiteBalance;
uint32 fSceneCaptureType;
uint32 fGainControl;
uint32 fContrast;
uint32 fSaturation;
uint32 fSharpness;
uint32 fSubjectDistanceRange;
uint32 fSelfTimerMode;
uint32 fImageNumber;
uint32 fFocalLengthIn35mmFilm;
uint32 fISOSpeedRatings [3]; // EXIF 2.3: PhotographicSensitivity.
// Sensitivity tags added in EXIF 2.3.
uint32 fSensitivityType;
uint32 fStandardOutputSensitivity;
uint32 fRecommendedExposureIndex;
uint32 fISOSpeed;
uint32 fISOSpeedLatitudeyyy;
uint32 fISOSpeedLatitudezzz;
uint32 fSubjectAreaCount;
uint32 fSubjectArea [4];
uint32 fComponentsConfiguration;
dng_urational fCompresssedBitsPerPixel;
uint32 fPixelXDimension;
uint32 fPixelYDimension;
dng_urational fFocalPlaneXResolution;
dng_urational fFocalPlaneYResolution;
uint32 fFocalPlaneResolutionUnit;
uint32 fCFARepeatPatternRows;
uint32 fCFARepeatPatternCols;
uint8 fCFAPattern [kMaxCFAPattern] [kMaxCFAPattern];
dng_fingerprint fImageUniqueID;
uint32 fGPSVersionID;
dng_string fGPSLatitudeRef;
dng_urational fGPSLatitude [3];
dng_string fGPSLongitudeRef;
dng_urational fGPSLongitude [3];
uint32 fGPSAltitudeRef;
dng_urational fGPSAltitude;
dng_urational fGPSTimeStamp [3];
dng_string fGPSSatellites;
dng_string fGPSStatus;
dng_string fGPSMeasureMode;
dng_urational fGPSDOP;
dng_string fGPSSpeedRef;
dng_urational fGPSSpeed;
dng_string fGPSTrackRef;
dng_urational fGPSTrack;
dng_string fGPSImgDirectionRef;
dng_urational fGPSImgDirection;
dng_string fGPSMapDatum;
dng_string fGPSDestLatitudeRef;
dng_urational fGPSDestLatitude [3];
dng_string fGPSDestLongitudeRef;
dng_urational fGPSDestLongitude [3];
dng_string fGPSDestBearingRef;
dng_urational fGPSDestBearing;
dng_string fGPSDestDistanceRef;
dng_urational fGPSDestDistance;
dng_string fGPSProcessingMethod;
dng_string fGPSAreaInformation;
dng_string fGPSDateStamp;
uint32 fGPSDifferential;
dng_urational fGPSHPositioningError;
dng_string fInteroperabilityIndex;
uint32 fInteroperabilityVersion;
dng_string fRelatedImageFileFormat;
uint32 fRelatedImageWidth;
uint32 fRelatedImageLength;
dng_string fCameraSerialNumber; // EXIF 2.3: BodySerialNumber.
dng_urational fLensInfo [4]; // EXIF 2.3: LensSpecification.
dng_string fLensID;
dng_string fLensMake;
dng_string fLensName; // EXIF 2.3: LensModel.
dng_string fLensSerialNumber;
// Was the lens name field read from a LensModel tag?
bool fLensNameWasReadFromExif;
// Private field to hold the approximate focus distance of the lens, in
// meters. This value is often coarsely measured/reported and hence should be
// interpreted only as a rough estimate of the true distance from the plane
// of focus (in object space) to the focal plane. It is still useful for the
// purposes of applying lens corrections.
dng_urational fApproxFocusDistance;
dng_srational fFlashCompensation;
dng_string fOwnerName; // EXIF 2.3: CameraOwnerName.
dng_string fFirmware;
public:
dng_exif ();
virtual ~dng_exif ();
/// Make clone.
virtual dng_exif * Clone () const;
/// Clear all EXIF fields.
void SetEmpty ();
/// Copy all GPS-related fields.
/// \param exif Source object from which to copy GPS fields.
void CopyGPSFrom (const dng_exif &exif);
/// Utility to fix up common errors and rounding issues with EXIF exposure
/// times.
static real64 SnapExposureTime (real64 et);
/// Set exposure time and shutter speed fields. Optionally fix up common
/// errors and rounding issues with EXIF exposure times.
/// \param et Exposure time in seconds.
/// \param snap Set to true to fix up common errors and rounding issues with
/// EXIF exposure times.
void SetExposureTime (real64 et,
bool snap = true);
/// Set shutter speed value (APEX units) and exposure time.
/// \param Shutter speed in APEX units.
void SetShutterSpeedValue (real64 ss);
/// Utility to encode f-number as a rational.
/// \param fs The f-number to encode.
static dng_urational EncodeFNumber (real64 fs);
/// Set the FNumber and ApertureValue fields.
/// \param fs The f-number to set.
void SetFNumber (real64 fs);
/// Set the FNumber and ApertureValue fields.
/// \param av The aperture value (APEX units).
void SetApertureValue (real64 av);
/// Utility to convert aperture value (APEX units) to f-number.
/// \param av The aperture value (APEX units) to convert.
static real64 ApertureValueToFNumber (real64 av);
/// Utility to convert aperture value (APEX units) to f-number.
/// \param av The aperture value (APEX units) to convert.
static real64 ApertureValueToFNumber (const dng_urational &av);
/// Utility to convert f-number to aperture value (APEX units).
/// \param fNumber The f-number to convert.
static real64 FNumberToApertureValue (real64 fNumber);
/// Utility to convert f-number to aperture value (APEX units).
/// \param fNumber The f-number to convert.
static real64 FNumberToApertureValue (const dng_urational &fNumber);
/// Set the DateTime field.
/// \param dt The DateTime value.
void UpdateDateTime (const dng_date_time_info &dt);
/// Returns true iff the EXIF version is at least 2.3.
bool AtLeastVersion0230 () const;
virtual bool ParseTag (dng_stream &stream,
dng_shared &shared,
uint32 parentCode,
bool isMainIFD,
uint32 tagCode,
uint32 tagType,
uint32 tagCount,
uint64 tagOffset);
virtual void PostParse (dng_host &host,
dng_shared &shared);
protected:
virtual bool Parse_ifd0 (dng_stream &stream,
dng_shared &shared,
uint32 parentCode,
uint32 tagCode,
uint32 tagType,
uint32 tagCount,
uint64 tagOffset);
virtual bool Parse_ifd0_main (dng_stream &stream,
dng_shared &shared,
uint32 parentCode,
uint32 tagCode,
uint32 tagType,
uint32 tagCount,
uint64 tagOffset);
virtual bool Parse_ifd0_exif (dng_stream &stream,
dng_shared &shared,
uint32 parentCode,
uint32 tagCode,
uint32 tagType,
uint32 tagCount,
uint64 tagOffset);
virtual bool Parse_gps (dng_stream &stream,
dng_shared &shared,
uint32 parentCode,
uint32 tagCode,
uint32 tagType,
uint32 tagCount,
uint64 tagOffset);
virtual bool Parse_interoperability (dng_stream &stream,
dng_shared &shared,
uint32 parentCode,
uint32 tagCode,
uint32 tagType,
uint32 tagCount,
uint64 tagOffset);
};
/*****************************************************************************/
#endif
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,31 @@
/*****************************************************************************/
// Copyright 2006-2007 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_fast_module.h#1 $ */
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */
/** \file
* Include file to set optimization to highest level for performance-critical routines.
* Normal files should have otpimization set to normal level to save code size as there is less
* cache pollution this way.
*/
/*****************************************************************************/
// Include this file in modules that contain routines that should be as fast
// as possible, even at the expense of slight code size increases.
/*****************************************************************************/
#ifdef _MSC_VER
#pragma optimize ("t", on)
#endif
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,135 @@
/*****************************************************************************/
// Copyright 2006-2007 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_file_stream.cpp#2 $ */
/* $DateTime: 2012/06/01 07:28:57 $ */
/* $Change: 832715 $ */
/* $Author: tknoll $ */
/*****************************************************************************/
#include "dng_file_stream.h"
#include "dng_exceptions.h"
/*****************************************************************************/
dng_file_stream::dng_file_stream (const char *filename,
bool output,
uint32 bufferSize)
: dng_stream ((dng_abort_sniffer *) NULL,
bufferSize,
0)
, fFile (NULL)
{
fFile = fopen (filename, output ? "wb" : "rb");
if (!fFile)
{
#if qDNGValidate
ReportError ("Unable to open file",
filename);
ThrowSilentError ();
#else
ThrowOpenFile ();
#endif
}
}
/*****************************************************************************/
dng_file_stream::~dng_file_stream ()
{
if (fFile)
{
fclose (fFile);
fFile = NULL;
}
}
/*****************************************************************************/
uint64 dng_file_stream::DoGetLength ()
{
if (fseek (fFile, 0, SEEK_END) != 0)
{
ThrowReadFile ();
}
return (uint64) ftell (fFile);
}
/*****************************************************************************/
void dng_file_stream::DoRead (void *data,
uint32 count,
uint64 offset)
{
if (fseek (fFile, (long) offset, SEEK_SET) != 0)
{
ThrowReadFile ();
}
uint32 bytesRead = (uint32) fread (data, 1, count, fFile);
if (bytesRead != count)
{
ThrowReadFile ();
}
}
/*****************************************************************************/
void dng_file_stream::DoWrite (const void *data,
uint32 count,
uint64 offset)
{
if (fseek (fFile, (uint32) offset, SEEK_SET) != 0)
{
ThrowWriteFile ();
}
uint32 bytesWritten = (uint32) fwrite (data, 1, count, fFile);
if (bytesWritten != count)
{
ThrowWriteFile ();
}
}
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,78 @@
/*****************************************************************************/
// Copyright 2006-2007 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_file_stream.h#1 $ */
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */
/** \file
* Simple, portable, file read/write support.
*/
/*****************************************************************************/
#ifndef __dng_file_stream__
#define __dng_file_stream__
/*****************************************************************************/
#include <stdio.h>
#include "dng_stream.h"
/*****************************************************************************/
/// \brief A stream to/from a disk file. See dng_stream for read/write interface
class dng_file_stream: public dng_stream
{
private:
FILE *fFile;
public:
/// Open a stream on a file.
/// \param filename Pathname in platform synax.
/// \param output Set to true if writing, false otherwise.
/// \param bufferSize size of internal buffer to use. Defaults to 4k.
dng_file_stream (const char *filename,
bool output = false,
uint32 bufferSize = kDefaultBufferSize);
virtual ~dng_file_stream ();
protected:
virtual uint64 DoGetLength ();
virtual void DoRead (void *data,
uint32 count,
uint64 offset);
virtual void DoWrite (const void *data,
uint32 count,
uint64 offset);
private:
// Hidden copy constructor and assignment operator.
dng_file_stream (const dng_file_stream &stream);
dng_file_stream & operator= (const dng_file_stream &stream);
};
/*****************************************************************************/
#endif
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,167 @@
/*****************************************************************************/
// Copyright 2006 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_filter_task.cpp#1 $ */
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */
/*****************************************************************************/
#include "dng_filter_task.h"
#include "dng_bottlenecks.h"
#include "dng_exceptions.h"
#include "dng_image.h"
#include "dng_memory.h"
#include "dng_tag_types.h"
#include "dng_utils.h"
/*****************************************************************************/
dng_filter_task::dng_filter_task (const dng_image &srcImage,
dng_image &dstImage)
: fSrcImage (srcImage)
, fDstImage (dstImage)
, fSrcPlane (0 )
, fSrcPlanes (srcImage.Planes ())
, fSrcPixelType (srcImage.PixelType ())
, fDstPlane (0 )
, fDstPlanes (dstImage.Planes ())
, fDstPixelType (dstImage.PixelType ())
, fSrcRepeat (1, 1)
{
}
/*****************************************************************************/
dng_filter_task::~dng_filter_task ()
{
}
/*****************************************************************************/
void dng_filter_task::Start (uint32 threadCount,
const dng_point &tileSize,
dng_memory_allocator *allocator,
dng_abort_sniffer * /* sniffer */)
{
dng_point srcTileSize = SrcTileSize (tileSize);
uint32 srcPixelSize = TagTypeSize (fSrcPixelType);
uint32 srcBufferSize = srcTileSize.v *
RoundUpForPixelSize (srcTileSize.h, srcPixelSize) *
srcPixelSize *
fSrcPlanes;
uint32 dstPixelSize = TagTypeSize (fDstPixelType);
uint32 dstBufferSize = tileSize.v *
RoundUpForPixelSize (tileSize.h, dstPixelSize) *
dstPixelSize *
fDstPlanes;
for (uint32 threadIndex = 0; threadIndex < threadCount; threadIndex++)
{
fSrcBuffer [threadIndex] . Reset (allocator->Allocate (srcBufferSize));
fDstBuffer [threadIndex] . Reset (allocator->Allocate (dstBufferSize));
// Zero buffers so any pad bytes have defined values.
DoZeroBytes (fSrcBuffer [threadIndex]->Buffer (),
fSrcBuffer [threadIndex]->LogicalSize ());
DoZeroBytes (fDstBuffer [threadIndex]->Buffer (),
fDstBuffer [threadIndex]->LogicalSize ());
}
}
/*****************************************************************************/
void dng_filter_task::Process (uint32 threadIndex,
const dng_rect &area,
dng_abort_sniffer * /* sniffer */)
{
// Find source area for this destination area.
dng_rect srcArea = SrcArea (area);
// Setup srcBuffer.
dng_pixel_buffer srcBuffer;
srcBuffer.fArea = srcArea;
srcBuffer.fPlane = fSrcPlane;
srcBuffer.fPlanes = fSrcPlanes;
srcBuffer.fPixelType = fSrcPixelType;
srcBuffer.fPixelSize = TagTypeSize (fSrcPixelType);
srcBuffer.fPlaneStep = RoundUpForPixelSize (srcArea.W (),
srcBuffer.fPixelSize);
srcBuffer.fRowStep = srcBuffer.fPlaneStep *
srcBuffer.fPlanes;
srcBuffer.fData = fSrcBuffer [threadIndex]->Buffer ();
// Setup dstBuffer.
dng_pixel_buffer dstBuffer;
dstBuffer.fArea = area;
dstBuffer.fPlane = fDstPlane;
dstBuffer.fPlanes = fDstPlanes;
dstBuffer.fPixelType = fDstPixelType;
dstBuffer.fPixelSize = TagTypeSize (fDstPixelType);
dstBuffer.fPlaneStep = RoundUpForPixelSize (area.W (),
dstBuffer.fPixelSize);
dstBuffer.fRowStep = dstBuffer.fPlaneStep *
dstBuffer.fPlanes;
dstBuffer.fData = fDstBuffer [threadIndex]->Buffer ();
// Get source pixels.
fSrcImage.Get (srcBuffer,
dng_image::edge_repeat,
fSrcRepeat.v,
fSrcRepeat.h);
// Process area.
ProcessArea (threadIndex,
srcBuffer,
dstBuffer);
// Save result pixels.
fDstImage.Put (dstBuffer);
}
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,157 @@
/*****************************************************************************/
// Copyright 2006 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_filter_task.h#2 $ */
/* $DateTime: 2012/07/11 10:36:56 $ */
/* $Change: 838485 $ */
/* $Author: tknoll $ */
/** \file
* Specialization of dng_area_task for processing an area from one dng_image to an
* area of another.
*/
/*****************************************************************************/
#ifndef __dng_filter_task__
#define __dng_filter_task__
/*****************************************************************************/
#include "dng_area_task.h"
#include "dng_auto_ptr.h"
#include "dng_point.h"
#include "dng_rect.h"
#include "dng_sdk_limits.h"
/*****************************************************************************/
/// \brief Represents a task which filters an area of a source dng_image to an area
/// of a destination dng_image.
class dng_filter_task: public dng_area_task
{
protected:
const dng_image &fSrcImage;
dng_image &fDstImage;
uint32 fSrcPlane;
uint32 fSrcPlanes;
uint32 fSrcPixelType;
uint32 fDstPlane;
uint32 fDstPlanes;
uint32 fDstPixelType;
dng_point fSrcRepeat;
AutoPtr<dng_memory_block> fSrcBuffer [kMaxMPThreads];
AutoPtr<dng_memory_block> fDstBuffer [kMaxMPThreads];
public:
/// Construct a filter task given a source and destination images.
/// \param srcImage Image from which source pixels are read.
/// \param dstImage Image to which result pixels are written.
dng_filter_task (const dng_image &srcImage,
dng_image &dstImage);
virtual ~dng_filter_task ();
/// Compute the source area needed for a given destination area. Default
/// implementation assumes destination area is equal to source area for all
/// cases.
///
/// \param dstArea Area to for which pixels will be computed.
///
/// \retval The source area needed as input to calculate the requested
/// destination area.
virtual dng_rect SrcArea (const dng_rect &dstArea)
{
return dstArea;
}
/// Given a destination tile size, calculate input tile size. Simlar to
/// SrcArea, and should seldom be overridden.
///
/// \param dstTileSize The destination tile size that is targeted for output.
///
/// \retval The source tile size needed to compute a tile of the destination
/// size.
virtual dng_point SrcTileSize (const dng_point &dstTileSize)
{
return SrcArea (dng_rect (dstTileSize)).Size ();
}
/// Implements filtering operation from one buffer to another. Source and
/// destination pixels are set up in member fields of this class. Ideally, no
/// allocation should be done in this routine.
///
/// \param threadIndex The thread on which this routine is being called,
/// between 0 and threadCount - 1 for the threadCount passed to Start method.
///
/// \param srcBuffer Input area and source pixels.
///
/// \param dstBuffer Output area and destination pixels.
virtual void ProcessArea (uint32 threadIndex,
dng_pixel_buffer &srcBuffer,
dng_pixel_buffer &dstBuffer) = 0;
/// Called prior to processing on specific threads. Can be used to allocate
/// per-thread memory buffers, etc.
///
/// \param threadCount Total number of threads that will be used for
/// processing. Less than or equal to MaxThreads of dng_area_task.
///
/// \param tileSize Size of source tiles which will be processed. (Not all
/// tiles will be this size due to edge conditions.)
///
/// \param allocator dng_memory_allocator to use for allocating temporary
/// buffers, etc.
///
/// \param sniffer Sniffer to test for user cancellation and to set up
/// progress.
virtual void Start (uint32 threadCount,
const dng_point &tileSize,
dng_memory_allocator *allocator,
dng_abort_sniffer *sniffer);
/// Process one tile or partitioned area. Should not be overridden. Instead,
/// override ProcessArea, which is where to implement filter processing for a
/// specific type of dng_filter_task. There is no allocator parameter as all
/// allocation should be done in Start.
///
/// \param threadIndex 0 to threadCount - 1 index indicating which thread
/// this is. (Can be used to get a thread-specific buffer allocated in the
/// Start method.)
///
/// \param area Size of tiles to be used for sizing buffers, etc. (Edges of
/// processing can be smaller.)
///
/// \param sniffer dng_abort_sniffer to use to check for user cancellation
/// and progress updates.
virtual void Process (uint32 threadIndex,
const dng_rect &area,
dng_abort_sniffer *sniffer);
};
/*****************************************************************************/
#endif
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,589 @@
/*****************************************************************************/
// Copyright 2006-2007 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_fingerprint.cpp#3 $ */
/* $DateTime: 2012/07/11 10:36:56 $ */
/* $Change: 838485 $ */
/* $Author: tknoll $ */
/*****************************************************************************/
#include "dng_fingerprint.h"
#include "dng_assertions.h"
#include "dng_flags.h"
/*****************************************************************************/
dng_fingerprint::dng_fingerprint ()
{
for (uint32 j = 0; j < 16; j++)
{
data [j] = 0;
}
}
/*****************************************************************************/
bool dng_fingerprint::IsNull () const
{
for (uint32 j = 0; j < 16; j++)
{
if (data [j] != 0)
{
return false;
}
}
return true;
}
/*****************************************************************************/
bool dng_fingerprint::operator== (const dng_fingerprint &print) const
{
for (uint32 j = 0; j < 16; j++)
{
if (data [j] != print.data [j])
{
return false;
}
}
return true;
}
/******************************************************************************/
uint32 dng_fingerprint::Collapse32 () const
{
uint32 x = 0;
for (uint32 j = 0; j < 4; j++)
{
uint32 y = 0;
for (uint32 k = 0; k < 4; k++)
{
y = (y << 8) + (uint32) data [j * 4 + k];
}
x = x ^ y;
}
return x;
}
/******************************************************************************/
static char NumToHexChar (unsigned int c)
{
if (c < 10)
{
return (char) ('0' + c);
}
else
{
return (char) ('A' + c - 10);
}
}
/*****************************************************************************/
void dng_fingerprint::ToUtf8HexString (char resultStr [2 * kDNGFingerprintSize + 1]) const
{
for (size_t i = 0; i < kDNGFingerprintSize; i++)
{
unsigned char c = data [i];
resultStr [i * 2] = NumToHexChar (c >> 4);
resultStr [i * 2 + 1] = NumToHexChar (c & 15);
}
resultStr [kDNGFingerprintSize * 2] = '\0';
}
/******************************************************************************/
static int HexCharToNum (char hexChar)
{
if (hexChar >= '0' && hexChar <= '9')
{
return hexChar - '0';
}
else if (hexChar >= 'A' && hexChar <= 'F')
{
return hexChar - 'A' + 10;
}
else if (hexChar >= 'a' && hexChar <= 'f')
{
return hexChar - 'a' + 10;
}
return -1;
}
/*****************************************************************************/
bool dng_fingerprint::FromUtf8HexString (const char inputStr [2 * kDNGFingerprintSize + 1])
{
for (size_t i = 0; i < kDNGFingerprintSize; i++)
{
int highNibble = HexCharToNum (inputStr [i * 2]);
if (highNibble < 0)
{
return false;
}
int lowNibble = HexCharToNum (inputStr [i * 2 + 1]);
if (lowNibble < 0)
{
return false;
}
data [i] = (uint8) ((highNibble << 4) + lowNibble);
}
return true;
}
/******************************************************************************/
// Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm
// Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
// rights reserved.
//
// License to copy and use this software is granted provided that it
// is identified as the "RSA Data Security, Inc. MD5 Message-Digest
// Algorithm" in all material mentioning or referencing this software
// or this function.
//
// License is also granted to make and use derivative works provided
// that such works are identified as "derived from the RSA Data
// Security, Inc. MD5 Message-Digest Algorithm" in all material
// mentioning or referencing the derived work.
//
// RSA Data Security, Inc. makes no representations concerning either
// the merchantability of this software or the suitability of this
// software for any particular purpose. It is provided "as is"
// without express or implied warranty of any kind.
//
// These notices must be retained in any copies of any part of this
// documentation and/or software.
/******************************************************************************/
dng_md5_printer::dng_md5_printer ()
: final (false)
, result ()
{
Reset ();
}
/******************************************************************************/
void dng_md5_printer::Reset ()
{
// No bits processed yet.
count [0] = 0;
count [1] = 0;
// Load magic initialization constants.
state [0] = 0x67452301;
state [1] = 0xefcdab89;
state [2] = 0x98badcfe;
state [3] = 0x10325476;
// Not finalized yet.
final = false;
}
/******************************************************************************/
void dng_md5_printer::Process (const void *data,
uint32 inputLen)
{
DNG_ASSERT (!final, "Fingerprint already finalized!");
const uint8 *input = (const uint8 *) data;
// Compute number of bytes mod 64
uint32 index = (count [0] >> 3) & 0x3F;
// Update number of bits
if ((count [0] += inputLen << 3) < (inputLen << 3))
{
count [1]++;
}
count [1] += inputLen >> 29;
// Transform as many times as possible.
uint32 i = 0;
uint32 partLen = 64 - index;
if (inputLen >= partLen)
{
memcpy (&buffer [index],
input,
partLen);
MD5Transform (state, buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
{
MD5Transform (state, &input [i]);
}
index = 0;
}
// Buffer remaining input
memcpy (&buffer [index],
&input [i],
inputLen - i);
}
/******************************************************************************/
const dng_fingerprint & dng_md5_printer::Result ()
{
if (!final)
{
static uint8 PADDING [64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
// Save number of bits
uint8 bits [8];
Encode (bits, count, 8);
// Pad out to 56 mod 64.
uint32 index = (count [0] >> 3) & 0x3f;
uint32 padLen = (index < 56) ? (56 - index) : (120 - index);
Process (PADDING, padLen);
// Append length (before padding)
Process (bits, 8);
// Store state in digest
Encode (result.data, state, 16);
// We are now finalized.
final = true;
}
return result;
}
/******************************************************************************/
// Encodes input (uint32) into output (uint8). Assumes len is
// a multiple of 4.
void dng_md5_printer::Encode (uint8 *output,
const uint32 *input,
uint32 len)
{
uint32 i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
{
output [j ] = (uint8) ((input [i] ) & 0xff);
output [j+1] = (uint8) ((input [i] >> 8) & 0xff);
output [j+2] = (uint8) ((input [i] >> 16) & 0xff);
output [j+3] = (uint8) ((input [i] >> 24) & 0xff);
}
}
/******************************************************************************/
// Decodes input (uint8) into output (uint32). Assumes len is
// a multiple of 4.
void dng_md5_printer::Decode (uint32 *output,
const uint8 *input,
uint32 len)
{
// Check for non-aligned case.
if (((uintptr) input) & 3)
{
uint32 i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
{
output [i] = (((uint32) input [j ]) ) |
(((uint32) input [j+1]) << 8) |
(((uint32) input [j+2]) << 16) |
(((uint32) input [j+3]) << 24);
}
}
// Else use optimized code for aligned case.
else
{
len = len >> 2;
const uint32 *sPtr = (const uint32 *) input;
uint32 *dPtr = output;
while (len--)
{
#if qDNGBigEndian
uint32 data = *(sPtr++);
data = (data >> 24) |
((data >> 8) & 0x0000FF00) |
((data << 8) & 0x00FF0000) |
(data << 24);
*(dPtr++) = data;
#else
*(dPtr++) = *(sPtr++);
#endif
}
}
}
/******************************************************************************/
// MD5 basic transformation. Transforms state based on block.
void dng_md5_printer::MD5Transform (uint32 state [4],
const uint8 block [64])
{
enum
{
S11 = 7,
S12 = 12,
S13 = 17,
S14 = 22,
S21 = 5,
S22 = 9,
S23 = 14,
S24 = 20,
S31 = 4,
S32 = 11,
S33 = 16,
S34 = 23,
S41 = 6,
S42 = 10,
S43 = 15,
S44 = 21
};
#if qDNGBigEndian
uint32 x [16];
Decode (x, block, 64);
#else
uint32 temp [16];
const uint32 *x;
if (((uintptr) block) & 3)
{
Decode (temp, block, 64);
x = temp;
}
else
x = (const uint32 *) block;
#endif
uint32 a = state [0];
uint32 b = state [1];
uint32 c = state [2];
uint32 d = state [3];
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state [0] += a;
state [1] += b;
state [2] += c;
state [3] += d;
}
/*****************************************************************************/
// End of RSA Data Security, Inc. derived code.
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,377 @@
/*****************************************************************************/
// Copyright 2006-2007 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_fingerprint.h#2 $ */
/* $DateTime: 2012/07/11 10:36:56 $ */
/* $Change: 838485 $ */
/* $Author: tknoll $ */
/** \file
* Fingerprint (cryptographic hashing) support for generating strong hashes of image
* data.
*/
/*****************************************************************************/
#ifndef __dng_fingerprint__
#define __dng_fingerprint__
/*****************************************************************************/
#include "dng_exceptions.h"
#include "dng_types.h"
#include "dng_stream.h"
#include <cstring>
/*****************************************************************************/
/// \brief Container fingerprint (MD5 only at present).
class dng_fingerprint
{
public:
static const size_t kDNGFingerprintSize = 16;
uint8 data [kDNGFingerprintSize];
public:
dng_fingerprint ();
/// Check if fingerprint is all zeros.
bool IsNull () const;
/// Same as IsNull but expresses intention of testing validity.
bool IsValid () const
{
return !IsNull ();
}
/// Set to all zeros, a value used to indicate an invalid fingerprint.
void Clear ()
{
*this = dng_fingerprint ();
}
/// Test if two fingerprints are equal.
bool operator== (const dng_fingerprint &print) const;
/// Test if two fingerprints are not equal.
bool operator!= (const dng_fingerprint &print) const
{
return !(*this == print);
}
/// Produce a 32-bit hash value from fingerprint used for faster hashing of
/// fingerprints.
uint32 Collapse32 () const;
/// Convert fingerprint to UTF-8 string.
///
/// \param resultStr The output array to which the UTF-8 encoding of the
/// fingerprint will be written.
void ToUtf8HexString (char resultStr [2 * kDNGFingerprintSize + 1]) const;
/// Convert UTF-8 string to fingerprint. Returns true on success, false on
/// failure.
///
/// \param inputStr The input array from which the UTF-8 encoding of the
/// fingerprint will be read.
///
/// \retval True indicates success.
bool FromUtf8HexString (const char inputStr [2 * kDNGFingerprintSize + 1]);
};
/*****************************************************************************/
/// \brief Utility to compare fingerprints (e.g., for sorting).
struct dng_fingerprint_less_than
{
/// Less-than comparison.
bool operator() (const dng_fingerprint &a,
const dng_fingerprint &b) const
{
return memcmp (a.data,
b.data,
sizeof (a.data)) < 0;
}
};
/******************************************************************************/
// Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm.
// Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
// rights reserved.
//
// License to copy and use this software is granted provided that it
// is identified as the "RSA Data Security, Inc. MD5 Message-Digest
// Algorithm" in all material mentioning or referencing this software
// or this function.
//
// License is also granted to make and use derivative works provided
// that such works are identified as "derived from the RSA Data
// Security, Inc. MD5 Message-Digest Algorithm" in all material
// mentioning or referencing the derived work.
//
// RSA Data Security, Inc. makes no representations concerning either
// the merchantability of this software or the suitability of this
// software for any particular purpose. It is provided "as is"
// without express or implied warranty of any kind.
//
// These notices must be retained in any copies of any part of this
// documentation and/or software.
/// \brief Class to hash binary data to a fingerprint using the MD5 Message-Digest
/// Algorithm.
class dng_md5_printer
{
public:
dng_md5_printer ();
virtual ~dng_md5_printer ()
{
}
/// Reset the fingerprint.
void Reset ();
/// Append the data to the stream to be hashed.
/// \param data The data to be hashed.
/// \param inputLen The length of data, in bytes.
void Process (const void *data,
uint32 inputLen);
/// Append the string to the stream to be hashed.
/// \param text The string to be hashed.
void Process (const char *text)
{
Process (text, (uint32) strlen (text));
}
/// Get the fingerprint (i.e., result of the hash).
const dng_fingerprint & Result ();
private:
static void Encode (uint8 *output,
const uint32 *input,
uint32 len);
static void Decode (uint32 *output,
const uint8 *input,
uint32 len);
// F, G, H and I are basic MD5 functions.
static inline uint32 F (uint32 x,
uint32 y,
uint32 z)
{
return (x & y) | (~x & z);
}
static inline uint32 G (uint32 x,
uint32 y,
uint32 z)
{
return (x & z) | (y & ~z);
}
static inline uint32 H (uint32 x,
uint32 y,
uint32 z)
{
return x ^ y ^ z;
}
static inline uint32 I (uint32 x,
uint32 y,
uint32 z)
{
return y ^ (x | ~z);
}
// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
static inline void FF (uint32 &a,
uint32 b,
uint32 c,
uint32 d,
uint32 x,
uint32 s,
uint32 ac)
{
a += F (b, c, d) + x + ac;
a = (a << s) | (a >> (32 - s));
a += b;
}
static inline void GG (uint32 &a,
uint32 b,
uint32 c,
uint32 d,
uint32 x,
uint32 s,
uint32 ac)
{
a += G (b, c, d) + x + ac;
a = (a << s) | (a >> (32 - s));
a += b;
}
static inline void HH (uint32 &a,
uint32 b,
uint32 c,
uint32 d,
uint32 x,
uint32 s,
uint32 ac)
{
a += H (b, c, d) + x + ac;
a = (a << s) | (a >> (32 - s));
a += b;
}
static inline void II (uint32 &a,
uint32 b,
uint32 c,
uint32 d,
uint32 x,
uint32 s,
uint32 ac)
{
a += I (b, c, d) + x + ac;
a = (a << s) | (a >> (32 - s));
a += b;
}
static void MD5Transform (uint32 state [4],
const uint8 block [64]);
private:
uint32 state [4];
uint32 count [2];
uint8 buffer [64];
bool final;
dng_fingerprint result;
};
/*****************************************************************************/
/// \brief A dng_stream based interface to the MD5 printing logic.
class dng_md5_printer_stream : public dng_stream, dng_md5_printer
{
private:
uint64 fNextOffset;
public:
/// Create an empty MD5 printer stream.
dng_md5_printer_stream ()
: fNextOffset (0)
{
}
virtual uint64 DoGetLength ()
{
return fNextOffset;
}
virtual void DoRead (void * /* data */,
uint32 /* count */,
uint64 /* offset */)
{
ThrowProgramError ();
}
virtual void DoSetLength (uint64 length)
{
if (length != fNextOffset)
{
ThrowProgramError ();
}
}
virtual void DoWrite (const void *data,
uint32 count2,
uint64 offset)
{
if (offset != fNextOffset)
{
ThrowProgramError ();
}
Process (data, count2);
fNextOffset += count2;
}
const dng_fingerprint & Result ()
{
Flush ();
return dng_md5_printer::Result ();
}
};
/*****************************************************************************/
#endif
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,267 @@
/*****************************************************************************/
// Copyright 2006-2012 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_flags.h#5 $ */
/* $DateTime: 2012/07/31 22:04:34 $ */
/* $Change: 840853 $ */
/* $Author: tknoll $ */
/** \file
* Conditional compilation flags for DNG SDK.
*
* All conditional compilation macros for the DNG SDK begin with a lowercase 'q'.
*/
/*****************************************************************************/
#ifndef __dng_flags__
#define __dng_flags__
#define METADATA_CLEANUP 0
#include "gpr_platform.h"
/*****************************************************************************/
/// \def qMacOS
/// 1 if compiling for Mac OS X.
/// \def qWinOS
/// 1 if compiling for Windows.
// Make sure qMacOS and qWinOS are defined.
#if !defined(qMacOS) && !defined(qWinOS)
#include "RawEnvironment.h"
#endif
#if !defined(qMacOS) && !defined(qWinOS)
#error Unable to figure out platform
#endif
/*****************************************************************************/
// Platforms.
#ifndef qImagecore
#define qImagecore 0
#endif
#ifndef qiPhone
#define qiPhone 0
#endif
#ifndef qiPhoneSimulator
#define qiPhoneSimulator 0
#endif
#ifndef qAndroid
#define qAndroid 0
#endif
#ifndef qAndroidArm7
#define qAndroidArm7 0
#endif
/*****************************************************************************/
// Establish WIN32 and WIN64 definitions.
#if defined(_WIN32) && !defined(WIN32)
#define WIN32 1
#endif
#if defined(_WIN64) && !defined(WIN64)
#define WIN64 1
#endif
/*****************************************************************************/
/// \def qDNGDebug
/// 1 if debug code is compiled in, 0 otherwise. Enables assertions and other debug
/// checks in exchange for slower processing.
// Figure out if debug build or not.
#ifndef qDNGDebug
#if defined(Debug)
#define qDNGDebug Debug
#elif defined(_DEBUG)
#define qDNGDebug _DEBUG
#else
#define qDNGDebug 0
#endif
#endif
/*****************************************************************************/
// Figure out byte order.
/// \def qDNGBigEndian
/// 1 if this target platform is big endian (e.g. PowerPC Macintosh), else 0.
///
/// \def qDNGLittleEndian
/// 1 if this target platform is little endian (e.g. x86 processors), else 0.
#ifndef qDNGBigEndian
#if defined(qDNGLittleEndian)
#define qDNGBigEndian !qDNGLittleEndian
#elif defined(__POWERPC__)
#define qDNGBigEndian 1
#elif defined(__INTEL__)
#define qDNGBigEndian 0
#elif defined(_M_IX86)
#define qDNGBigEndian 0
#elif defined(_M_X64) || defined(__amd64__)
#define qDNGBigEndian 0
#elif defined(__LITTLE_ENDIAN__)
#define qDNGBigEndian 0
#elif defined(__BIG_ENDIAN__)
#define qDNGBigEndian 1
#elif defined(_ARM_)
#define qDNGBigEndian 0
#else
#ifndef qXCodeRez
#error Unable to figure out byte order.
#endif
#endif
#endif
#ifndef qXCodeRez
#ifndef qDNGLittleEndian
#define qDNGLittleEndian !qDNGBigEndian
#endif
#endif
/*****************************************************************************/
/// \def qDNG64Bit
/// 1 if this target platform uses 64-bit addresses, 0 otherwise.
#ifndef qDNG64Bit
#if qMacOS
#ifdef __LP64__
#if __LP64__
#define qDNG64Bit 1
#endif
#endif
#elif qWinOS
#ifdef WIN64
#if WIN64
#define qDNG64Bit 1
#endif
#endif
#endif
#ifndef qDNG64Bit
#define qDNG64Bit 0
#endif
#endif
/*****************************************************************************/
/// \def qDNGThreadSafe
/// 1 if target platform has thread support and threadsafe libraries, 0 otherwise.
#ifndef qDNGThreadSafe
#define qDNGThreadSafe (qMacOS || qWinOS)
#endif
/*****************************************************************************/
/// \def qDNGValidateTarget
/// 1 if dng_validate command line tool is being built, 0 otherwise.
#ifndef qDNGValidateTarget
#define qDNGValidateTarget 0
#endif
/*****************************************************************************/
/// \def qDNGValidate
/// 1 if DNG validation code is enabled, 0 otherwise.
#ifndef qDNGValidate
#define qDNGValidate qDNGValidateTarget
#endif
/*****************************************************************************/
/// \def qDNGPrintMessages
/// 1 if dng_show_message should use fprintf to stderr. 0 if it should use a platform
/// specific interrupt mechanism.
#ifndef qDNGPrintMessages
#define qDNGPrintMessages qDNGValidate
#endif
/*****************************************************************************/
/// \def qDNGCodec
/// 1 to build the Windows Imaging Component Codec (e.g. for Vista).
#ifndef qDNGCodec
#define qDNGCodec 0
#endif
/*****************************************************************************/
// Experimental features -- work in progress for Lightroom 4.0 and Camera Raw 7.0.
// Turn this off for Lightroom 3.x & Camera Raw 6.x dot releases.
#ifndef qDNGExperimental
#define qDNGExperimental 1
#endif
/*****************************************************************************/
/// \def qDNGXMPFiles
/// 1 to use XMPFiles.
#ifndef qDNGXMPFiles
#define qDNGXMPFiles 0
#endif
/*****************************************************************************/
/// \def qDNGXMPDocOps
/// 1 to use XMPDocOps.
#ifndef qDNGXMPDocOps
#define qDNGXMPDocOps 0
#endif
/*****************************************************************************/
#endif
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,582 @@
/*****************************************************************************/
// Copyright 2008-2009 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_gain_map.cpp#1 $ */
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */
/*****************************************************************************/
#include "dng_gain_map.h"
#include "dng_exceptions.h"
#include "dng_globals.h"
#include "dng_host.h"
#include "dng_pixel_buffer.h"
#include "dng_stream.h"
#include "dng_tag_values.h"
/*****************************************************************************/
class dng_gain_map_interpolator
{
private:
const dng_gain_map &fMap;
dng_point_real64 fScale;
dng_point_real64 fOffset;
int32 fColumn;
int32 fPlane;
uint32 fRowIndex1;
uint32 fRowIndex2;
real32 fRowFract;
int32 fResetColumn;
real32 fValueBase;
real32 fValueStep;
real32 fValueIndex;
public:
dng_gain_map_interpolator (const dng_gain_map &map,
const dng_rect &mapBounds,
int32 row,
int32 column,
uint32 plane);
real32 Interpolate () const
{
return fValueBase + fValueStep * fValueIndex;
}
void Increment ()
{
if (++fColumn >= fResetColumn)
{
ResetColumn ();
}
else
{
fValueIndex += 1.0f;
}
}
private:
real32 InterpolateEntry (uint32 colIndex);
void ResetColumn ();
};
/*****************************************************************************/
dng_gain_map_interpolator::dng_gain_map_interpolator (const dng_gain_map &map,
const dng_rect &mapBounds,
int32 row,
int32 column,
uint32 plane)
: fMap (map)
, fScale (1.0 / mapBounds.H (),
1.0 / mapBounds.W ())
, fOffset (0.5 - mapBounds.t,
0.5 - mapBounds.l)
, fColumn (column)
, fPlane (plane)
, fRowIndex1 (0)
, fRowIndex2 (0)
, fRowFract (0.0f)
, fResetColumn (0)
, fValueBase (0.0f)
, fValueStep (0.0f)
, fValueIndex (0.0f)
{
real64 rowIndexF = (fScale.v * (row + fOffset.v) -
fMap.Origin ().v) / fMap.Spacing ().v;
if (rowIndexF <= 0.0)
{
fRowIndex1 = 0;
fRowIndex2 = 0;
fRowFract = 0.0f;
}
else
{
fRowIndex1 = (uint32) rowIndexF;
if ((int32) fRowIndex1 >= fMap.Points ().v - 1)
{
fRowIndex1 = fMap.Points ().v - 1;
fRowIndex2 = fRowIndex1;
fRowFract = 0.0f;
}
else
{
fRowIndex2 = fRowIndex1 + 1;
fRowFract = (real32) (rowIndexF - (real64) fRowIndex1);
}
}
ResetColumn ();
}
/*****************************************************************************/
real32 dng_gain_map_interpolator::InterpolateEntry (uint32 colIndex)
{
return fMap.Entry (fRowIndex1, colIndex, fPlane) * (1.0f - fRowFract) +
fMap.Entry (fRowIndex2, colIndex, fPlane) * ( fRowFract);
}
/*****************************************************************************/
void dng_gain_map_interpolator::ResetColumn ()
{
real64 colIndexF = ((fScale.h * (fColumn + fOffset.h)) -
fMap.Origin ().h) / fMap.Spacing ().h;
if (colIndexF <= 0.0)
{
fValueBase = InterpolateEntry (0);
fValueStep = 0.0f;
fResetColumn = (int32) ceil (fMap.Origin ().h / fScale.h - fOffset.h);
}
else
{
uint32 colIndex = (uint32) colIndexF;
if ((int32) colIndex >= fMap.Points ().h - 1)
{
fValueBase = InterpolateEntry (fMap.Points ().h - 1);
fValueStep = 0.0f;
fResetColumn = 0x7FFFFFFF;
}
else
{
real64 base = InterpolateEntry (colIndex);
real64 delta = InterpolateEntry (colIndex + 1) - base;
fValueBase = (real32) (base + delta * (colIndexF - (real64) colIndex));
fValueStep = (real32) ((delta * fScale.h) / fMap.Spacing ().h);
fResetColumn = (int32) ceil (((colIndex + 1) * fMap.Spacing ().h +
fMap.Origin ().h) / fScale.h - fOffset.h);
}
}
fValueIndex = 0.0f;
}
/*****************************************************************************/
dng_gain_map::dng_gain_map (dng_memory_allocator &allocator,
const dng_point &points,
const dng_point_real64 &spacing,
const dng_point_real64 &origin,
uint32 planes)
: fPoints (points)
, fSpacing (spacing)
, fOrigin (origin)
, fPlanes (planes)
, fRowStep (planes * points.h)
, fBuffer ()
{
fBuffer.Reset (allocator.Allocate (fPoints.v *
fPoints.h *
fPlanes * (uint32) sizeof (real32)));
}
/*****************************************************************************/
real32 dng_gain_map::Interpolate (int32 row,
int32 col,
uint32 plane,
const dng_rect &bounds) const
{
dng_gain_map_interpolator interp (*this,
bounds,
row,
col,
plane);
return interp.Interpolate ();
}
/*****************************************************************************/
uint32 dng_gain_map::PutStreamSize () const
{
return 44 + fPoints.v * fPoints.h * fPlanes * 4;
}
/*****************************************************************************/
void dng_gain_map::PutStream (dng_stream &stream) const
{
stream.Put_uint32 (fPoints.v);
stream.Put_uint32 (fPoints.h);
stream.Put_real64 (fSpacing.v);
stream.Put_real64 (fSpacing.h);
stream.Put_real64 (fOrigin.v);
stream.Put_real64 (fOrigin.h);
stream.Put_uint32 (fPlanes);
for (int32 rowIndex = 0; rowIndex < fPoints.v; rowIndex++)
{
for (int32 colIndex = 0; colIndex < fPoints.h; colIndex++)
{
for (uint32 plane = 0; plane < fPlanes; plane++)
{
stream.Put_real32 (Entry (rowIndex,
colIndex,
plane));
}
}
}
}
/*****************************************************************************/
dng_gain_map * dng_gain_map::GetStream (dng_stream &stream, dng_memory_allocator &allocator)
{
dng_point mapPoints;
mapPoints.v = stream.Get_uint32 ();
mapPoints.h = stream.Get_uint32 ();
dng_point_real64 mapSpacing;
mapSpacing.v = stream.Get_real64 ();
mapSpacing.h = stream.Get_real64 ();
dng_point_real64 mapOrigin;
mapOrigin.v = stream.Get_real64 ();
mapOrigin.h = stream.Get_real64 ();
uint32 mapPlanes = stream.Get_uint32 ();
#if qDNGValidate
if (gVerbose)
{
printf ("Points: v=%d, h=%d\n",
(int) mapPoints.v,
(int) mapPoints.h);
printf ("Spacing: v=%.6f, h=%.6f\n",
mapSpacing.v,
mapSpacing.h);
printf ("Origin: v=%.6f, h=%.6f\n",
mapOrigin.v,
mapOrigin.h);
printf ("Planes: %u\n",
(unsigned) mapPlanes);
}
#endif
if (mapPoints.v == 1)
{
mapSpacing.v = 1.0;
mapOrigin.v = 0.0;
}
if (mapPoints.h == 1)
{
mapSpacing.h = 1.0;
mapOrigin.h = 0.0;
}
if (mapPoints.v < 1 ||
mapPoints.h < 1 ||
mapSpacing.v <= 0.0 ||
mapSpacing.h <= 0.0 ||
mapPlanes < 1)
{
ThrowBadFormat ();
}
AutoPtr<dng_gain_map> map (new dng_gain_map (allocator,
mapPoints,
mapSpacing,
mapOrigin,
mapPlanes));
#if qDNGValidate
uint32 linesPrinted = 0;
uint32 linesSkipped = 0;
#endif
for (int32 rowIndex = 0; rowIndex < mapPoints.v; rowIndex++)
{
for (int32 colIndex = 0; colIndex < mapPoints.h; colIndex++)
{
for (uint32 plane = 0; plane < mapPlanes; plane++)
{
real32 x = stream.Get_real32 ();
map->Entry (rowIndex, colIndex, plane) = x;
#if qDNGValidate
if (gVerbose)
{
if (linesPrinted < gDumpLineLimit)
{
printf (" Map [%3u] [%3u] [%u] = %.4f\n",
(unsigned) rowIndex,
(unsigned) colIndex,
(unsigned) plane,
x);
linesPrinted++;
}
else
linesSkipped++;
}
#endif
}
}
}
#if qDNGValidate
if (linesSkipped)
{
printf (" ... %u map entries skipped\n", (unsigned) linesSkipped);
}
#endif
return map.Release ();
}
/*****************************************************************************/
dng_opcode_GainMap::dng_opcode_GainMap (const dng_area_spec &areaSpec,
AutoPtr<dng_gain_map> &gainMap)
: dng_inplace_opcode (dngOpcode_GainMap,
dngVersion_1_3_0_0,
kFlag_None)
, fAreaSpec (areaSpec)
, fGainMap ()
{
fGainMap.Reset (gainMap.Release ());
}
/*****************************************************************************/
dng_opcode_GainMap::dng_opcode_GainMap (dng_host &host,
dng_stream &stream)
: dng_inplace_opcode (dngOpcode_GainMap,
stream,
"GainMap")
, fAreaSpec ()
, fGainMap ()
{
uint32 byteCount = stream.Get_uint32 ();
uint64 startPosition = stream.Position ();
fAreaSpec.GetData (stream);
fGainMap.Reset (dng_gain_map::GetStream (stream, host.Allocator()));
if (stream.Position () != startPosition + byteCount)
{
ThrowBadFormat ();
}
}
/*****************************************************************************/
void dng_opcode_GainMap::PutData (dng_stream &stream) const
{
stream.Put_uint32 (dng_area_spec::kDataSize +
fGainMap->PutStreamSize ());
fAreaSpec.PutData (stream);
fGainMap->PutStream (stream);
}
/*****************************************************************************/
void dng_opcode_GainMap::ProcessArea (dng_negative & /* negative */,
uint32 /* threadIndex */,
dng_pixel_buffer &buffer,
const dng_rect &dstArea,
const dng_rect &imageBounds)
{
dng_rect overlap = fAreaSpec.Overlap (dstArea);
if (overlap.NotEmpty ())
{
uint32 cols = overlap.W ();
uint32 colPitch = fAreaSpec.ColPitch ();
for (uint32 plane = fAreaSpec.Plane ();
plane < fAreaSpec.Plane () + fAreaSpec.Planes () &&
plane < buffer.Planes ();
plane++)
{
uint32 mapPlane = Min_uint32 (plane, fGainMap->Planes () - 1);
for (int32 row = overlap.t; row < overlap.b; row += fAreaSpec.RowPitch ())
{
real32 *dPtr = buffer.DirtyPixel_real32 (row, overlap.l, plane);
dng_gain_map_interpolator interp (*fGainMap,
imageBounds,
row,
overlap.l,
mapPlane);
for (uint32 col = 0; col < cols; col += colPitch)
{
real32 gain = interp.Interpolate ();
dPtr [col] = Min_real32 (dPtr [col] * gain, 1.0f);
for (uint32 j = 0; j < colPitch; j++)
{
interp.Increment ();
}
}
}
}
}
}
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,218 @@
/*****************************************************************************/
// Copyright 2008-2009 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_gain_map.h#2 $ */
/* $DateTime: 2012/07/31 22:04:34 $ */
/* $Change: 840853 $ */
/* $Author: tknoll $ */
/** \file
* Opcode to fix 2D uniformity defects, such as shading.
*/
/*****************************************************************************/
#ifndef __dng_gain_map__
#define __dng_gain_map__
/*****************************************************************************/
#include "dng_memory.h"
#include "dng_misc_opcodes.h"
#include "dng_tag_types.h"
/*****************************************************************************/
/// \brief Holds a discrete (i.e., sampled) 2D representation of a gain map. This is
/// effectively an image containing scale factors.
class dng_gain_map
{
private:
dng_point fPoints;
dng_point_real64 fSpacing;
dng_point_real64 fOrigin;
uint32 fPlanes;
uint32 fRowStep;
AutoPtr<dng_memory_block> fBuffer;
public:
/// Construct a gain map with the specified memory allocator, number of
/// samples (points), sample spacing, origin, and number of color planes.
dng_gain_map (dng_memory_allocator &allocator,
const dng_point &points,
const dng_point_real64 &spacing,
const dng_point_real64 &origin,
uint32 planes);
/// The number of samples in the horizontal and vertical directions.
const dng_point & Points () const
{
return fPoints;
}
/// The space between adjacent samples in the horizontal and vertical
/// directions.
const dng_point_real64 & Spacing () const
{
return fSpacing;
}
/// The 2D coordinate for the first (i.e., top-left-most) sample.
const dng_point_real64 & Origin () const
{
return fOrigin;
}
/// The number of color planes.
uint32 Planes () const
{
return fPlanes;
}
/// Getter for a gain map sample (specified by row, column, and plane).
real32 & Entry (uint32 rowIndex,
uint32 colIndex,
uint32 plane)
{
return *(fBuffer->Buffer_real32 () +
rowIndex * fRowStep +
colIndex * fPlanes +
plane);
}
/// Getter for a gain map sample (specified by row index, column index, and
/// plane index).
const real32 & Entry (uint32 rowIndex,
uint32 colIndex,
uint32 plane) const
{
return *(fBuffer->Buffer_real32 () +
rowIndex * fRowStep +
colIndex * fPlanes +
plane);
}
/// Compute the interpolated gain (i.e., scale factor) at the specified pixel
/// position and color plane, within the specified image bounds (in pixels).
real32 Interpolate (int32 row,
int32 col,
uint32 plane,
const dng_rect &bounds) const;
/// The number of bytes needed to hold the gain map data.
uint32 PutStreamSize () const;
/// Write the gain map to the specified stream.
void PutStream (dng_stream &stream) const;
/// Read a gain map from the specified stream.
static dng_gain_map * GetStream (dng_stream &stream, dng_memory_allocator &allocator);
private:
// Hidden copy constructor and assignment operator.
dng_gain_map (const dng_gain_map &map);
dng_gain_map & operator= (const dng_gain_map &map);
};
/*****************************************************************************/
/// \brief An opcode to fix 2D spatially-varying light falloff or color casts (i.e.,
/// uniformity issues). This is commonly due to shading.
class dng_opcode_GainMap: public dng_inplace_opcode
{
private:
dng_area_spec fAreaSpec;
AutoPtr<dng_gain_map> fGainMap;
public:
/// Construct a GainMap opcode for the specified image area and the specified
/// gain map.
dng_opcode_GainMap (const dng_area_spec &areaSpec,
AutoPtr<dng_gain_map> &gainMap);
/// Construct a GainMap opcode from the specified stream.
dng_opcode_GainMap (dng_host &host,
dng_stream &stream);
/// Write the opcode to the specified stream.
virtual void PutData (dng_stream &stream) const;
/// The pixel data type of this opcode.
virtual uint32 BufferPixelType (uint32 /* imagePixelType */)
{
return ttFloat;
}
/// The adjusted bounds (processing area) of this opcode. It is limited to
/// the intersection of the specified image area and the GainMap area.
virtual dng_rect ModifiedBounds (const dng_rect &imageBounds)
{
return fAreaSpec.Overlap (imageBounds);
}
/// Apply the gain map.
virtual void ProcessArea (dng_negative &negative,
uint32 threadIndex,
dng_pixel_buffer &buffer,
const dng_rect &dstArea,
const dng_rect &imageBounds);
private:
// Hidden copy constructor and assignment operator.
dng_opcode_GainMap (const dng_opcode_GainMap &opcode);
dng_opcode_GainMap & operator= (const dng_opcode_GainMap &opcode);
};
/*****************************************************************************/
#endif
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,28 @@
/*****************************************************************************/
// Copyright 2006 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_globals.cpp#1 $ */
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */
/*****************************************************************************/
#include "dng_globals.h"
/*****************************************************************************/
#if qDNGValidate
bool gVerbose = false;
uint32 gDumpLineLimit = 100;
#endif
/*****************************************************************************/

Wyświetl plik

@ -0,0 +1,46 @@
/*****************************************************************************/
// Copyright 2006 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_globals.h#1 $ */
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */
/** \file
* Definitions of global variables controling DNG SDK behavior. Currenntly only used for validation control.
*/
/*****************************************************************************/
#ifndef __dng_globals__
#define __dng_globals__
/*****************************************************************************/
#include "dng_flags.h"
#include "dng_types.h"
/*****************************************************************************/
#if qDNGValidate
/// When validation (qValidate) is turned on, this globale enables verbose output about DNG tags and other properties.
extern bool gVerbose;
/// When validation (qValidate) is turned on, and verbose mode (gVerbose) is enabled, limits the number of lines of text that are dumped for each tag.
extern uint32 gDumpLineLimit;
#endif
/*****************************************************************************/
#endif
/*****************************************************************************/

Some files were not shown because too many files have changed in this diff Show More