Login
Log in using an SSO provider:
Fedora Account System
Red Hat Associate
Red Hat Customer
Login using a Red Hat Bugzilla account
Forgot Password
Create an Account
Red Hat Bugzilla – Attachment 1254014 Details for
Bug 1424245
rawtherapee: FTBFS in rawhide
Home
New
Search
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh90 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
[?]
This site requires JavaScript to be enabled to function correctly, please enable it.
build.log
<fdopen> (text/plain), 750.65 KB, created by
Fedora Release Engineering
on 2017-02-17 16:27:02 UTC
(
hide
)
Description:
build.log
Filename:
MIME Type:
Creator:
Fedora Release Engineering
Created:
2017-02-17 16:27:02 UTC
Size:
750.65 KB
patch
obsolete
>Mock Version: 1.3.3 >Mock Version: 1.3.3 >ENTER ['do'](['bash', '--login', '-c', '/usr/bin/rpmbuild -bs --target ppc64le --nodeps /builddir/build/SPECS/rawtherapee.spec'], logger=<mockbuild.trace_decorator.getLog object at 0x3fff82e52390>printOutput=FalsechrootPath='/var/lib/mock/f26-build-7664934-694564/root'user='mockbuild'env={'PS1': '<mock-chroot> \\s-\\v\\$ ', 'HOSTNAME': 'mock', 'LANG': 'en_US.UTF-8', 'HOME': '/builddir', 'SHELL': '/bin/bash', 'TERM': 'vt100', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;<mock-chroot>\\007"'}timeout=172800gid=425uid=1000shell=False) >Executing command: ['bash', '--login', '-c', '/usr/bin/rpmbuild -bs --target ppc64le --nodeps /builddir/build/SPECS/rawtherapee.spec'] with env {'PS1': '<mock-chroot> \\s-\\v\\$ ', 'HOSTNAME': 'mock', 'LANG': 'en_US.UTF-8', 'HOME': '/builddir', 'SHELL': '/bin/bash', 'TERM': 'vt100', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;<mock-chroot>\\007"'} and shell False >Building target platforms: ppc64le >Building for target ppc64le >Wrote: /builddir/build/SRPMS/rawtherapee-5.0-2.fc26.src.rpm >Child return code was: 0 >ENTER ['do'](['bash', '--login', '-c', '/usr/bin/rpmbuild -bb --target ppc64le --nodeps /builddir/build/SPECS/rawtherapee.spec'], logger=<mockbuild.trace_decorator.getLog object at 0x3fff82e52390>printOutput=FalsechrootPath='/var/lib/mock/f26-build-7664934-694564/root'user='mockbuild'env={'PS1': '<mock-chroot> \\s-\\v\\$ ', 'HOSTNAME': 'mock', 'LANG': 'en_US.UTF-8', 'HOME': '/builddir', 'SHELL': '/bin/bash', 'TERM': 'vt100', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;<mock-chroot>\\007"'}timeout=172800private_network=Truegid=425uid=1000shell=False) >Executing command: ['bash', '--login', '-c', '/usr/bin/rpmbuild -bb --target ppc64le --nodeps /builddir/build/SPECS/rawtherapee.spec'] with env {'PS1': '<mock-chroot> \\s-\\v\\$ ', 'HOSTNAME': 'mock', 'LANG': 'en_US.UTF-8', 'HOME': '/builddir', 'SHELL': '/bin/bash', 'TERM': 'vt100', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;<mock-chroot>\\007"'} and shell False >Building target platforms: ppc64le >Building for target ppc64le >Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.Mc4sC8 >+ umask 022 >+ cd /builddir/build/BUILD >+ cd /builddir/build/BUILD >+ rm -rf RawTherapee-5.0-gtk3 >+ /usr/bin/gzip -dc /builddir/build/SOURCES/RawTherapee-5.0-gtk3.tar.gz >+ /usr/bin/tar -xof - >+ STATUS=0 >+ '[' 0 -ne 0 ']' >+ cd RawTherapee-5.0-gtk3 >+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w . >+ cat >+ sed -i 's|\r||g' LICENSE.txt >+ exit 0 >Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.1h7iSc >+ umask 022 >+ cd /builddir/build/BUILD >+ cd RawTherapee-5.0-gtk3 >+ CFLAGS='-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8' >+ export CFLAGS >+ CXXFLAGS='-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8' >+ export CXXFLAGS >+ FFLAGS='-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8 -I/usr/lib64/gfortran/modules' >+ export FFLAGS >+ FCFLAGS='-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8 -I/usr/lib64/gfortran/modules' >+ export FCFLAGS >+ LDFLAGS='-Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld' >+ export LDFLAGS >+ /usr/bin/cmake -DCMAKE_C_FLAGS_RELEASE:STRING=-DNDEBUG -DCMAKE_CXX_FLAGS_RELEASE:STRING=-DNDEBUG -DCMAKE_Fortran_FLAGS_RELEASE:STRING=-DNDEBUG -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -DCMAKE_INSTALL_PREFIX:PATH=/usr -DINCLUDE_INSTALL_DIR:PATH=/usr/include -DLIB_INSTALL_DIR:PATH=/usr/lib64 -DSYSCONF_INSTALL_DIR:PATH=/etc -DSHARE_INSTALL_PREFIX:PATH=/usr/share -DLIB_SUFFIX=64 -DBUILD_SHARED_LIBS:BOOL=ON -DCMAKE_INSTALL_PREFIX=/usr -DLIBDIR=/usr/lib64 -DCMAKE_BUILD_TYPE=release -DBUILD_SHARED_LIBS:BOOL=ON -DAUTOMATED_BUILD_SYSTEM:BOOL=ON -DCACHE_NAME_SUFFIX= '-DCMAKE_CXX_FLAGS=-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8' '-DCMAKE_C_FLAGS=-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8' . >-- The C compiler identification is GNU 7.0.1 >-- The CXX compiler identification is GNU 7.0.1 >-- Check for working C compiler: /usr/bin/cc >-- Check for working C compiler: /usr/bin/cc -- works >-- Detecting C compiler ABI info >-- Detecting C compiler ABI info - done >-- Detecting C compile features >-- Detecting C compile features - done >-- Check for working CXX compiler: /usr/bin/c++ >-- Check for working CXX compiler: /usr/bin/c++ -- works >-- Detecting CXX compiler ABI info >-- Detecting CXX compiler ABI info - done >-- Detecting CXX compile features >-- Detecting CXX compile features - done >-- CMAKE_BUILD_TYPE: release >-- Found PkgConfig: /usr/bin/pkg-config (found version "1.2.2") >-- Checking for module 'gtk+-3.0>=3.16' >-- Found gtk+-3.0, version 3.22.7 >-- Checking for module 'glib-2.0>=2.44' >-- Found glib-2.0, version 2.51.0 >-- Checking for module 'glibmm-2.4>=2.44' >-- Found glibmm-2.4, version 2.50.0 >-- Checking for module 'gtkmm-3.0>=3.16' >-- Found gtkmm-3.0, version 3.22.0 >-- Checking for module 'gio-2.0>=2.44' >-- Found gio-2.0, version 2.51.0 >-- Checking for module 'giomm-2.4>=2.44' >-- Found giomm-2.4, version 2.50.0 >-- Checking for module 'gthread-2.0>=2.44' >-- Found gthread-2.0, version 2.51.0 >-- Checking for module 'gobject-2.0>=2.44' >-- Found gobject-2.0, version 2.51.0 >-- Checking for module 'sigc++-2.0>=2.3.1' >-- Found sigc++-2.0, version 2.10.0 >-- Checking for module 'lcms2>=2.6' >-- Found lcms2, version 2.8 >-- Checking for module 'expat>=2.1' >-- Found expat, version 2.2.0 >-- Checking for module 'fftw3f' >-- Found fftw3f, version 3.3.5 >-- Checking for module 'libiptcdata' >-- Found libiptcdata, version 1.0.4 >-- Found JPEG: /usr/lib64/libjpeg.so >-- Found ZLIB: /usr/lib64/libz.so (found version "1.2.11") >-- Found PNG: /usr/lib64/libpng.so (found version "1.6.28") >-- Found TIFF: /usr/lib64/libtiff.so (found version "4.0.7") >-- Found BZip2: /usr/lib64/libbz2.so (found version "1.0.6") >-- Looking for BZ2_bzCompressInit >-- Looking for BZ2_bzCompressInit - found >-- Checking for module 'libcanberra-gtk3' >-- Found libcanberra-gtk3, version 0.30 >-- Try OpenMP C flag = [-fopenmp] >-- Performing Test OpenMP_FLAG_DETECTED >-- Performing Test OpenMP_FLAG_DETECTED - Success >CMake Warning (dev) at /usr/share/cmake/Modules/FindOpenMP.cmake:179 (if): > if given arguments: > "TRUE" > An argument named "TRUE" appears in a conditional statement. Policy > CMP0012 is not set: if() recognizes numbers and boolean constants. Run > "cmake --help-policy CMP0012" for policy details. Use the cmake_policy > command to set the policy and suppress this warning. >Call Stack (most recent call first): > /usr/share/cmake/Modules/FindOpenMP.cmake:224 (_OPENMP_GET_SPEC_DATE) > CMakeLists.txt:298 (find_package) >This warning is for project developers. Use -Wno-dev to suppress it. >-- Try OpenMP CXX flag = [-fopenmp] >-- Performing Test OpenMP_FLAG_DETECTED >-- Performing Test OpenMP_FLAG_DETECTED - Success >CMake Warning (dev) at /usr/share/cmake/Modules/FindOpenMP.cmake:179 (if): > if given arguments: > "TRUE" > An argument named "TRUE" appears in a conditional statement. Policy > CMP0012 is not set: if() recognizes numbers and boolean constants. Run > "cmake --help-policy CMP0012" for policy details. Use the cmake_policy > command to set the policy and suppress this warning. >Call Stack (most recent call first): > /usr/share/cmake/Modules/FindOpenMP.cmake:266 (_OPENMP_GET_SPEC_DATE) > CMakeLists.txt:298 (find_package) >This warning is for project developers. Use -Wno-dev to suppress it. >-- Found OpenMP: -fopenmp >CMake Warning at CMakeLists.txt:310 (message): > You are performing an in-source build. This is discouraged. For an > explanation and the advantages of out-of-source builds, please refer to > http://www.cmake.org/Wiki/CMake_FAQ#What_is_an_.22out-of-source.22_build.3F >-- Configuring done >-- Generating done >CMake Warning: > Manually-specified variables were not used by the project: > AUTOMATED_BUILD_SYSTEM > CMAKE_Fortran_FLAGS_RELEASE > INCLUDE_INSTALL_DIR > LIB_INSTALL_DIR > LIB_SUFFIX > SHARE_INSTALL_PREFIX > SYSCONF_INSTALL_DIR >-- Build files have been written to: /builddir/build/BUILD/RawTherapee-5.0-gtk3 >+ make VERBOSE=1 -j4 >/usr/bin/cmake -H/builddir/build/BUILD/RawTherapee-5.0-gtk3 -B/builddir/build/BUILD/RawTherapee-5.0-gtk3 --check-build-system CMakeFiles/Makefile.cmake 0 >/usr/bin/cmake -E cmake_progress_start /builddir/build/BUILD/RawTherapee-5.0-gtk3/CMakeFiles /builddir/build/BUILD/RawTherapee-5.0-gtk3/CMakeFiles/progress.marks >make -f CMakeFiles/Makefile2 all >make[1]: Entering directory '/builddir/build/BUILD/RawTherapee-5.0-gtk3' >make -f CMakeFiles/AboutFile.dir/build.make CMakeFiles/AboutFile.dir/depend >make[2]: Entering directory '/builddir/build/BUILD/RawTherapee-5.0-gtk3' >cd /builddir/build/BUILD/RawTherapee-5.0-gtk3 && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /builddir/build/BUILD/RawTherapee-5.0-gtk3 /builddir/build/BUILD/RawTherapee-5.0-gtk3 /builddir/build/BUILD/RawTherapee-5.0-gtk3 /builddir/build/BUILD/RawTherapee-5.0-gtk3 /builddir/build/BUILD/RawTherapee-5.0-gtk3/CMakeFiles/AboutFile.dir/DependInfo.cmake --color= >Dependee "/builddir/build/BUILD/RawTherapee-5.0-gtk3/CMakeFiles/AboutFile.dir/DependInfo.cmake" is newer than depender "/builddir/build/BUILD/RawTherapee-5.0-gtk3/CMakeFiles/AboutFile.dir/depend.internal". >Dependee "/builddir/build/BUILD/RawTherapee-5.0-gtk3/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/builddir/build/BUILD/RawTherapee-5.0-gtk3/CMakeFiles/AboutFile.dir/depend.internal". >Scanning dependencies of target AboutFile >make[2]: Leaving directory '/builddir/build/BUILD/RawTherapee-5.0-gtk3' >make -f CMakeFiles/AboutFile.dir/build.make CMakeFiles/AboutFile.dir/build >make[2]: Entering directory '/builddir/build/BUILD/RawTherapee-5.0-gtk3' >[ 0%] Creating the about file >/usr/bin/cmake -DPROJECT_SOURCE_DIR:STRING=/builddir/build/BUILD/RawTherapee-5.0-gtk3 -DCACHE_NAME_SUFFIX:STRING= -DPROC_LABEL:STRING="ppc64le" -DPROC_BIT_DEPTH:STRING="64 bits" -DBUILD_TYPE:STRING=release -DVERSION_SUFFIX:STRING= -DGTKMM_VERSION:STRING=3.22.0 -DOPTION_OMP:STRING=ON -DWITH_MYFILE_MMAP:STRING=ON -DSYSTEM:STRING=Linux -DCXX_FLAGS:STRING=-O2\ -g\ -pipe\ -Wall\ -Werror=format-security\ -Wp,-D_FORTIFY_SOURCE=2\ -fexceptions\ -fstack-protector-strong\ --param=ssp-buffer-size=4\ -grecord-gcc-switches\ -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1\ -m64\ -mcpu=power8\ -mtune=power8\ -std=gnu++11\ \ -Werror=unused-label\ -fopenmp\ -Werror=unknown-pragmas\ -DNDEBUG\ -DLFLAGS:STRING=-Wl,-z,relro\ -specs=/usr/lib/rpm/redhat/redhat-hardened-ld\ \ -DCOMPILER_INFO:STRING=cc\ 7.0.1 -P /builddir/build/BUILD/RawTherapee-5.0-gtk3/AboutThisBuild.cmake >make[2]: Leaving directory '/builddir/build/BUILD/RawTherapee-5.0-gtk3' >[ 0%] Built target AboutFile >make -f rtexif/CMakeFiles/rtexif.dir/build.make rtexif/CMakeFiles/rtexif.dir/depend >make[2]: Entering directory '/builddir/build/BUILD/RawTherapee-5.0-gtk3' >cd /builddir/build/BUILD/RawTherapee-5.0-gtk3 && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /builddir/build/BUILD/RawTherapee-5.0-gtk3 /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif /builddir/build/BUILD/RawTherapee-5.0-gtk3 /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/CMakeFiles/rtexif.dir/DependInfo.cmake --color= >Dependee "/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/CMakeFiles/rtexif.dir/DependInfo.cmake" is newer than depender "/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/CMakeFiles/rtexif.dir/depend.internal". >Dependee "/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/CMakeFiles/rtexif.dir/depend.internal". >Scanning dependencies of target rtexif >make[2]: Leaving directory '/builddir/build/BUILD/RawTherapee-5.0-gtk3' >make -f rtexif/CMakeFiles/rtexif.dir/build.make rtexif/CMakeFiles/rtexif.dir/build >make[2]: Entering directory '/builddir/build/BUILD/RawTherapee-5.0-gtk3' >[ 0%] Building CXX object rtexif/CMakeFiles/rtexif.dir/stdattribs.cc.o >[ 1%] Building CXX object rtexif/CMakeFiles/rtexif.dir/rtexif.cc.o >[ 2%] Building CXX object rtexif/CMakeFiles/rtexif.dir/nikonattribs.cc.o >cd /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif && /usr/bin/c++ -DAUTO_GDK_FLUSH=0 -DBZIP_SUPPORT -DMYFILE_MMAP -DNDEBUG -DSTRICT_MUTEX=1 -DTRACE_MYRWMUTEX=0 -D_DNDEBUG -Drtexif_EXPORTS -I/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/glibmm-2.4 -I/usr/lib64/glibmm-2.4/include -I/usr/include/sigc++-2.0 -I/usr/lib64/sigc++-2.0/include -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/libdrm -I/usr/include/harfbuzz -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gio-unix-2.0 -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -I/usr/include/gtkmm-3.0 -I/usr/lib64/gtkmm-3.0/include -I/usr/include/atkmm-1.6 -I/usr/include/giomm-2.4 -I/usr/lib64/giomm-2.4/include -I/usr/include/pangomm-1.4 -I/usr/lib64/pangomm-1.4/include -I/usr/include/cairomm-1.0 -I/usr/lib64/cairomm-1.0/include -I/usr/include/gtk-3.0/unix-print -I/usr/include/gdkmm-3.0 -I/usr/lib64/gdkmm-3.0/include -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8 -std=gnu++11 -Werror=unused-label -fopenmp -Werror=unknown-pragmas -DNDEBUG -fPIC -ffast-math -fexpensive-optimizations -fPIC -o CMakeFiles/rtexif.dir/rtexif.cc.o -c /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc >cd /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif && /usr/bin/c++ -DAUTO_GDK_FLUSH=0 -DBZIP_SUPPORT -DMYFILE_MMAP -DNDEBUG -DSTRICT_MUTEX=1 -DTRACE_MYRWMUTEX=0 -D_DNDEBUG -Drtexif_EXPORTS -I/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/glibmm-2.4 -I/usr/lib64/glibmm-2.4/include -I/usr/include/sigc++-2.0 -I/usr/lib64/sigc++-2.0/include -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/libdrm -I/usr/include/harfbuzz -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gio-unix-2.0 -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -I/usr/include/gtkmm-3.0 -I/usr/lib64/gtkmm-3.0/include -I/usr/include/atkmm-1.6 -I/usr/include/giomm-2.4 -I/usr/lib64/giomm-2.4/include -I/usr/include/pangomm-1.4 -I/usr/lib64/pangomm-1.4/include -I/usr/include/cairomm-1.0 -I/usr/lib64/cairomm-1.0/include -I/usr/include/gtk-3.0/unix-print -I/usr/include/gdkmm-3.0 -I/usr/lib64/gdkmm-3.0/include -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8 -std=gnu++11 -Werror=unused-label -fopenmp -Werror=unknown-pragmas -DNDEBUG -fPIC -ffast-math -fexpensive-optimizations -fPIC -o CMakeFiles/rtexif.dir/stdattribs.cc.o -c /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/stdattribs.cc >cd /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif && /usr/bin/c++ -DAUTO_GDK_FLUSH=0 -DBZIP_SUPPORT -DMYFILE_MMAP -DNDEBUG -DSTRICT_MUTEX=1 -DTRACE_MYRWMUTEX=0 -D_DNDEBUG -Drtexif_EXPORTS -I/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/glibmm-2.4 -I/usr/lib64/glibmm-2.4/include -I/usr/include/sigc++-2.0 -I/usr/lib64/sigc++-2.0/include -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/libdrm -I/usr/include/harfbuzz -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gio-unix-2.0 -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -I/usr/include/gtkmm-3.0 -I/usr/lib64/gtkmm-3.0/include -I/usr/include/atkmm-1.6 -I/usr/include/giomm-2.4 -I/usr/lib64/giomm-2.4/include -I/usr/include/pangomm-1.4 -I/usr/lib64/pangomm-1.4/include -I/usr/include/cairomm-1.0 -I/usr/lib64/cairomm-1.0/include -I/usr/include/gtk-3.0/unix-print -I/usr/include/gdkmm-3.0 -I/usr/lib64/gdkmm-3.0/include -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8 -std=gnu++11 -Werror=unused-label -fopenmp -Werror=unknown-pragmas -DNDEBUG -fPIC -ffast-math -fexpensive-optimizations -fPIC -o CMakeFiles/rtexif.dir/nikonattribs.cc.o -c /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/nikonattribs.cc >[ 2%] Building CXX object rtexif/CMakeFiles/rtexif.dir/canonattribs.cc.o >cd /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif && /usr/bin/c++ -DAUTO_GDK_FLUSH=0 -DBZIP_SUPPORT -DMYFILE_MMAP -DNDEBUG -DSTRICT_MUTEX=1 -DTRACE_MYRWMUTEX=0 -D_DNDEBUG -Drtexif_EXPORTS -I/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/glibmm-2.4 -I/usr/lib64/glibmm-2.4/include -I/usr/include/sigc++-2.0 -I/usr/lib64/sigc++-2.0/include -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/libdrm -I/usr/include/harfbuzz -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gio-unix-2.0 -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -I/usr/include/gtkmm-3.0 -I/usr/lib64/gtkmm-3.0/include -I/usr/include/atkmm-1.6 -I/usr/include/giomm-2.4 -I/usr/lib64/giomm-2.4/include -I/usr/include/pangomm-1.4 -I/usr/lib64/pangomm-1.4/include -I/usr/include/cairomm-1.0 -I/usr/lib64/cairomm-1.0/include -I/usr/include/gtk-3.0/unix-print -I/usr/include/gdkmm-3.0 -I/usr/lib64/gdkmm-3.0/include -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8 -std=gnu++11 -Werror=unused-label -fopenmp -Werror=unknown-pragmas -DNDEBUG -fPIC -ffast-math -fexpensive-optimizations -fPIC -o CMakeFiles/rtexif.dir/canonattribs.cc.o -c /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/canonattribs.cc >In file included from /usr/include/glibmm-2.4/glibmm/containerhandle_shared.h:24:0, > from /usr/include/glibmm-2.4/glibmm/arrayhandle.h:23, > from /usr/include/glibmm-2.4/glibmm.h:93, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.h:30, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/nikonattribs.cc:27: >/usr/include/glibmm-2.4/glibmm/variant.h:596:55: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > static V_CastTo cast_dynamic(const VariantBase& v) throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:643:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast) > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:899:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1082:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1139:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >In file included from /usr/include/glibmm-2.4/glibmm/containerhandle_shared.h:24:0, > from /usr/include/glibmm-2.4/glibmm/arrayhandle.h:23, > from /usr/include/glibmm-2.4/glibmm.h:93, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.h:30, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/stdattribs.cc:26: >/usr/include/glibmm-2.4/glibmm/variant.h:596:55: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > static V_CastTo cast_dynamic(const VariantBase& v) throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:643:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast) > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:899:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1082:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1139:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >In file included from /usr/include/glibmm-2.4/glibmm/containerhandle_shared.h:24:0, > from /usr/include/glibmm-2.4/glibmm/arrayhandle.h:23, > from /usr/include/glibmm-2.4/glibmm.h:93, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.h:30, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/canonattribs.cc:25: >/usr/include/glibmm-2.4/glibmm/variant.h:596:55: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > static V_CastTo cast_dynamic(const VariantBase& v) throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:643:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast) > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:899:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1082:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1139:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >In file included from /usr/include/glibmm-2.4/glibmm/containerhandle_shared.h:24:0, > from /usr/include/glibmm-2.4/glibmm/arrayhandle.h:23, > from /usr/include/glibmm-2.4/glibmm.h:93, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.h:30, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:30: >/usr/include/glibmm-2.4/glibmm/variant.h:596:55: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > static V_CastTo cast_dynamic(const VariantBase& v) throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:643:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast) > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:899:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1082:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1139:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc: In function 'short unsigned int rtexif::get2(FILE*, rtexif::ByteOrder)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:2998:11: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (str, 1, 2, f); > ~~~~~~^~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc: In constructor 'rtexif::TagDirectoryTable::TagDirectoryTable(rtexif::TagDirectory*, FILE*, int, int, rtexif::TagType, const rtexif::TagAttrib*, rtexif::ByteOrder)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:720:11: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (values, 1, valuesSize, f); > ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc: In constructor 'rtexif::Tag::Tag(rtexif::TagDirectory*, FILE*, int)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:815:19: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (buffer, 1, 14, f ); > ~~~~~~^~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:830:19: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (buffer, 1, 2, f); > ~~~~~~^~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:1060:15: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (value, 1, valuesize, f); > ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:1071:11: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (value, 1, valuesize, f); > ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc: In function 'int rtexif::get4(FILE*, rtexif::ByteOrder)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:3006:11: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (str, 1, 4, f); > ~~~~~~^~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc: In member function 'bool rtexif::Tag::parseMakerNote(FILE*, int, rtexif::ByteOrder)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:1123:19: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (value, 1, 8, f); > ~~~~~~^~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:1139:19: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (value, 1, 18, f); > ~~~~~~^~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:1159:15: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (value, 1, 6, f); > ~~~~~~^~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:1167:15: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (value, 1, 10, f); > ~~~~~~^~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:1175:15: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (value, 1, 12, f); > ~~~~~~^~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:1187:15: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (value, 1, 12, f); > ~~~~~~^~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:1203:15: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (value, 1, 8, f); > ~~~~~~^~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:1209:19: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (value + 8, 1, 4, f); > ~~~~~~^~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc: In static member function 'static rtexif::Tag* rtexif::ExifManager::saveCIFFMNTag(FILE*, rtexif::TagDirectory*, int, const char*)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:1890:11: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (data, len, 1, f); > ~~~~~~^~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc: In static member function 'static void rtexif::ExifManager::parseCIFF(FILE*, int, int, rtexif::TagDirectory*)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:1939:19: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (buffer, 64, 1, f); > ~~~~~~^~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:1946:19: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (buffer, 64, 1, f); > ~~~~~~^~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:1951:19: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (buffer, 64, 1, f); > ~~~~~~^~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc: In static member function 'static rtexif::TagDirectory* rtexif::ExifManager::parse(FILE*, int, bool)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:2506:11: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (&bo, 1, 2, f); > ~~~~~~^~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc: In static member function 'static rtexif::TagDirectory* rtexif::ExifManager::parseJPEG(FILE*)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.cc:2758:11: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (&c, 1, 1, f); > ~~~~~~^~~~~~~~~~~~~ >[ 3%] Building CXX object rtexif/CMakeFiles/rtexif.dir/pentaxattribs.cc.o >cd /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif && /usr/bin/c++ -DAUTO_GDK_FLUSH=0 -DBZIP_SUPPORT -DMYFILE_MMAP -DNDEBUG -DSTRICT_MUTEX=1 -DTRACE_MYRWMUTEX=0 -D_DNDEBUG -Drtexif_EXPORTS -I/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/glibmm-2.4 -I/usr/lib64/glibmm-2.4/include -I/usr/include/sigc++-2.0 -I/usr/lib64/sigc++-2.0/include -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/libdrm -I/usr/include/harfbuzz -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gio-unix-2.0 -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -I/usr/include/gtkmm-3.0 -I/usr/lib64/gtkmm-3.0/include -I/usr/include/atkmm-1.6 -I/usr/include/giomm-2.4 -I/usr/lib64/giomm-2.4/include -I/usr/include/pangomm-1.4 -I/usr/lib64/pangomm-1.4/include -I/usr/include/cairomm-1.0 -I/usr/lib64/cairomm-1.0/include -I/usr/include/gtk-3.0/unix-print -I/usr/include/gdkmm-3.0 -I/usr/lib64/gdkmm-3.0/include -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8 -std=gnu++11 -Werror=unused-label -fopenmp -Werror=unknown-pragmas -DNDEBUG -fPIC -ffast-math -fexpensive-optimizations -fPIC -o CMakeFiles/rtexif.dir/pentaxattribs.cc.o -c /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/pentaxattribs.cc >[ 3%] Building CXX object rtexif/CMakeFiles/rtexif.dir/fujiattribs.cc.o >cd /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif && /usr/bin/c++ -DAUTO_GDK_FLUSH=0 -DBZIP_SUPPORT -DMYFILE_MMAP -DNDEBUG -DSTRICT_MUTEX=1 -DTRACE_MYRWMUTEX=0 -D_DNDEBUG -Drtexif_EXPORTS -I/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/glibmm-2.4 -I/usr/lib64/glibmm-2.4/include -I/usr/include/sigc++-2.0 -I/usr/lib64/sigc++-2.0/include -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/libdrm -I/usr/include/harfbuzz -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gio-unix-2.0 -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -I/usr/include/gtkmm-3.0 -I/usr/lib64/gtkmm-3.0/include -I/usr/include/atkmm-1.6 -I/usr/include/giomm-2.4 -I/usr/lib64/giomm-2.4/include -I/usr/include/pangomm-1.4 -I/usr/lib64/pangomm-1.4/include -I/usr/include/cairomm-1.0 -I/usr/lib64/cairomm-1.0/include -I/usr/include/gtk-3.0/unix-print -I/usr/include/gdkmm-3.0 -I/usr/lib64/gdkmm-3.0/include -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8 -std=gnu++11 -Werror=unused-label -fopenmp -Werror=unknown-pragmas -DNDEBUG -fPIC -ffast-math -fexpensive-optimizations -fPIC -o CMakeFiles/rtexif.dir/fujiattribs.cc.o -c /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/fujiattribs.cc >In file included from /usr/include/glibmm-2.4/glibmm/containerhandle_shared.h:24:0, > from /usr/include/glibmm-2.4/glibmm/arrayhandle.h:23, > from /usr/include/glibmm-2.4/glibmm.h:93, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.h:30, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/pentaxattribs.cc:28: >/usr/include/glibmm-2.4/glibmm/variant.h:596:55: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > static V_CastTo cast_dynamic(const VariantBase& v) throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:643:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast) > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:899:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1082:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1139:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >In file included from /usr/include/glibmm-2.4/glibmm/containerhandle_shared.h:24:0, > from /usr/include/glibmm-2.4/glibmm/arrayhandle.h:23, > from /usr/include/glibmm-2.4/glibmm.h:93, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.h:30, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/fujiattribs.cc:22: >/usr/include/glibmm-2.4/glibmm/variant.h:596:55: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > static V_CastTo cast_dynamic(const VariantBase& v) throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:643:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast) > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:899:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1082:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1139:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >[ 3%] Building CXX object rtexif/CMakeFiles/rtexif.dir/sonyminoltaattribs.cc.o >cd /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif && /usr/bin/c++ -DAUTO_GDK_FLUSH=0 -DBZIP_SUPPORT -DMYFILE_MMAP -DNDEBUG -DSTRICT_MUTEX=1 -DTRACE_MYRWMUTEX=0 -D_DNDEBUG -Drtexif_EXPORTS -I/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/glibmm-2.4 -I/usr/lib64/glibmm-2.4/include -I/usr/include/sigc++-2.0 -I/usr/lib64/sigc++-2.0/include -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/libdrm -I/usr/include/harfbuzz -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gio-unix-2.0 -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -I/usr/include/gtkmm-3.0 -I/usr/lib64/gtkmm-3.0/include -I/usr/include/atkmm-1.6 -I/usr/include/giomm-2.4 -I/usr/lib64/giomm-2.4/include -I/usr/include/pangomm-1.4 -I/usr/lib64/pangomm-1.4/include -I/usr/include/cairomm-1.0 -I/usr/lib64/cairomm-1.0/include -I/usr/include/gtk-3.0/unix-print -I/usr/include/gdkmm-3.0 -I/usr/lib64/gdkmm-3.0/include -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8 -std=gnu++11 -Werror=unused-label -fopenmp -Werror=unknown-pragmas -DNDEBUG -fPIC -ffast-math -fexpensive-optimizations -fPIC -o CMakeFiles/rtexif.dir/sonyminoltaattribs.cc.o -c /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/sonyminoltaattribs.cc >[ 4%] Building CXX object rtexif/CMakeFiles/rtexif.dir/olympusattribs.cc.o >cd /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif && /usr/bin/c++ -DAUTO_GDK_FLUSH=0 -DBZIP_SUPPORT -DMYFILE_MMAP -DNDEBUG -DSTRICT_MUTEX=1 -DTRACE_MYRWMUTEX=0 -D_DNDEBUG -Drtexif_EXPORTS -I/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/glibmm-2.4 -I/usr/lib64/glibmm-2.4/include -I/usr/include/sigc++-2.0 -I/usr/lib64/sigc++-2.0/include -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/libdrm -I/usr/include/harfbuzz -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gio-unix-2.0 -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -I/usr/include/gtkmm-3.0 -I/usr/lib64/gtkmm-3.0/include -I/usr/include/atkmm-1.6 -I/usr/include/giomm-2.4 -I/usr/lib64/giomm-2.4/include -I/usr/include/pangomm-1.4 -I/usr/lib64/pangomm-1.4/include -I/usr/include/cairomm-1.0 -I/usr/lib64/cairomm-1.0/include -I/usr/include/gtk-3.0/unix-print -I/usr/include/gdkmm-3.0 -I/usr/lib64/gdkmm-3.0/include -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8 -std=gnu++11 -Werror=unused-label -fopenmp -Werror=unknown-pragmas -DNDEBUG -fPIC -ffast-math -fexpensive-optimizations -fPIC -o CMakeFiles/rtexif.dir/olympusattribs.cc.o -c /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/olympusattribs.cc >In file included from /usr/include/glibmm-2.4/glibmm/containerhandle_shared.h:24:0, > from /usr/include/glibmm-2.4/glibmm/arrayhandle.h:23, > from /usr/include/glibmm-2.4/glibmm.h:93, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.h:30, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/sonyminoltaattribs.cc:23: >/usr/include/glibmm-2.4/glibmm/variant.h:596:55: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > static V_CastTo cast_dynamic(const VariantBase& v) throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:643:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast) > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:899:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1082:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1139:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >In file included from /usr/include/glibmm-2.4/glibmm/containerhandle_shared.h:24:0, > from /usr/include/glibmm-2.4/glibmm/arrayhandle.h:23, > from /usr/include/glibmm-2.4/glibmm.h:93, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.h:30, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/olympusattribs.cc:27: >/usr/include/glibmm-2.4/glibmm/variant.h:596:55: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > static V_CastTo cast_dynamic(const VariantBase& v) throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:643:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast) > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:899:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1082:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1139:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >[ 4%] Building CXX object rtexif/CMakeFiles/rtexif.dir/kodakattribs.cc.o >cd /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif && /usr/bin/c++ -DAUTO_GDK_FLUSH=0 -DBZIP_SUPPORT -DMYFILE_MMAP -DNDEBUG -DSTRICT_MUTEX=1 -DTRACE_MYRWMUTEX=0 -D_DNDEBUG -Drtexif_EXPORTS -I/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/glibmm-2.4 -I/usr/lib64/glibmm-2.4/include -I/usr/include/sigc++-2.0 -I/usr/lib64/sigc++-2.0/include -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/libdrm -I/usr/include/harfbuzz -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gio-unix-2.0 -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -I/usr/include/gtkmm-3.0 -I/usr/lib64/gtkmm-3.0/include -I/usr/include/atkmm-1.6 -I/usr/include/giomm-2.4 -I/usr/lib64/giomm-2.4/include -I/usr/include/pangomm-1.4 -I/usr/lib64/pangomm-1.4/include -I/usr/include/cairomm-1.0 -I/usr/lib64/cairomm-1.0/include -I/usr/include/gtk-3.0/unix-print -I/usr/include/gdkmm-3.0 -I/usr/lib64/gdkmm-3.0/include -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8 -std=gnu++11 -Werror=unused-label -fopenmp -Werror=unknown-pragmas -DNDEBUG -fPIC -ffast-math -fexpensive-optimizations -fPIC -o CMakeFiles/rtexif.dir/kodakattribs.cc.o -c /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/kodakattribs.cc >In file included from /usr/include/glibmm-2.4/glibmm/containerhandle_shared.h:24:0, > from /usr/include/glibmm-2.4/glibmm/arrayhandle.h:23, > from /usr/include/glibmm-2.4/glibmm.h:93, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/rtexif.h:30, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/kodakattribs.cc:8: >/usr/include/glibmm-2.4/glibmm/variant.h:596:55: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > static V_CastTo cast_dynamic(const VariantBase& v) throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:643:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast) > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:899:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1082:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1139:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/kodakattribs.cc: In function 'void rtexif::parseKodakIfdTextualInfo(rtexif::Tag*, rtexif::Tag*)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif/kodakattribs.cc:23:9: warning: unused variable 'valuesize' [-Wunused-variable] > int valuesize = textualInfo->getValueSize(); > ^~~~~~~~~ >[ 5%] Linking CXX shared library librtexif.so >cd /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtexif && /usr/bin/cmake -E cmake_link_script CMakeFiles/rtexif.dir/link.txt --verbose=1 >/usr/bin/c++ -fPIC -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8 -std=gnu++11 -Werror=unused-label -fopenmp -Werror=unknown-pragmas -DNDEBUG -Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -shared -Wl,-soname,librtexif.so -o librtexif.so CMakeFiles/rtexif.dir/rtexif.cc.o CMakeFiles/rtexif.dir/stdattribs.cc.o CMakeFiles/rtexif.dir/nikonattribs.cc.o CMakeFiles/rtexif.dir/canonattribs.cc.o CMakeFiles/rtexif.dir/pentaxattribs.cc.o CMakeFiles/rtexif.dir/fujiattribs.cc.o CMakeFiles/rtexif.dir/sonyminoltaattribs.cc.o CMakeFiles/rtexif.dir/olympusattribs.cc.o CMakeFiles/rtexif.dir/kodakattribs.cc.o >make[2]: Leaving directory '/builddir/build/BUILD/RawTherapee-5.0-gtk3' >[ 5%] Built target rtexif >make -f rtengine/CMakeFiles/rtengine.dir/build.make rtengine/CMakeFiles/rtengine.dir/depend >make[2]: Entering directory '/builddir/build/BUILD/RawTherapee-5.0-gtk3' >cd /builddir/build/BUILD/RawTherapee-5.0-gtk3 && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /builddir/build/BUILD/RawTherapee-5.0-gtk3 /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine /builddir/build/BUILD/RawTherapee-5.0-gtk3 /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/CMakeFiles/rtengine.dir/DependInfo.cmake --color= >Dependee "/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/CMakeFiles/rtengine.dir/DependInfo.cmake" is newer than depender "/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/CMakeFiles/rtengine.dir/depend.internal". >Dependee "/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/CMakeFiles/rtengine.dir/depend.internal". >Scanning dependencies of target rtengine >make[2]: Leaving directory '/builddir/build/BUILD/RawTherapee-5.0-gtk3' >make -f rtengine/CMakeFiles/rtengine.dir/build.make rtengine/CMakeFiles/rtengine.dir/build >make[2]: Entering directory '/builddir/build/BUILD/RawTherapee-5.0-gtk3' >[ 5%] Building CXX object rtengine/CMakeFiles/rtengine.dir/colortemp.cc.o >cd /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine && /usr/bin/c++ -DAUTO_GDK_FLUSH=0 -DBZIP_SUPPORT -DMYFILE_MMAP -DNDEBUG -DSTRICT_MUTEX=1 -DTRACE_MYRWMUTEX=0 -D_DNDEBUG -Drtengine_EXPORTS -I/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/glibmm-2.4 -I/usr/lib64/glibmm-2.4/include -I/usr/include/sigc++-2.0 -I/usr/lib64/sigc++-2.0/include -I/usr/include/libiptcdata -I/usr/include/gtkmm-3.0 -I/usr/lib64/gtkmm-3.0/include -I/usr/include/atkmm-1.6 -I/usr/include/atk-1.0 -I/usr/include/giomm-2.4 -I/usr/lib64/giomm-2.4/include -I/usr/include/pangomm-1.4 -I/usr/lib64/pangomm-1.4/include -I/usr/include/cairomm-1.0 -I/usr/lib64/cairomm-1.0/include -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/libdrm -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/gtk-3.0 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gio-unix-2.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -I/usr/include/gtk-3.0/unix-print -I/usr/include/gdkmm-3.0 -I/usr/lib64/gdkmm-3.0/include -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8 -std=gnu++11 -Werror=unused-label -fopenmp -Werror=unknown-pragmas -DNDEBUG -fPIC -o CMakeFiles/rtengine.dir/colortemp.cc.o -c /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/colortemp.cc >[ 6%] Building CXX object rtengine/CMakeFiles/rtengine.dir/curves.cc.o >cd /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine && /usr/bin/c++ -DAUTO_GDK_FLUSH=0 -DBZIP_SUPPORT -DMYFILE_MMAP -DNDEBUG -DSTRICT_MUTEX=1 -DTRACE_MYRWMUTEX=0 -D_DNDEBUG -Drtengine_EXPORTS -I/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/glibmm-2.4 -I/usr/lib64/glibmm-2.4/include -I/usr/include/sigc++-2.0 -I/usr/lib64/sigc++-2.0/include -I/usr/include/libiptcdata -I/usr/include/gtkmm-3.0 -I/usr/lib64/gtkmm-3.0/include -I/usr/include/atkmm-1.6 -I/usr/include/atk-1.0 -I/usr/include/giomm-2.4 -I/usr/lib64/giomm-2.4/include -I/usr/include/pangomm-1.4 -I/usr/lib64/pangomm-1.4/include -I/usr/include/cairomm-1.0 -I/usr/lib64/cairomm-1.0/include -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/libdrm -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/gtk-3.0 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gio-unix-2.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -I/usr/include/gtk-3.0/unix-print -I/usr/include/gdkmm-3.0 -I/usr/lib64/gdkmm-3.0/include -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8 -std=gnu++11 -Werror=unused-label -fopenmp -Werror=unknown-pragmas -DNDEBUG -fPIC -o CMakeFiles/rtengine.dir/curves.cc.o -c /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.cc >[ 6%] Building CXX object rtengine/CMakeFiles/rtengine.dir/flatcurves.cc.o >[ 7%] Building CXX object rtengine/CMakeFiles/rtengine.dir/diagonalcurves.cc.o >cd /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine && /usr/bin/c++ -DAUTO_GDK_FLUSH=0 -DBZIP_SUPPORT -DMYFILE_MMAP -DNDEBUG -DSTRICT_MUTEX=1 -DTRACE_MYRWMUTEX=0 -D_DNDEBUG -Drtengine_EXPORTS -I/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/glibmm-2.4 -I/usr/lib64/glibmm-2.4/include -I/usr/include/sigc++-2.0 -I/usr/lib64/sigc++-2.0/include -I/usr/include/libiptcdata -I/usr/include/gtkmm-3.0 -I/usr/lib64/gtkmm-3.0/include -I/usr/include/atkmm-1.6 -I/usr/include/atk-1.0 -I/usr/include/giomm-2.4 -I/usr/lib64/giomm-2.4/include -I/usr/include/pangomm-1.4 -I/usr/lib64/pangomm-1.4/include -I/usr/include/cairomm-1.0 -I/usr/lib64/cairomm-1.0/include -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/libdrm -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/gtk-3.0 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gio-unix-2.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -I/usr/include/gtk-3.0/unix-print -I/usr/include/gdkmm-3.0 -I/usr/lib64/gdkmm-3.0/include -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8 -std=gnu++11 -Werror=unused-label -fopenmp -Werror=unknown-pragmas -DNDEBUG -fPIC -o CMakeFiles/rtengine.dir/flatcurves.cc.o -c /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/flatcurves.cc >cd /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine && /usr/bin/c++ -DAUTO_GDK_FLUSH=0 -DBZIP_SUPPORT -DMYFILE_MMAP -DNDEBUG -DSTRICT_MUTEX=1 -DTRACE_MYRWMUTEX=0 -D_DNDEBUG -Drtengine_EXPORTS -I/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/glibmm-2.4 -I/usr/lib64/glibmm-2.4/include -I/usr/include/sigc++-2.0 -I/usr/lib64/sigc++-2.0/include -I/usr/include/libiptcdata -I/usr/include/gtkmm-3.0 -I/usr/lib64/gtkmm-3.0/include -I/usr/include/atkmm-1.6 -I/usr/include/atk-1.0 -I/usr/include/giomm-2.4 -I/usr/lib64/giomm-2.4/include -I/usr/include/pangomm-1.4 -I/usr/lib64/pangomm-1.4/include -I/usr/include/cairomm-1.0 -I/usr/lib64/cairomm-1.0/include -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/libdrm -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/gtk-3.0 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gio-unix-2.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -I/usr/include/gtk-3.0/unix-print -I/usr/include/gdkmm-3.0 -I/usr/lib64/gdkmm-3.0/include -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8 -std=gnu++11 -Werror=unused-label -fopenmp -Werror=unknown-pragmas -DNDEBUG -fPIC -o CMakeFiles/rtengine.dir/diagonalcurves.cc.o -c /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/diagonalcurves.cc >In file included from /usr/include/glibmm-2.4/glibmm/containerhandle_shared.h:24:0, > from /usr/include/glibmm-2.4/glibmm/arrayhandle.h:23, > from /usr/include/glibmm-2.4/glibmm.h:93, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/colortemp.h:22, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/colortemp.cc:19: >/usr/include/glibmm-2.4/glibmm/variant.h:596:55: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > static V_CastTo cast_dynamic(const VariantBase& v) throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:643:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast) > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:899:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1082:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1139:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >In file included from /usr/include/glibmm-2.4/glibmm/containerhandle_shared.h:24:0, > from /usr/include/glibmm-2.4/glibmm/arrayhandle.h:23, > from /usr/include/glibmm-2.4/glibmm.h:93, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.h:22, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/flatcurves.cc:19: >/usr/include/glibmm-2.4/glibmm/variant.h:596:55: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > static V_CastTo cast_dynamic(const VariantBase& v) throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:643:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast) > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:899:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1082:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1139:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >In file included from /usr/include/glibmm-2.4/glibmm/containerhandle_shared.h:24:0, > from /usr/include/glibmm-2.4/glibmm/arrayhandle.h:23, > from /usr/include/glibmm-2.4/glibmm.h:93, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.h:22, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/diagonalcurves.cc:21: >/usr/include/glibmm-2.4/glibmm/variant.h:596:55: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > static V_CastTo cast_dynamic(const VariantBase& v) throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:643:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast) > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:899:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1082:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1139:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >In file included from /usr/include/glibmm-2.4/glibmm/containerhandle_shared.h:24:0, > from /usr/include/glibmm-2.4/glibmm/arrayhandle.h:23, > from /usr/include/glibmm-2.4/glibmm.h:93, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.h:22, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.cc:35: >/usr/include/glibmm-2.4/glibmm/variant.h:596:55: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > static V_CastTo cast_dynamic(const VariantBase& v) throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:643:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast) > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:899:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1082:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1139:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >[ 7%] Building CXX object rtengine/CMakeFiles/rtengine.dir/dcraw.cc.o >cd /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine && /usr/bin/c++ -DAUTO_GDK_FLUSH=0 -DBZIP_SUPPORT -DMYFILE_MMAP -DNDEBUG -DSTRICT_MUTEX=1 -DTRACE_MYRWMUTEX=0 -D_DNDEBUG -Drtengine_EXPORTS -I/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/glibmm-2.4 -I/usr/lib64/glibmm-2.4/include -I/usr/include/sigc++-2.0 -I/usr/lib64/sigc++-2.0/include -I/usr/include/libiptcdata -I/usr/include/gtkmm-3.0 -I/usr/lib64/gtkmm-3.0/include -I/usr/include/atkmm-1.6 -I/usr/include/atk-1.0 -I/usr/include/giomm-2.4 -I/usr/lib64/giomm-2.4/include -I/usr/include/pangomm-1.4 -I/usr/lib64/pangomm-1.4/include -I/usr/include/cairomm-1.0 -I/usr/lib64/cairomm-1.0/include -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/libdrm -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/gtk-3.0 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gio-unix-2.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -I/usr/include/gtk-3.0/unix-print -I/usr/include/gdkmm-3.0 -I/usr/lib64/gdkmm-3.0/include -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8 -std=gnu++11 -Werror=unused-label -fopenmp -Werror=unknown-pragmas -DNDEBUG -fPIC -o CMakeFiles/rtengine.dir/dcraw.cc.o -c /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc >In file included from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.cc:35:0: >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.h: In constructor 'rtengine::Curve::Curve()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.h:350:9: warning: 'rtengine::Curve::nbr_points' will be initialized after [-Wreorder] > int nbr_points; > ^~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.h:342:20: warning: 'short unsigned int rtengine::Curve::hashSize' [-Wreorder] > unsigned short hashSize; // hash table's size, between [10, 100, 1000] > ^~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.cc:48:1: warning: when initialized here [-Wreorder] > Curve::Curve () : N(0), ppn(0), x(nullptr), y(nullptr), mc(0.0), mfc(0.0), msc(0.0), mhc(0.0), ypp(nullptr), x1(0.0), y1(0.0), x2(0.0), y2(0.0), x3(0.0), y3(0.0), firstPointIncluded(false), increment(0.0), nbr_points(0), hashSize(1000 /* has to be initialized to the maximum value */) {} > ^~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.cc: In member function 'void rtengine::Curve::fillHash()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.cc:107:32: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (unsigned int i = 0; i < (hashSize + 1);) { > ~~^~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.cc: In static member function 'static float rtengine::PerceptualToneCurve::get_curve_val(float, float*, float*, size_t)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.cc:1768:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if (idx >= lut_size - 1) { > ~~~~^~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.cc: In member function 'float rtengine::PerceptualToneCurve::calculateToneCurveContrastValue() const': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.cc:1793:27: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (int i = 0; i < sizeof(tx) / sizeof(tx[0]); i++) { > ~~^~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.cc:1810:31: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (int i = 0; i < sizeof(tx) / sizeof(tx[0]); i++) { > ~~^~~~~~~~~~~~~~~~~~~~~~ >In file included from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.cc:34:0: >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/LUT.h: In instantiation of 'void LUT<T>::compressTo(LUT<T>&, unsigned int, const LUT<float>&) const [with U = unsigned int; <template-parameter-2-2> = void; T = unsigned int]': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.cc:931:75: required from here >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/LUT.h:582:31: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (int i = 0; i < numVals; i++) { > ~~^~~~~~~~~ >In file included from /usr/include/glibmm-2.4/glibmm/containerhandle_shared.h:24:0, > from /usr/include/glibmm-2.4/glibmm/arrayhandle.h:23, > from /usr/include/glibmm-2.4/glibmm.h:93, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/procparams.h:27, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/rtengine.h:23, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/myfile.h:25, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.h:23, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:108: >/usr/include/glibmm-2.4/glibmm/variant.h:596:55: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > static V_CastTo cast_dynamic(const VariantBase& v) throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:643:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast) > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:899:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1082:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1139:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'unsigned int DCraw::getbithuff_t::operator()(int, DCraw::UshORt*)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:565:54: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > while (!reset && vbits < nbits && (c = fgetc(ifp)) != EOF && > ^ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'int DCraw::canon_has_lowbits()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:708:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (i=540; i < sizeof test - 1; i++) > ~~^~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::canon_sraw_load_raw()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:984:8: warning: suggest explicit braces to avoid ambiguous 'else' [-Wdangling-else] > if (row & (jh.sraw >> 1)) > ^ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::adobe_copy_pixel(unsigned int, unsigned int, DCraw::UshORt**)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:124:31: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > #define FORC(cnt) for (c=0; c < cnt; c++) > ~~^~~~~~~~~~~ > #define FORC3 FORC(3) > ~~~~~~~~~~~~~~~~~~~~~ > #define FORC4 FORC(4) > ~~~~~~~~~~~~~~~~~~~~~ > #define FORCC FORC(colors) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > #define SQR(x) rtengine::SQR(x) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define MIN(a,b) rtengine::min(a,static_cast<__typeof__(a)>(b)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define MAX(a,b) rtengine::max(a,static_cast<__typeof__(a)>(b)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define LIM(x,min,max) rtengine::LIM(x,static_cast<__typeof__(x)>(min),static_cast<__typeof__(x)>(max)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define ULIM(x,y,z) rtengine::median(x,static_cast<__typeof__(x)>(y),static_cast<__typeof__(x)>(z)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define CLIP(x) rtengine::CLIP(x) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; } > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > /* > ~~ > In order to inline this calculation, I make the risky > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > assumption that all filter patterns can be described > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > by a repeating pattern of eight rows and two columns > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > Do not use the FC or BAYER macros with the Leaf CatchLight, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > because its pattern is 16x16, not 2x8. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4: > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0 G M G M G M 0 C Y C Y C Y 0 Y C Y C Y C 0 G M G M G M > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 1 C Y C Y C Y 1 M G M G M G 1 M G M G M G 1 Y C Y C Y C > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 3 C Y C Y C Y 3 G M G M G M 3 G M G M G M > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 4 C Y C Y C Y 4 Y C Y C Y C > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > PowerShot A5 5 G M G M G M 5 G M G M G M > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 7 M G M G M G 7 M G M G M G > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0 1 2 3 4 5 > ~~~~~~~~~~~ > 0 C Y C Y C Y > ~~~~~~~~~~~~~ > 1 G M G M G M > ~~~~~~~~~~~~~ > 2 C Y C Y C Y > ~~~~~~~~~~~~~ > 3 M G M G M G > ~~~~~~~~~~~~~ > > > All RGB cameras use one of these Bayer grids: > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > 0x16161616: 0x61616161: 0x49494949: 0x94949494: > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0 B G B G B G 0 G R G R G R 0 G B G B G B 0 R G R G R G > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 1 G R G R G R 1 B G B G B G 1 R G R G R G 1 G B G B G B > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 2 B G B G B G 2 G R G R G R 2 G B G B G B 2 R G R G R G > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 3 G R G R G R 3 B G B G B G 3 R G R G R G 3 G B G B G B > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > > > #define RAW(row,col) \ > ~~~~~~~~~~~~~~~~~~~~~~ > raw_image[(row)*raw_width+(col)] > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > #define FC(row,col) \ > ~~~~~~~~~~~~~~~~~~~~~ > (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > #define BAYER(row,col) \ > ~~~~~~~~~~~~~~~~~~~~~~~~ > image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)] > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > #define BAYER2(row,col) \ > ~~~~~~~~~~~~~~~~~~~~~~~~~ > image[((row) >> shrink)*iwidth + ((col) >> shrink)][fcol(row,col)] > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > int CLASS fcol (int row, int col) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const char filter[16][16] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (filters == 9) return xtrans[(row+6) % 6][(col+6) % 6]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > return FC(row,col); > ~~~~~~~~~~~~~~~~~~~ > } > ~ > > > #ifndef __GLIBC__ > ~~~~~~~~~~~~~~~~~ > char *my_memmem (char *haystack, size_t haystacklen, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > char *needle, size_t needlelen) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > char *c; > ~~~~~~~~ > for (c = haystack; c <= haystack + haystacklen - needlelen; c++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!memcmp (c, needle, needlelen)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return c; > ~~~~~~~~~ > return 0; > ~~~~~~~~~ > } > ~ > #define memmem my_memmem > ~~~~~~~~~~~~~~~~~~~~~~~~ > char *my_strcasestr (char *haystack, const char *needle) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > char *c; > ~~~~~~~~ > for (c = haystack; *c; c++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!strncasecmp(c, needle, strlen(needle))) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return c; > ~~~~~~~~~ > return 0; > ~~~~~~~~~ > } > ~ > #define strcasestr my_strcasestr > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #endif > ~~~~~~ > > > void CLASS merror (void *ptr, const char *where) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > if (ptr) return; > ~~~~~~~~~~~~~~~~ > fprintf (stderr,_("%s: Out of memory in %s\n"), ifname, where); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > longjmp (failure, 1); > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS derror() > ~~~~~~~~~~~~~~~~~~~ > { > ~ > if (!data_error) { > ~~~~~~~~~~~~~~~~~~ > fprintf (stderr, "%s: ", ifname); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (feof(ifp)) > ~~~~~~~~~~~~~~ > fprintf (stderr,_("Unexpected end of file\n")); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else > ~~~~ > fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > data_error++; > ~~~~~~~~~~~~~ > /*RT Issue 2467 longjmp (failure, 1);*/ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > ushort CLASS sget2 (uchar *s) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > if (order == 0x4949) /* "II" means little-endian */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return s[0] | s[1] << 8; > ~~~~~~~~~~~~~~~~~~~~~~~~ > else /* "MM" means big-endian */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return s[0] << 8 | s[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > ushort CLASS get2() > ~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar str[2] = { 0xff,0xff }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (str, 1, 2, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~ > return sget2(str); > ~~~~~~~~~~~~~~~~~~ > } > ~ > > > unsigned CLASS sget4 (uchar *s) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > if (order == 0x4949) > ~~~~~~~~~~~~~~~~~~~~ > return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else > ~~~~ > return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > #define sget4(s) sget4((uchar *)s) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > unsigned CLASS get4() > ~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar str[4] = { 0xff,0xff,0xff,0xff }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (str, 1, 4, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~ > return sget4(str); > ~~~~~~~~~~~~~~~~~~ > } > ~ > > > unsigned CLASS getint (int type) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > return type == 3 ? get2() : get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > float CLASS int_to_float (int i) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > union { int i; float f; } u; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > u.i = i; > ~~~~~~~~ > return u.f; > ~~~~~~~~~~~ > } > ~ > > > double CLASS getreal (int type) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > union { char c[8]; double d; } u; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int i, rev; > ~~~~~~~~~~~ > > > switch (type) { > ~~~~~~~~~~~~~~~ > case 3: return (unsigned short) get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 4: return (unsigned int) get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 5: u.d = (unsigned int) get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return u.d / (unsigned int) get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 8: return (signed short) get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 9: return (signed int) get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 10: u.d = (signed int) get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return u.d / (signed int) get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 11: return int_to_float (get4()); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 12: > ~~~~~~~~ > rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 8; i++) > ~~~~~~~~~~~~~~~~~~~~~ > u.c[i ^ rev] = fgetc(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > return u.d; > ~~~~~~~~~~~ > default: return fgetc(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS read_shorts (ushort *pixel, int count) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > if (fread (pixel, 2, count, ifp) < count) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > swab ((char*)pixel, (char*)pixel, count*2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS cubic_spline (const int *x_, const int *y_, const int len) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > float **A, *b, *c, *d, *x, *y; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int i, j; > ~~~~~~~~~ > > > A = (float **) calloc (((2*len + 4)*sizeof **A + sizeof *A), 2*len); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!A) return; > ~~~~~~~~~~~~~~~ > A[0] = (float *) (A + 2*len); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i = 1; i < 2*len; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > A[i] = A[0] + 2*len*i; > ~~~~~~~~~~~~~~~~~~~~~~ > y = len + (x = i + (d = i + (c = i + (b = A[0] + i*i)))); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i = 0; i < len; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > x[i] = x_[i] / 65535.0; > ~~~~~~~~~~~~~~~~~~~~~~~ > y[i] = y_[i] / 65535.0; > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (i = len-1; i > 0; i--) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > b[i] = (y[i] - y[i-1]) / (x[i] - x[i-1]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > d[i-1] = x[i] - x[i-1]; > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (i = 1; i < len-1; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > A[i][i] = 2 * (d[i-1] + d[i]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (i > 1) { > ~~~~~~~~~~~~ > A[i][i-1] = d[i-1]; > ~~~~~~~~~~~~~~~~~~~ > A[i-1][i] = d[i-1]; > ~~~~~~~~~~~~~~~~~~~ > } > ~ > A[i][len-1] = 6 * (b[i+1] - b[i]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for(i = 1; i < len-2; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float v = A[i+1][i] / A[i][i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for(j = 1; j <= len-1; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > A[i+1][j] -= v * A[i][j]; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for(i = len-2; i > 0; i--) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float acc = 0; > ~~~~~~~~~~~~~~ > for(j = i; j <= len-2; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > acc += A[i][j]*c[j]; > ~~~~~~~~~~~~~~~~~~~~ > c[i] = (A[i][len-1] - acc) / A[i][i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (i = 0; i < 0x10000; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float x_out = (float)(i / 65535.0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float y_out = 0; > ~~~~~~~~~~~~~~~~ > for (j = 0; j < len-1; j++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (x[j] <= x_out && x_out <= x[j+1]) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float v = x_out - x[j]; > ~~~~~~~~~~~~~~~~~~~~~~~ > y_out = y[j] + > ~~~~~~~~~~~~~~ > ((y[j+1] - y[j]) / d[j] - (2 * d[j] * c[j] + c[j+1] * d[j])/6) * v > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > + (c[j] * 0.5) * v*v + ((c[j+1] - c[j]) / (6 * d[j])) * v*v*v; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > curve[i] = y_out < 0.0 ? 0 : (y_out >= 1.0 ? 65535 : > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (ushort)(y_out * 65535.0 + 0.5)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > free (A); > ~~~~~~~~~ > } > ~ > > > void CLASS canon_600_fixed_wb (int temp) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const short mul[4][5] = { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 667, 358,397,565,452 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 731, 390,367,499,517 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 1119, 396,348,448,537 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 1399, 485,431,508,688 } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int lo, hi, i; > ~~~~~~~~~~~~~~ > float frac=0; > ~~~~~~~~~~~~~ > > > for (lo=4; --lo; ) > ~~~~~~~~~~~~~~~~~~ > if (*mul[lo] <= temp) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (hi=0; hi < 3; hi++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (*mul[hi] >= temp) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (lo != hi) > ~~~~~~~~~~~~~ > frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=1; i < 5; i++) > ~~~~~~~~~~~~~~~~~~~~~ > pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > /* Return values: 0 = white 1 = near white 2 = not white */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int CLASS canon_600_color (int ratio[2], int mar) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int clipped=0, target, miss; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > if (flash_used) { > ~~~~~~~~~~~~~~~~~ > if (ratio[1] < -104) > ~~~~~~~~~~~~~~~~~~~~ > { ratio[1] = -104; clipped = 1; } > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ratio[1] > 12) > ~~~~~~~~~~~~~~~~~~~~ > { ratio[1] = 12; clipped = 1; } > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else { > ~~~~~~~~ > if (ratio[1] < -264 || ratio[1] > 461) return 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ratio[1] < -50) > ~~~~~~~~~~~~~~~~~~~ > { ratio[1] = -50; clipped = 1; } > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ratio[1] > 307) > ~~~~~~~~~~~~~~~~~~~ > { ratio[1] = 307; clipped = 1; } > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > target = flash_used || ratio[1] < 197 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ? -38 - (398 * ratio[1] >> 10) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > : -123 + (48 * ratio[1] >> 10); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (target - mar <= ratio[0] && > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > target + 20 >= ratio[0] && !clipped) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > miss = target - ratio[0]; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if (abs(miss) >= mar*4) return 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (miss < -20) miss = -20; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (miss > mar) miss = mar; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ratio[0] = target - miss; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > return 1; > ~~~~~~~~~ > } > ~ > > > void CLASS canon_600_auto_wb() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int mar, row, col, i, j, st, count[] = { 0,0 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int test[8], total[2][8], ratio[2][2], stat[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > memset (&total, 0, sizeof total); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = canon_ev + 0.5; > ~~~~~~~~~~~~~~~~~~~ > if (i < 10) mar = 150; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else if (i > 12) mar = 20; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > else mar = 280 - 20 * i; > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (flash_used) mar = 80; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=14; row < height-14; row+=4) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=10; col < width; col+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 8; i++) > ~~~~~~~~~~~~~~~~~~~~~ > test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > BAYER(row+(i >> 1),col+(i & 1)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 8; i++) > ~~~~~~~~~~~~~~~~~~~~~ > if (test[i] < 150 || test[i] > 1500) goto next; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 4; i++) > ~~~~~~~~~~~~~~~~~~~~~ > if (abs(test[i] - test[i+4]) > 50) goto next; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 2; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 4; j+=2) > ~~~~~~~~~~~~~~~~~~~~~~ > ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > stat[i] = canon_600_color (ratio[i], mar); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if ((st = stat[0] | stat[1]) > 1) goto next; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 2; i++) > ~~~~~~~~~~~~~~~~~~~~~ > if (stat[i]) > ~~~~~~~~~~~~ > for (j=0; j < 2; j++) > ~~~~~~~~~~~~~~~~~~~~~ > test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 8; i++) > ~~~~~~~~~~~~~~~~~~~~~ > total[st][i] += test[i]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > count[st]++; > ~~~~~~~~~~~~ > next: ; > ~~~~~~~ > } > ~ > if (count[0] | count[1]) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > st = count[0]*200 < count[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 4; i++) > ~~~~~~~~~~~~~~~~~~~~~ > pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS canon_600_coeff() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const short table[6][12] = { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int t=0, i, c; > ~~~~~~~~~~~~~~ > float mc, yc; > ~~~~~~~~~~~~~ > > > mc = pre_mul[1] / pre_mul[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > yc = pre_mul[3] / pre_mul[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (mc > 1.28 && mc <= 2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (yc < 0.8789) t=3; > ~~~~~~~~~~~~~~~~~~~~~~ > else if (yc <= 2) t=4; > ~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (flash_used) t=5; > ~~~~~~~~~~~~~~~~~~~~ > for (raw_color = i=0; i < 3; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS canon_600_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar data[1120], *dp; > ~~~~~~~~~~~~~~~~~~~~~~~ > ushort *pix; > ~~~~~~~~~~~~ > int irow, row; > ~~~~~~~~~~~~~~ > > > for (irow=row=0; irow < height; irow++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (fread (data, 1, 1120, ifp) < 1120) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix = raw_image + row*raw_width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (dp=data; dp < data+1120; dp+=10, pix+=8) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[0] = (dp[0] << 2) + (dp[1] >> 6 ); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[3] = (dp[4] << 2) + (dp[1] & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[4] = (dp[5] << 2) + (dp[9] & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[7] = (dp[8] << 2) + (dp[9] >> 6 ); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if ((row+=2) > height) row = 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS canon_600_correct() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int row, col, val; > ~~~~~~~~~~~~~~~~~~ > static const short mul[4][2] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > for (row=0; row < height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((val = BAYER(row,col) - black) < 0) val = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > val = val * mul[row & 3][col & 1] >> 9; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > BAYER(row,col) = val; > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > canon_600_fixed_wb(1311); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > canon_600_auto_wb(); > ~~~~~~~~~~~~~~~~~~~~ > canon_600_coeff(); > ~~~~~~~~~~~~~~~~~~ > maximum = (0x3ff - black) * 1109 >> 9; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > black = 0; > ~~~~~~~~~~ > } > ~ > > > int CLASS canon_s2is() > ~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned row; > ~~~~~~~~~~~~~ > > > for (row=0; row < 100; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, row*3340 + 3284, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (getc(ifp) > 15) return 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > return 0; > ~~~~~~~~~ > } > ~ > > > inline unsigned CLASS getbithuff_t::operator() (int nbits, ushort *huff) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > /*RT static unsigned bitbuf=0; */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > /*RT static int vbits=0, reset=0; */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unsigned c; > ~~~~~~~~~~~ > > > if (UNLIKELY(nbits > 25)) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (nbits < 0) > ~~~~~~~~~~~~~~ > return bitbuf = vbits = reset = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (nbits == 0 || vbits < 0) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (!reset && vbits < nbits && (c = fgetc(ifp)) != EOF && > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > !(reset = zero_after_ff && c == 0xff && fgetc(ifp))) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > bitbuf = (bitbuf << 8) + (uchar) c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > vbits += 8; > ~~~~~~~~~~~ > } > ~ > c = bitbuf << (32-vbits) >> (32-nbits); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (huff) { > ~~~~~~~~~~~ > vbits -= huff[c] >> 8; > ~~~~~~~~~~~~~~~~~~~~~~ > c = (uchar) huff[c]; > ~~~~~~~~~~~~~~~~~~~~ > } else > ~~~~~~ > vbits -= nbits; > ~~~~~~~~~~~~~~~ > if (vbits < 0) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~ > return c; > ~~~~~~~~~ > } > ~ > > > #define getbits(n) getbithuff(n,0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define gethuff(h) getbithuff(*h,h+1) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > /* > ~~ > Construct a decode tree according the specification in *source. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > The first 16 bytes specify how many codes should be 1-bit, 2-bit > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 3-bit, etc. Bytes after that are the leaf values. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > For example, if the source is > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > then the code is > ~~~~~~~~~~~~~~~~ > > > 00 0x04 > ~~~~~~~~ > 010 0x03 > ~~~~~~~~~ > 011 0x05 > ~~~~~~~~~ > 100 0x06 > ~~~~~~~~~ > 101 0x02 > ~~~~~~~~~ > 1100 0x07 > ~~~~~~~~~~ > 1101 0x01 > ~~~~~~~~~~ > 11100 0x08 > ~~~~~~~~~~~ > 11101 0x09 > ~~~~~~~~~~~ > 11110 0x00 > ~~~~~~~~~~~ > 111110 0x0a > ~~~~~~~~~~~~ > 1111110 0x0b > ~~~~~~~~~~~~~ > 1111111 0xff > ~~~~~~~~~~~~~ > */ > ~~ > ushort * CLASS make_decoder_ref (const uchar **source) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int max, len, h, i, j; > ~~~~~~~~~~~~~~~~~~~~~~ > const uchar *count; > ~~~~~~~~~~~~~~~~~~~ > ushort *huff; > ~~~~~~~~~~~~~ > > > count = (*source += 16) - 17; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (max=16; max && !count[max]; max--); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > huff = (ushort *) calloc (1 + (1 << max), sizeof *huff); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (huff, "make_decoder()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > huff[0] = max; > ~~~~~~~~~~~~~~ > for (h=len=1; len <= max; len++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < count[len]; i++, ++*source) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 1 << (max-len); j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (h <= 1 << max) > ~~~~~~~~~~~~~~~~~~ > huff[h++] = len << 8 | **source; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return huff; > ~~~~~~~~~~~~ > } > ~ > > > ushort * CLASS make_decoder (const uchar *source) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > return make_decoder_ref (&source); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS crw_init_tables (unsigned table, ushort *huff[2]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const uchar first_tree[3][29] = { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > }; > ~~ > static const uchar second_tree[3][180] = { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff } > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > }; > ~~ > if (table > 2) table = 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > huff[0] = make_decoder ( first_tree[table]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > huff[1] = make_decoder (second_tree[table]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > /* > ~~ > Return 0 if the image starts with compressed data, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 1 if it starts with uncompressed low-order bits. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > In Canon compressed data, 0xff is always followed by 0x00. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > int CLASS canon_has_lowbits() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar test[0x4000]; > ~~~~~~~~~~~~~~~~~~~ > int ret=1, i; > ~~~~~~~~~~~~~ > > > fseek (ifp, 0, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (test, 1, sizeof test, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=540; i < sizeof test - 1; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (test[i] == 0xff) { > ~~~~~~~~~~~~~~~~~~~~~~ > if (test[i+1]) return 1; > ~~~~~~~~~~~~~~~~~~~~~~~~ > ret=0; > ~~~~~~ > } > ~ > return ret; > ~~~~~~~~~~~ > } > ~ > > > void CLASS canon_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > ushort *pixel, *prow, *huff[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int nblocks, lowbits, i, c, row, r, save, val; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > crw_init_tables (tiff_compress, huff); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > lowbits = canon_has_lowbits(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!lowbits) maximum = 0x3ff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > zero_after_ff = 1; > ~~~~~~~~~~~~~~~~~~ > getbits(-1); > ~~~~~~~~~~~~ > for (row=0; row < raw_height; row+=8) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pixel = raw_image + row*raw_width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > nblocks = MIN (8, raw_height-row) * raw_width >> 6; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (block=0; block < nblocks; block++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memset (diffbuf, 0, sizeof diffbuf); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 64; i++ ) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > leaf = gethuff(huff[i > 0]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (leaf == 0 && i) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (leaf == 0xff) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i += leaf >> 4; > ~~~~~~~~~~~~~~~~ > len = leaf & 15; > ~~~~~~~~~~~~~~~~ > if (len == 0) continue; > ~~~~~~~~~~~~~~~~~~~~~~~ > diff = getbits(len); > ~~~~~~~~~~~~~~~~~~~~ > if ((diff & (1 << (len-1))) == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff -= (1 << len) - 1; > ~~~~~~~~~~~~~~~~~~~~~~~ > if (i < 64) diffbuf[i] = diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > diffbuf[0] += carry; > ~~~~~~~~~~~~~~~~~~~~ > carry = diffbuf[0]; > ~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 64; i++ ) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if (pnum++ % raw_width == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > base[0] = base[1] = 512; > ~~~~~~~~~~~~~~~~~~~~~~~~ > if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > derror(); > ~~~~~~~~~ > } > ~ > } > ~ > if (lowbits) { > ~~~~~~~~~~~~~~ > save = ftell(ifp); > ~~~~~~~~~~~~~~~~~~ > fseek (ifp, 26 + row*raw_width/4, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (prow=pixel, i=0; i < raw_width*2; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > c = fgetc(ifp); > ~~~~~~~~~~~~~~~ > for (r=0; r < 8; r+=2, prow++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > val = (*prow << 2) + ((c >> r) & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (raw_width == 2672 && val < 512) val += 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > *prow = val; > ~~~~~~~~~~~~ > } > ~ > } > ~ > fseek (ifp, save, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > FORC(2) free (huff[c]); > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > /* > ~~ > Not a full implementation of Lossless JPEG, just > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > enough to decode Canon, Kodak and Adobe DNG images. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > struct jhead { > ~~~~~~~~~~~~~~ > int bits, high, wide, clrs, sraw, psv, restart, vpred[6]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort *huff[6], *free[4], *row; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > }; > ~~ > > > int CLASS ljpeg_start (struct jhead *jh, int info_only) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > ushort c, tag, len; > ~~~~~~~~~~~~~~~~~~~ > uchar data[0x10000]; > ~~~~~~~~~~~~~~~~~~~~ > const uchar *dp; > ~~~~~~~~~~~~~~~~ > > > memset (jh, 0, sizeof *jh); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jh->restart = INT_MAX; > ~~~~~~~~~~~~~~~~~~~~~~ > if ((fgetc(ifp),fgetc(ifp)) != 0xd8) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > do { > ~~~~ > if (!fread (data, 2, 2, ifp)) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tag = data[0] << 8 | data[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > len = (data[2] << 8 | data[3]) - 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag <= 0xff00) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (data, 1, len, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > switch (tag) { > ~~~~~~~~~~~~~~ > case 0xffc3: > ~~~~~~~~~~~~ > jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 0xffc1: > ~~~~~~~~~~~~ > case 0xffc0: > ~~~~~~~~~~~~ > jh->algo = tag & 0xff; > ~~~~~~~~~~~~~~~~~~~~~~ > jh->bits = data[0]; > ~~~~~~~~~~~~~~~~~~~ > jh->high = data[1] << 8 | data[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jh->wide = data[3] << 8 | data[4]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jh->clrs = data[5] + jh->sraw; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (len == 9 && !dng_version) getc(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 0xffc4: > ~~~~~~~~~~~~ > if (info_only) break; > ~~~~~~~~~~~~~~~~~~~~~ > for (dp = data; dp < data+len && !((c = *dp++) & -20); ) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jh->free[c] = jh->huff[c] = make_decoder_ref (&dp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 0xffda: > ~~~~~~~~~~~~ > jh->psv = data[1+data[0]*2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jh->bits -= data[3+data[0]*2] & 15; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 0xffdb: > ~~~~~~~~~~~~ > FORC(64) jh->quant[c] = data[c*2+1] << 8 | data[c*2+2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 0xffdd: > ~~~~~~~~~~~~ > jh->restart = data[0] << 8 | data[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } while (tag != 0xffda); > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (jh->bits > 16 || jh->clrs > 6 || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > !jh->bits || !jh->high || !jh->wide || !jh->clrs) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (info_only) return 1; > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (!jh->huff[0]) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(19) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (jh->sraw) { > ~~~~~~~~~~~~~~~ > FORC(4) jh->huff[2+c] = jh->huff[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(jh->sraw) jh->huff[1+c] = jh->huff[0]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > jh->row = (ushort *) calloc (2 * jh->wide*jh->clrs, 4); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (jh->row, "ljpeg_start()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return zero_after_ff = 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS ljpeg_end (struct jhead *jh) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int c; > ~~~~~~ > FORC4 if (jh->free[c]) free (jh->free[c]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > free (jh->row); > ~~~~~~~~~~~~~~~ > } > ~ > > > inline int CLASS ljpeg_diff (ushort *huff) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int len, diff; > ~~~~~~~~~~~~~~ > > > len = gethuff(huff); > ~~~~~~~~~~~~~~~~~~~~ > if (len == 16 && (!dng_version || dng_version >= 0x1010000)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return -32768; > ~~~~~~~~~~~~~~ > diff = getbits(len); > ~~~~~~~~~~~~~~~~~~~~ > if ((diff & (1 << (len-1))) == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff -= (1 << len) - 1; > ~~~~~~~~~~~~~~~~~~~~~~~ > return diff; > ~~~~~~~~~~~~ > } > ~ > > > ushort * CLASS ljpeg_row (int jrow, struct jhead *jh) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int col, c, diff, pred, spred=0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort mark=0, *row[3]; > ~~~~~~~~~~~~~~~~~~~~~~~ > > > if (jrow * jh->wide % jh->restart == 0) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(6) jh->vpred[c] = 1 << (jh->bits-1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (jrow) { > ~~~~~~~~~~~ > fseek (ifp, -2, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > do mark = (mark << 8) + (c = fgetc(ifp)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (c != EOF && mark >> 4 != 0xffd); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > getbits(-1); > ~~~~~~~~~~~~ > } > ~ > FORC3 row[c] = (jh->row + ((jrow & 1) + 1) * (jh->wide*jh->clrs*((jrow+c) & 1))); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < jh->wide; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(jh->clrs) { > ~~~~~~~~~~~~~~~~ > diff = ljpeg_diff (jh->huff[c]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (jh->sraw && c <= jh->sraw && (col | c)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pred = spred; > ~~~~~~~~~~~~~ > else if (col) pred = row[0][-jh->clrs]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else pred = (jh->vpred[c] += diff) - diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (jh->psv != 1 && jrow && col) switch (jh->psv) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 2: pred = row[1][0]; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 3: pred = row[1][-jh->clrs]; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 7: pred = (pred + row[1][0]) >> 1; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > default: pred = 0; > ~~~~~~~~~~~~~~~~~~ > } > ~ > if (UNLIKELY((**row = pred + diff) >> jh->bits)) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (c <= jh->sraw) spred = **row; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row[0]++; row[1]++; > ~~~~~~~~~~~~~~~~~~~ > } > ~ > return row[2]; > ~~~~~~~~~~~~~~ > } > ~ > > > void CLASS lossless_jpeg_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > struct jhead jh; > ~~~~~~~~~~~~~~~~ > int row=0, col=0; > ~~~~~~~~~~~~~~~~~ > > > if (!ljpeg_start (&jh, 0)) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int jwide = jh.wide * jh.clrs; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort *rp[2]; > ~~~~~~~~~~~~~~ > rp[0] = ljpeg_row (0, &jh); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > for (int jrow=0; jrow < jh.high; jrow++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #ifdef _OPENMP > ~~~~~~~~~~~~~~ > #pragma omp parallel sections > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #endif > ~~~~~~ > { > ~ > #ifdef _OPENMP > ~~~~~~~~~~~~~~ > #pragma omp section > ~~~~~~~~~~~~~~~~~~~ > #endif > ~~~~~~ > { > ~ > if(jrow < jh.high - 1) > ~~~~~~~~~~~~~~~~~~~~~~ > rp[(jrow + 1)&1] = ljpeg_row (jrow + 1, &jh); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > #ifdef _OPENMP > ~~~~~~~~~~~~~~ > #pragma omp section > ~~~~~~~~~~~~~~~~~~~ > #endif > ~~~~~~ > { > ~ > if (load_flags & 1) > ~~~~~~~~~~~~~~~~~~~ > row = jrow & 1 ? height-1-jrow/2 : jrow/2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (int jcol=0; jcol < jwide; jcol++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int val = curve[*rp[jrow&1]++]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (cr2_slice[0]) { > ~~~~~~~~~~~~~~~~~~~ > int jidx = jrow*jwide + jcol; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int i = jidx / (cr2_slice[1]*raw_height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int j; > ~~~~~~ > if ((j = i >= cr2_slice[0])) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = cr2_slice[0]; > ~~~~~~~~~~~~~~~~~~ > jidx -= i * (cr2_slice[1]*raw_height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row = jidx / cr2_slice[1+j]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > col = jidx % cr2_slice[1+j] + i*cr2_slice[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (raw_width == 3984 && (col -= 2) < 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > col += (row--,raw_width); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((unsigned) row < raw_height) RAW(row,col) = val; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (++col >= raw_width) > ~~~~~~~~~~~~~~~~~~~~~~~ > col = (row++,0); > ~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > } > ~ > ljpeg_end (&jh); > ~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS canon_sraw_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > struct jhead jh; > ~~~~~~~~~~~~~~~~ > short *rp=0, (*ip)[4]; > ~~~~~~~~~~~~~~~~~~~~~~ > int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int v[3]={0,0,0}, ver, hue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > char *cp; > ~~~~~~~~~ > > > if (!ljpeg_start (&jh, 0) || jh.clrs < 4) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jwide = (jh.wide >>= 1) * jh.clrs; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > for (ecol=slice=0; slice <= cr2_slice[0]; slice++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > scol = ecol; > ~~~~~~~~~~~~ > ecol += cr2_slice[1] * 2 / jh.clrs; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!cr2_slice[0] || ecol > raw_width-1) ecol = raw_width & -2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < height; row += (jh.clrs >> 1) - 1) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ip = (short (*)[4]) image + row*width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=scol; col < ecol; col+=2, jcol+=jh.clrs) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((jcol %= jwide) == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~ > rp = (short *) ljpeg_row (jrow++, &jh); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col >= width) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC (jh.clrs-2) > ~~~~~~~~~~~~~~~~ > ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ip[col][1] = rp[jcol+jh.clrs-2] - 16384; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ip[col][2] = rp[jcol+jh.clrs-1] - 16384; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > for (cp=model2; *cp && !isdigit(*cp); cp++); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sscanf (cp, "%d.%d.%d", v, v+1, v+2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ver = (v[0]*1000 + v[1])*1000 + v[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > hue = (jh.sraw+1) << 2; > ~~~~~~~~~~~~~~~~~~~~~~~ > if (unique_id >= 0x80000281 || (unique_id == 0x80000218 && ver > 1000006)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > hue = jh.sraw << 1; > ~~~~~~~~~~~~~~~~~~~ > ip = (short (*)[4]) image; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > rp = ip[0]; > ~~~~~~~~~~~ > for (row=0; row < height; row++, ip+=width) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (row & (jh.sraw >> 1)) > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col+=2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (c=1; c < 3; c++) > ~~~~~~~~~~~~~~~~~~~~~ > if (row == height-1) > ~~~~~~~~~~~~~~~~~~~~ > ip[col][c] = ip[col-width][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else ip[col][c] = (ip[col-width][c] + ip[col+width][c] + 1) >> 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=1; col < width; col+=2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (c=1; c < 3; c++) > ~~~~~~~~~~~~~~~~~~~~~ > if (col == width-1) > ~~~~~~~~~~~~~~~~~~~ > ip[col][c] = ip[col-1][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else ip[col][c] = (ip[col-1][c] + ip[col+1][c] + 1) >> 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for ( ; rp < ip[0]; rp+=4) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (unique_id == 0x80000218 || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unique_id == 0x80000250 || > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > unique_id == 0x80000261 || > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > unique_id == 0x80000281 || > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > unique_id == 0x80000287) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > rp[1] = (rp[1] << 2) + hue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > rp[2] = (rp[2] << 2) + hue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[0] = rp[0] + (( 50*rp[1] + 22929*rp[2]) >> 14); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[2] = rp[0] + ((29040*rp[1] - 101*rp[2]) >> 14); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else { > ~~~~~~~~ > if (unique_id < 0x80000218) rp[0] -= 512; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[0] = rp[0] + rp[2]; > ~~~~~~~~~~~~~~~~~~~~~~~ > pix[2] = rp[0] + rp[1]; > ~~~~~~~~~~~~~~~~~~~~~~~ > pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > FORC3 rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > ljpeg_end (&jh); > ~~~~~~~~~~~~~~~~ > maximum = 0x3fff; > ~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS adobe_copy_pixel (unsigned row, unsigned col, ushort **rp) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int c; > ~~~~~~ > > > if (tiff_samples == 2 && shot_select) (*rp)++; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (raw_image) { > ~~~~~~~~~~~~~~~~ > if (row < raw_height && col < raw_width) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = curve[**rp]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > *rp += tiff_samples; > ~~~~~~~~~~~~~~~~~~~~ > } else { > ~~~~~~~~ > if (row < height && col < width) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(tiff_samples) > ~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1030:7: note: in expansion of macro 'FORC' > FORC(tiff_samples) > ^~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::lossless_dng_load_raw()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1091:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (jrow=0; jrow+7 < jh.high; jrow += 8) { > ~~~~~~~^~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1092:24: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (jcol=0; jcol+7 < jh.wide; jcol += 8) { > ~~~~~~~^~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1104:28: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (row=col=jrow=0; jrow < jh.high; jrow++) { > ~~~~~^~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::packed_dng_load_raw()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1131:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (col=0; col < raw_width * tiff_samples; col++) > ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::nikon_3700()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1303:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (i=0; i < sizeof table / sizeof *table; i++) > ~~^~~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'int DCraw::minolta_z2()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1320:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (nz=i=0; i < sizeof tail; i++) > ~~^~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::ppm16_thumb()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1347:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (i=0; i < thumb_length; i++) > ~~^~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::layer_thumb()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1366:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (i=0; i < thumb_length; i++) > ~~^~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::phase_one_flat_field(int, int)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1430:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (c=0; c < nc; c+=2) { > ~~^~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1439:7: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > row < head[1]+head[3]-head[5]; row++) { > ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1441:14: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (c=0; c < nc; c+=2) { > ~~^~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1448:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > col < cend && col < head[0]+head[2]-head[4]; col++) { > ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1454:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (c=0; c < nc; c+=2) > ~~^~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1459:14: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (c=0; c < nc; c+=2) > ~~^~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::phase_one_correct()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1579:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > row < (qr ? raw_height : ph1.split_row); row++) > ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1581:8: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > col < (qc ? raw_width : ph1.split_col); col++) > ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1598:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > i = qmult[row >= ph1.split_row][col >= ph1.split_col] * RAW(row,col); > ~~~~^~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1598:40: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > i = qmult[row >= ph1.split_row][col >= ph1.split_col] * RAW(row,col); > ~~~~^~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1622:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > row < (qr ? raw_height : ph1.split_row); row++) > ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1624:8: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > col < (qc ? raw_width : ph1.split_col); col++) > ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::parse_hasselblad_gain()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1840:12: warning: variable 'raw_h' set but not used [-Wunused-but-set-variable] > ushort raw_h, count, ch_count, u16; > ^~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1840:19: warning: unused variable 'count' [-Wunused-variable] > ushort raw_h, count, ch_count, u16; > ^~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1840:26: warning: unused variable 'ch_count' [-Wunused-variable] > ushort raw_h, count, ch_count, u16; > ^~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1840:36: warning: unused variable 'u16' [-Wunused-variable] > ushort raw_h, count, ch_count, u16; > ^~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1841:9: warning: unused variable 'i' [-Wunused-variable] > int i, offset; > ^ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::hasselblad_correct()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:1896:31: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (row = 1; row < raw_height-1; row++) { > ~~~~^~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:2005:27: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (row = 0; row < bh; row++) { > ~~~~^~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:2012:31: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (col = 0; col < bw; col++) { > ~~~~^~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:2014:71: error: call of overloaded 'abs(unsigned int)' is ambiguous > ushort dist = (ushort)sqrt(abs(corners[i][0] - row) * abs(corners[i][0] - row) + abs(corners[i][1] - col) * abs(corners[i][1] - col)); > ^ >In file included from /usr/include/c++/7/cstdlib:75:0, > from /usr/include/c++/7/bits/stl_algo.h:59, > from /usr/include/c++/7/algorithm:62, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/rt_math.h:3, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6: >/usr/include/stdlib.h:751:12: note: candidate: int abs(int) > extern int abs (int __x) __THROW __attribute__ ((__const__)) __wur; > ^~~ >In file included from /usr/include/c++/7/cstdlib:77:0, > from /usr/include/c++/7/bits/stl_algo.h:59, > from /usr/include/c++/7/algorithm:62, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/rt_math.h:3, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6: >/usr/include/c++/7/bits/std_abs.h:56:3: note: candidate: long int std::abs(long int) > abs(long __i) { return __builtin_labs(__i); } > ^~~ >/usr/include/c++/7/bits/std_abs.h:61:3: note: candidate: long long int std::abs(long long int) > abs(long long __x) { return __builtin_llabs (__x); } > ^~~ >/usr/include/c++/7/bits/std_abs.h:70:3: note: candidate: constexpr double std::abs(double) > abs(double __x) > ^~~ >/usr/include/c++/7/bits/std_abs.h:74:3: note: candidate: constexpr float std::abs(float) > abs(float __x) > ^~~ >/usr/include/c++/7/bits/std_abs.h:78:3: note: candidate: constexpr long double std::abs(long double) > abs(long double __x) > ^~~ >/usr/include/c++/7/bits/std_abs.h:84:3: note: candidate: constexpr __int128 std::abs(__int128) > abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; } > ^~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:2014:98: error: call of overloaded 'abs(unsigned int)' is ambiguous > ushort dist = (ushort)sqrt(abs(corners[i][0] - row) * abs(corners[i][0] - row) + abs(corners[i][1] - col) * abs(corners[i][1] - col)); > ^ >In file included from /usr/include/c++/7/cstdlib:75:0, > from /usr/include/c++/7/bits/stl_algo.h:59, > from /usr/include/c++/7/algorithm:62, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/rt_math.h:3, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6: >/usr/include/stdlib.h:751:12: note: candidate: int abs(int) > extern int abs (int __x) __THROW __attribute__ ((__const__)) __wur; > ^~~ >In file included from /usr/include/c++/7/cstdlib:77:0, > from /usr/include/c++/7/bits/stl_algo.h:59, > from /usr/include/c++/7/algorithm:62, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/rt_math.h:3, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6: >/usr/include/c++/7/bits/std_abs.h:56:3: note: candidate: long int std::abs(long int) > abs(long __i) { return __builtin_labs(__i); } > ^~~ >/usr/include/c++/7/bits/std_abs.h:61:3: note: candidate: long long int std::abs(long long int) > abs(long long __x) { return __builtin_llabs (__x); } > ^~~ >/usr/include/c++/7/bits/std_abs.h:70:3: note: candidate: constexpr double std::abs(double) > abs(double __x) > ^~~ >/usr/include/c++/7/bits/std_abs.h:74:3: note: candidate: constexpr float std::abs(float) > abs(float __x) > ^~~ >/usr/include/c++/7/bits/std_abs.h:78:3: note: candidate: constexpr long double std::abs(long double) > abs(long double __x) > ^~~ >/usr/include/c++/7/bits/std_abs.h:84:3: note: candidate: constexpr __int128 std::abs(__int128) > abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; } > ^~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:2014:125: error: call of overloaded 'abs(unsigned int)' is ambiguous > ushort dist = (ushort)sqrt(abs(corners[i][0] - row) * abs(corners[i][0] - row) + abs(corners[i][1] - col) * abs(corners[i][1] - col)); > ^ >In file included from /usr/include/c++/7/cstdlib:75:0, > from /usr/include/c++/7/bits/stl_algo.h:59, > from /usr/include/c++/7/algorithm:62, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/rt_math.h:3, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6: >/usr/include/stdlib.h:751:12: note: candidate: int abs(int) > extern int abs (int __x) __THROW __attribute__ ((__const__)) __wur; > ^~~ >In file included from /usr/include/c++/7/cstdlib:77:0, > from /usr/include/c++/7/bits/stl_algo.h:59, > from /usr/include/c++/7/algorithm:62, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/rt_math.h:3, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6: >/usr/include/c++/7/bits/std_abs.h:56:3: note: candidate: long int std::abs(long int) > abs(long __i) { return __builtin_labs(__i); } > ^~~ >/usr/include/c++/7/bits/std_abs.h:61:3: note: candidate: long long int std::abs(long long int) > abs(long long __x) { return __builtin_llabs (__x); } > ^~~ >/usr/include/c++/7/bits/std_abs.h:70:3: note: candidate: constexpr double std::abs(double) > abs(double __x) > ^~~ >/usr/include/c++/7/bits/std_abs.h:74:3: note: candidate: constexpr float std::abs(float) > abs(float __x) > ^~~ >/usr/include/c++/7/bits/std_abs.h:78:3: note: candidate: constexpr long double std::abs(long double) > abs(long double __x) > ^~~ >/usr/include/c++/7/bits/std_abs.h:84:3: note: candidate: constexpr __int128 std::abs(__int128) > abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; } > ^~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:2014:152: error: call of overloaded 'abs(unsigned int)' is ambiguous > ushort dist = (ushort)sqrt(abs(corners[i][0] - row) * abs(corners[i][0] - row) + abs(corners[i][1] - col) * abs(corners[i][1] - col)); > ^ >In file included from /usr/include/c++/7/cstdlib:75:0, > from /usr/include/c++/7/bits/stl_algo.h:59, > from /usr/include/c++/7/algorithm:62, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/rt_math.h:3, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6: >/usr/include/stdlib.h:751:12: note: candidate: int abs(int) > extern int abs (int __x) __THROW __attribute__ ((__const__)) __wur; > ^~~ >In file included from /usr/include/c++/7/cstdlib:77:0, > from /usr/include/c++/7/bits/stl_algo.h:59, > from /usr/include/c++/7/algorithm:62, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/rt_math.h:3, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6: >/usr/include/c++/7/bits/std_abs.h:56:3: note: candidate: long int std::abs(long int) > abs(long __i) { return __builtin_labs(__i); } > ^~~ >/usr/include/c++/7/bits/std_abs.h:61:3: note: candidate: long long int std::abs(long long int) > abs(long long __x) { return __builtin_llabs (__x); } > ^~~ >/usr/include/c++/7/bits/std_abs.h:70:3: note: candidate: constexpr double std::abs(double) > abs(double __x) > ^~~ >/usr/include/c++/7/bits/std_abs.h:74:3: note: candidate: constexpr float std::abs(float) > abs(float __x) > ^~~ >/usr/include/c++/7/bits/std_abs.h:78:3: note: candidate: constexpr long double std::abs(long double) > abs(long double __x) > ^~~ >/usr/include/c++/7/bits/std_abs.h:84:3: note: candidate: constexpr __int128 std::abs(__int128) > abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; } > ^~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:2068:27: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if (x >= bw) x = bw-1; > ~~^~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:2069:27: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if (y >= bh) y = bh-1; > ~~^~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::hasselblad_load_raw()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:2115:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (s=0; s < tiff_samples*2; s+=2) { > ~~^~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:124:31: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > #define FORC(cnt) for (c=0; c < cnt; c++) > ~~^~~~~~~~~~~ > #define FORC3 FORC(3) > ~~~~~~~~~~~~~~~~~~~~~ > #define FORC4 FORC(4) > ~~~~~~~~~~~~~~~~~~~~~ > #define FORCC FORC(colors) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > #define SQR(x) rtengine::SQR(x) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define MIN(a,b) rtengine::min(a,static_cast<__typeof__(a)>(b)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define MAX(a,b) rtengine::max(a,static_cast<__typeof__(a)>(b)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define LIM(x,min,max) rtengine::LIM(x,static_cast<__typeof__(x)>(min),static_cast<__typeof__(x)>(max)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define ULIM(x,y,z) rtengine::median(x,static_cast<__typeof__(x)>(y),static_cast<__typeof__(x)>(z)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define CLIP(x) rtengine::CLIP(x) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; } > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > /* > ~~ > In order to inline this calculation, I make the risky > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > assumption that all filter patterns can be described > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > by a repeating pattern of eight rows and two columns > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > Do not use the FC or BAYER macros with the Leaf CatchLight, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > because its pattern is 16x16, not 2x8. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4: > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0 G M G M G M 0 C Y C Y C Y 0 Y C Y C Y C 0 G M G M G M > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 1 C Y C Y C Y 1 M G M G M G 1 M G M G M G 1 Y C Y C Y C > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 3 C Y C Y C Y 3 G M G M G M 3 G M G M G M > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 4 C Y C Y C Y 4 Y C Y C Y C > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > PowerShot A5 5 G M G M G M 5 G M G M G M > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 7 M G M G M G 7 M G M G M G > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0 1 2 3 4 5 > ~~~~~~~~~~~ > 0 C Y C Y C Y > ~~~~~~~~~~~~~ > 1 G M G M G M > ~~~~~~~~~~~~~ > 2 C Y C Y C Y > ~~~~~~~~~~~~~ > 3 M G M G M G > ~~~~~~~~~~~~~ > > > All RGB cameras use one of these Bayer grids: > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > 0x16161616: 0x61616161: 0x49494949: 0x94949494: > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0 B G B G B G 0 G R G R G R 0 G B G B G B 0 R G R G R G > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 1 G R G R G R 1 B G B G B G 1 R G R G R G 1 G B G B G B > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 2 B G B G B G 2 G R G R G R 2 G B G B G B 2 R G R G R G > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 3 G R G R G R 3 B G B G B G 3 R G R G R G 3 G B G B G B > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > > > #define RAW(row,col) \ > ~~~~~~~~~~~~~~~~~~~~~~ > raw_image[(row)*raw_width+(col)] > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > #define FC(row,col) \ > ~~~~~~~~~~~~~~~~~~~~~ > (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > #define BAYER(row,col) \ > ~~~~~~~~~~~~~~~~~~~~~~~~ > image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)] > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > #define BAYER2(row,col) \ > ~~~~~~~~~~~~~~~~~~~~~~~~~ > image[((row) >> shrink)*iwidth + ((col) >> shrink)][fcol(row,col)] > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > int CLASS fcol (int row, int col) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const char filter[16][16] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (filters == 9) return xtrans[(row+6) % 6][(col+6) % 6]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > return FC(row,col); > ~~~~~~~~~~~~~~~~~~~ > } > ~ > > > #ifndef __GLIBC__ > ~~~~~~~~~~~~~~~~~ > char *my_memmem (char *haystack, size_t haystacklen, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > char *needle, size_t needlelen) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > char *c; > ~~~~~~~~ > for (c = haystack; c <= haystack + haystacklen - needlelen; c++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!memcmp (c, needle, needlelen)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return c; > ~~~~~~~~~ > return 0; > ~~~~~~~~~ > } > ~ > #define memmem my_memmem > ~~~~~~~~~~~~~~~~~~~~~~~~ > char *my_strcasestr (char *haystack, const char *needle) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > char *c; > ~~~~~~~~ > for (c = haystack; *c; c++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!strncasecmp(c, needle, strlen(needle))) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return c; > ~~~~~~~~~ > return 0; > ~~~~~~~~~ > } > ~ > #define strcasestr my_strcasestr > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #endif > ~~~~~~ > > > void CLASS merror (void *ptr, const char *where) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > if (ptr) return; > ~~~~~~~~~~~~~~~~ > fprintf (stderr,_("%s: Out of memory in %s\n"), ifname, where); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > longjmp (failure, 1); > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS derror() > ~~~~~~~~~~~~~~~~~~~ > { > ~ > if (!data_error) { > ~~~~~~~~~~~~~~~~~~ > fprintf (stderr, "%s: ", ifname); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (feof(ifp)) > ~~~~~~~~~~~~~~ > fprintf (stderr,_("Unexpected end of file\n")); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else > ~~~~ > fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > data_error++; > ~~~~~~~~~~~~~ > /*RT Issue 2467 longjmp (failure, 1);*/ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > ushort CLASS sget2 (uchar *s) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > if (order == 0x4949) /* "II" means little-endian */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return s[0] | s[1] << 8; > ~~~~~~~~~~~~~~~~~~~~~~~~ > else /* "MM" means big-endian */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return s[0] << 8 | s[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > ushort CLASS get2() > ~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar str[2] = { 0xff,0xff }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (str, 1, 2, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~ > return sget2(str); > ~~~~~~~~~~~~~~~~~~ > } > ~ > > > unsigned CLASS sget4 (uchar *s) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > if (order == 0x4949) > ~~~~~~~~~~~~~~~~~~~~ > return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else > ~~~~ > return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > #define sget4(s) sget4((uchar *)s) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > unsigned CLASS get4() > ~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar str[4] = { 0xff,0xff,0xff,0xff }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (str, 1, 4, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~ > return sget4(str); > ~~~~~~~~~~~~~~~~~~ > } > ~ > > > unsigned CLASS getint (int type) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > return type == 3 ? get2() : get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > float CLASS int_to_float (int i) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > union { int i; float f; } u; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > u.i = i; > ~~~~~~~~ > return u.f; > ~~~~~~~~~~~ > } > ~ > > > double CLASS getreal (int type) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > union { char c[8]; double d; } u; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int i, rev; > ~~~~~~~~~~~ > > > switch (type) { > ~~~~~~~~~~~~~~~ > case 3: return (unsigned short) get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 4: return (unsigned int) get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 5: u.d = (unsigned int) get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return u.d / (unsigned int) get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 8: return (signed short) get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 9: return (signed int) get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 10: u.d = (signed int) get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return u.d / (signed int) get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 11: return int_to_float (get4()); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 12: > ~~~~~~~~ > rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 8; i++) > ~~~~~~~~~~~~~~~~~~~~~ > u.c[i ^ rev] = fgetc(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > return u.d; > ~~~~~~~~~~~ > default: return fgetc(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS read_shorts (ushort *pixel, int count) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > if (fread (pixel, 2, count, ifp) < count) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > swab ((char*)pixel, (char*)pixel, count*2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS cubic_spline (const int *x_, const int *y_, const int len) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > float **A, *b, *c, *d, *x, *y; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int i, j; > ~~~~~~~~~ > > > A = (float **) calloc (((2*len + 4)*sizeof **A + sizeof *A), 2*len); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!A) return; > ~~~~~~~~~~~~~~~ > A[0] = (float *) (A + 2*len); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i = 1; i < 2*len; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > A[i] = A[0] + 2*len*i; > ~~~~~~~~~~~~~~~~~~~~~~ > y = len + (x = i + (d = i + (c = i + (b = A[0] + i*i)))); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i = 0; i < len; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > x[i] = x_[i] / 65535.0; > ~~~~~~~~~~~~~~~~~~~~~~~ > y[i] = y_[i] / 65535.0; > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (i = len-1; i > 0; i--) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > b[i] = (y[i] - y[i-1]) / (x[i] - x[i-1]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > d[i-1] = x[i] - x[i-1]; > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (i = 1; i < len-1; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > A[i][i] = 2 * (d[i-1] + d[i]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (i > 1) { > ~~~~~~~~~~~~ > A[i][i-1] = d[i-1]; > ~~~~~~~~~~~~~~~~~~~ > A[i-1][i] = d[i-1]; > ~~~~~~~~~~~~~~~~~~~ > } > ~ > A[i][len-1] = 6 * (b[i+1] - b[i]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for(i = 1; i < len-2; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float v = A[i+1][i] / A[i][i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for(j = 1; j <= len-1; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > A[i+1][j] -= v * A[i][j]; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for(i = len-2; i > 0; i--) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float acc = 0; > ~~~~~~~~~~~~~~ > for(j = i; j <= len-2; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > acc += A[i][j]*c[j]; > ~~~~~~~~~~~~~~~~~~~~ > c[i] = (A[i][len-1] - acc) / A[i][i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (i = 0; i < 0x10000; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float x_out = (float)(i / 65535.0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float y_out = 0; > ~~~~~~~~~~~~~~~~ > for (j = 0; j < len-1; j++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (x[j] <= x_out && x_out <= x[j+1]) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float v = x_out - x[j]; > ~~~~~~~~~~~~~~~~~~~~~~~ > y_out = y[j] + > ~~~~~~~~~~~~~~ > ((y[j+1] - y[j]) / d[j] - (2 * d[j] * c[j] + c[j+1] * d[j])/6) * v > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > + (c[j] * 0.5) * v*v + ((c[j+1] - c[j]) / (6 * d[j])) * v*v*v; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > curve[i] = y_out < 0.0 ? 0 : (y_out >= 1.0 ? 65535 : > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (ushort)(y_out * 65535.0 + 0.5)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > free (A); > ~~~~~~~~~ > } > ~ > > > void CLASS canon_600_fixed_wb (int temp) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const short mul[4][5] = { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 667, 358,397,565,452 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 731, 390,367,499,517 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 1119, 396,348,448,537 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 1399, 485,431,508,688 } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int lo, hi, i; > ~~~~~~~~~~~~~~ > float frac=0; > ~~~~~~~~~~~~~ > > > for (lo=4; --lo; ) > ~~~~~~~~~~~~~~~~~~ > if (*mul[lo] <= temp) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (hi=0; hi < 3; hi++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (*mul[hi] >= temp) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (lo != hi) > ~~~~~~~~~~~~~ > frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=1; i < 5; i++) > ~~~~~~~~~~~~~~~~~~~~~ > pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > /* Return values: 0 = white 1 = near white 2 = not white */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int CLASS canon_600_color (int ratio[2], int mar) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int clipped=0, target, miss; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > if (flash_used) { > ~~~~~~~~~~~~~~~~~ > if (ratio[1] < -104) > ~~~~~~~~~~~~~~~~~~~~ > { ratio[1] = -104; clipped = 1; } > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ratio[1] > 12) > ~~~~~~~~~~~~~~~~~~~~ > { ratio[1] = 12; clipped = 1; } > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else { > ~~~~~~~~ > if (ratio[1] < -264 || ratio[1] > 461) return 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ratio[1] < -50) > ~~~~~~~~~~~~~~~~~~~ > { ratio[1] = -50; clipped = 1; } > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ratio[1] > 307) > ~~~~~~~~~~~~~~~~~~~ > { ratio[1] = 307; clipped = 1; } > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > target = flash_used || ratio[1] < 197 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ? -38 - (398 * ratio[1] >> 10) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > : -123 + (48 * ratio[1] >> 10); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (target - mar <= ratio[0] && > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > target + 20 >= ratio[0] && !clipped) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > miss = target - ratio[0]; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if (abs(miss) >= mar*4) return 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (miss < -20) miss = -20; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (miss > mar) miss = mar; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ratio[0] = target - miss; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > return 1; > ~~~~~~~~~ > } > ~ > > > void CLASS canon_600_auto_wb() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int mar, row, col, i, j, st, count[] = { 0,0 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int test[8], total[2][8], ratio[2][2], stat[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > memset (&total, 0, sizeof total); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = canon_ev + 0.5; > ~~~~~~~~~~~~~~~~~~~ > if (i < 10) mar = 150; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else if (i > 12) mar = 20; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > else mar = 280 - 20 * i; > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (flash_used) mar = 80; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=14; row < height-14; row+=4) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=10; col < width; col+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 8; i++) > ~~~~~~~~~~~~~~~~~~~~~ > test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > BAYER(row+(i >> 1),col+(i & 1)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 8; i++) > ~~~~~~~~~~~~~~~~~~~~~ > if (test[i] < 150 || test[i] > 1500) goto next; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 4; i++) > ~~~~~~~~~~~~~~~~~~~~~ > if (abs(test[i] - test[i+4]) > 50) goto next; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 2; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 4; j+=2) > ~~~~~~~~~~~~~~~~~~~~~~ > ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > stat[i] = canon_600_color (ratio[i], mar); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if ((st = stat[0] | stat[1]) > 1) goto next; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 2; i++) > ~~~~~~~~~~~~~~~~~~~~~ > if (stat[i]) > ~~~~~~~~~~~~ > for (j=0; j < 2; j++) > ~~~~~~~~~~~~~~~~~~~~~ > test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 8; i++) > ~~~~~~~~~~~~~~~~~~~~~ > total[st][i] += test[i]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > count[st]++; > ~~~~~~~~~~~~ > next: ; > ~~~~~~~ > } > ~ > if (count[0] | count[1]) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > st = count[0]*200 < count[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 4; i++) > ~~~~~~~~~~~~~~~~~~~~~ > pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS canon_600_coeff() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const short table[6][12] = { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int t=0, i, c; > ~~~~~~~~~~~~~~ > float mc, yc; > ~~~~~~~~~~~~~ > > > mc = pre_mul[1] / pre_mul[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > yc = pre_mul[3] / pre_mul[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (mc > 1.28 && mc <= 2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (yc < 0.8789) t=3; > ~~~~~~~~~~~~~~~~~~~~~~ > else if (yc <= 2) t=4; > ~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (flash_used) t=5; > ~~~~~~~~~~~~~~~~~~~~ > for (raw_color = i=0; i < 3; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS canon_600_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar data[1120], *dp; > ~~~~~~~~~~~~~~~~~~~~~~~ > ushort *pix; > ~~~~~~~~~~~~ > int irow, row; > ~~~~~~~~~~~~~~ > > > for (irow=row=0; irow < height; irow++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (fread (data, 1, 1120, ifp) < 1120) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix = raw_image + row*raw_width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (dp=data; dp < data+1120; dp+=10, pix+=8) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[0] = (dp[0] << 2) + (dp[1] >> 6 ); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[3] = (dp[4] << 2) + (dp[1] & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[4] = (dp[5] << 2) + (dp[9] & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[7] = (dp[8] << 2) + (dp[9] >> 6 ); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if ((row+=2) > height) row = 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS canon_600_correct() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int row, col, val; > ~~~~~~~~~~~~~~~~~~ > static const short mul[4][2] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > for (row=0; row < height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((val = BAYER(row,col) - black) < 0) val = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > val = val * mul[row & 3][col & 1] >> 9; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > BAYER(row,col) = val; > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > canon_600_fixed_wb(1311); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > canon_600_auto_wb(); > ~~~~~~~~~~~~~~~~~~~~ > canon_600_coeff(); > ~~~~~~~~~~~~~~~~~~ > maximum = (0x3ff - black) * 1109 >> 9; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > black = 0; > ~~~~~~~~~~ > } > ~ > > > int CLASS canon_s2is() > ~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned row; > ~~~~~~~~~~~~~ > > > for (row=0; row < 100; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, row*3340 + 3284, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (getc(ifp) > 15) return 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > return 0; > ~~~~~~~~~ > } > ~ > > > inline unsigned CLASS getbithuff_t::operator() (int nbits, ushort *huff) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > /*RT static unsigned bitbuf=0; */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > /*RT static int vbits=0, reset=0; */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unsigned c; > ~~~~~~~~~~~ > > > if (UNLIKELY(nbits > 25)) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (nbits < 0) > ~~~~~~~~~~~~~~ > return bitbuf = vbits = reset = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (nbits == 0 || vbits < 0) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (!reset && vbits < nbits && (c = fgetc(ifp)) != EOF && > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > !(reset = zero_after_ff && c == 0xff && fgetc(ifp))) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > bitbuf = (bitbuf << 8) + (uchar) c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > vbits += 8; > ~~~~~~~~~~~ > } > ~ > c = bitbuf << (32-vbits) >> (32-nbits); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (huff) { > ~~~~~~~~~~~ > vbits -= huff[c] >> 8; > ~~~~~~~~~~~~~~~~~~~~~~ > c = (uchar) huff[c]; > ~~~~~~~~~~~~~~~~~~~~ > } else > ~~~~~~ > vbits -= nbits; > ~~~~~~~~~~~~~~~ > if (vbits < 0) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~ > return c; > ~~~~~~~~~ > } > ~ > > > #define getbits(n) getbithuff(n,0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define gethuff(h) getbithuff(*h,h+1) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > /* > ~~ > Construct a decode tree according the specification in *source. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > The first 16 bytes specify how many codes should be 1-bit, 2-bit > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 3-bit, etc. Bytes after that are the leaf values. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > For example, if the source is > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > then the code is > ~~~~~~~~~~~~~~~~ > > > 00 0x04 > ~~~~~~~~ > 010 0x03 > ~~~~~~~~~ > 011 0x05 > ~~~~~~~~~ > 100 0x06 > ~~~~~~~~~ > 101 0x02 > ~~~~~~~~~ > 1100 0x07 > ~~~~~~~~~~ > 1101 0x01 > ~~~~~~~~~~ > 11100 0x08 > ~~~~~~~~~~~ > 11101 0x09 > ~~~~~~~~~~~ > 11110 0x00 > ~~~~~~~~~~~ > 111110 0x0a > ~~~~~~~~~~~~ > 1111110 0x0b > ~~~~~~~~~~~~~ > 1111111 0xff > ~~~~~~~~~~~~~ > */ > ~~ > ushort * CLASS make_decoder_ref (const uchar **source) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int max, len, h, i, j; > ~~~~~~~~~~~~~~~~~~~~~~ > const uchar *count; > ~~~~~~~~~~~~~~~~~~~ > ushort *huff; > ~~~~~~~~~~~~~ > > > count = (*source += 16) - 17; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (max=16; max && !count[max]; max--); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > huff = (ushort *) calloc (1 + (1 << max), sizeof *huff); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (huff, "make_decoder()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > huff[0] = max; > ~~~~~~~~~~~~~~ > for (h=len=1; len <= max; len++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < count[len]; i++, ++*source) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 1 << (max-len); j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (h <= 1 << max) > ~~~~~~~~~~~~~~~~~~ > huff[h++] = len << 8 | **source; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return huff; > ~~~~~~~~~~~~ > } > ~ > > > ushort * CLASS make_decoder (const uchar *source) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > return make_decoder_ref (&source); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS crw_init_tables (unsigned table, ushort *huff[2]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const uchar first_tree[3][29] = { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > }; > ~~ > static const uchar second_tree[3][180] = { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff } > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > }; > ~~ > if (table > 2) table = 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > huff[0] = make_decoder ( first_tree[table]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > huff[1] = make_decoder (second_tree[table]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > /* > ~~ > Return 0 if the image starts with compressed data, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 1 if it starts with uncompressed low-order bits. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > In Canon compressed data, 0xff is always followed by 0x00. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > int CLASS canon_has_lowbits() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar test[0x4000]; > ~~~~~~~~~~~~~~~~~~~ > int ret=1, i; > ~~~~~~~~~~~~~ > > > fseek (ifp, 0, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (test, 1, sizeof test, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=540; i < sizeof test - 1; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (test[i] == 0xff) { > ~~~~~~~~~~~~~~~~~~~~~~ > if (test[i+1]) return 1; > ~~~~~~~~~~~~~~~~~~~~~~~~ > ret=0; > ~~~~~~ > } > ~ > return ret; > ~~~~~~~~~~~ > } > ~ > > > void CLASS canon_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > ushort *pixel, *prow, *huff[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int nblocks, lowbits, i, c, row, r, save, val; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > crw_init_tables (tiff_compress, huff); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > lowbits = canon_has_lowbits(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!lowbits) maximum = 0x3ff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > zero_after_ff = 1; > ~~~~~~~~~~~~~~~~~~ > getbits(-1); > ~~~~~~~~~~~~ > for (row=0; row < raw_height; row+=8) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pixel = raw_image + row*raw_width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > nblocks = MIN (8, raw_height-row) * raw_width >> 6; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (block=0; block < nblocks; block++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memset (diffbuf, 0, sizeof diffbuf); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 64; i++ ) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > leaf = gethuff(huff[i > 0]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (leaf == 0 && i) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (leaf == 0xff) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i += leaf >> 4; > ~~~~~~~~~~~~~~~~ > len = leaf & 15; > ~~~~~~~~~~~~~~~~ > if (len == 0) continue; > ~~~~~~~~~~~~~~~~~~~~~~~ > diff = getbits(len); > ~~~~~~~~~~~~~~~~~~~~ > if ((diff & (1 << (len-1))) == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff -= (1 << len) - 1; > ~~~~~~~~~~~~~~~~~~~~~~~ > if (i < 64) diffbuf[i] = diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > diffbuf[0] += carry; > ~~~~~~~~~~~~~~~~~~~~ > carry = diffbuf[0]; > ~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 64; i++ ) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if (pnum++ % raw_width == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > base[0] = base[1] = 512; > ~~~~~~~~~~~~~~~~~~~~~~~~ > if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > derror(); > ~~~~~~~~~ > } > ~ > } > ~ > if (lowbits) { > ~~~~~~~~~~~~~~ > save = ftell(ifp); > ~~~~~~~~~~~~~~~~~~ > fseek (ifp, 26 + row*raw_width/4, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (prow=pixel, i=0; i < raw_width*2; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > c = fgetc(ifp); > ~~~~~~~~~~~~~~~ > for (r=0; r < 8; r+=2, prow++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > val = (*prow << 2) + ((c >> r) & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (raw_width == 2672 && val < 512) val += 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > *prow = val; > ~~~~~~~~~~~~ > } > ~ > } > ~ > fseek (ifp, save, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > FORC(2) free (huff[c]); > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > /* > ~~ > Not a full implementation of Lossless JPEG, just > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > enough to decode Canon, Kodak and Adobe DNG images. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > struct jhead { > ~~~~~~~~~~~~~~ > int bits, high, wide, clrs, sraw, psv, restart, vpred[6]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort *huff[6], *free[4], *row; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > }; > ~~ > > > int CLASS ljpeg_start (struct jhead *jh, int info_only) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > ushort c, tag, len; > ~~~~~~~~~~~~~~~~~~~ > uchar data[0x10000]; > ~~~~~~~~~~~~~~~~~~~~ > const uchar *dp; > ~~~~~~~~~~~~~~~~ > > > memset (jh, 0, sizeof *jh); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jh->restart = INT_MAX; > ~~~~~~~~~~~~~~~~~~~~~~ > if ((fgetc(ifp),fgetc(ifp)) != 0xd8) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > do { > ~~~~ > if (!fread (data, 2, 2, ifp)) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tag = data[0] << 8 | data[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > len = (data[2] << 8 | data[3]) - 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag <= 0xff00) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (data, 1, len, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > switch (tag) { > ~~~~~~~~~~~~~~ > case 0xffc3: > ~~~~~~~~~~~~ > jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 0xffc1: > ~~~~~~~~~~~~ > case 0xffc0: > ~~~~~~~~~~~~ > jh->algo = tag & 0xff; > ~~~~~~~~~~~~~~~~~~~~~~ > jh->bits = data[0]; > ~~~~~~~~~~~~~~~~~~~ > jh->high = data[1] << 8 | data[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jh->wide = data[3] << 8 | data[4]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jh->clrs = data[5] + jh->sraw; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (len == 9 && !dng_version) getc(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 0xffc4: > ~~~~~~~~~~~~ > if (info_only) break; > ~~~~~~~~~~~~~~~~~~~~~ > for (dp = data; dp < data+len && !((c = *dp++) & -20); ) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jh->free[c] = jh->huff[c] = make_decoder_ref (&dp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 0xffda: > ~~~~~~~~~~~~ > jh->psv = data[1+data[0]*2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jh->bits -= data[3+data[0]*2] & 15; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 0xffdb: > ~~~~~~~~~~~~ > FORC(64) jh->quant[c] = data[c*2+1] << 8 | data[c*2+2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 0xffdd: > ~~~~~~~~~~~~ > jh->restart = data[0] << 8 | data[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } while (tag != 0xffda); > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (jh->bits > 16 || jh->clrs > 6 || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > !jh->bits || !jh->high || !jh->wide || !jh->clrs) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (info_only) return 1; > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (!jh->huff[0]) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(19) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (jh->sraw) { > ~~~~~~~~~~~~~~~ > FORC(4) jh->huff[2+c] = jh->huff[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(jh->sraw) jh->huff[1+c] = jh->huff[0]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > jh->row = (ushort *) calloc (2 * jh->wide*jh->clrs, 4); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (jh->row, "ljpeg_start()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return zero_after_ff = 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS ljpeg_end (struct jhead *jh) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int c; > ~~~~~~ > FORC4 if (jh->free[c]) free (jh->free[c]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > free (jh->row); > ~~~~~~~~~~~~~~~ > } > ~ > > > inline int CLASS ljpeg_diff (ushort *huff) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int len, diff; > ~~~~~~~~~~~~~~ > > > len = gethuff(huff); > ~~~~~~~~~~~~~~~~~~~~ > if (len == 16 && (!dng_version || dng_version >= 0x1010000)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return -32768; > ~~~~~~~~~~~~~~ > diff = getbits(len); > ~~~~~~~~~~~~~~~~~~~~ > if ((diff & (1 << (len-1))) == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff -= (1 << len) - 1; > ~~~~~~~~~~~~~~~~~~~~~~~ > return diff; > ~~~~~~~~~~~~ > } > ~ > > > ushort * CLASS ljpeg_row (int jrow, struct jhead *jh) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int col, c, diff, pred, spred=0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort mark=0, *row[3]; > ~~~~~~~~~~~~~~~~~~~~~~~ > > > if (jrow * jh->wide % jh->restart == 0) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(6) jh->vpred[c] = 1 << (jh->bits-1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (jrow) { > ~~~~~~~~~~~ > fseek (ifp, -2, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > do mark = (mark << 8) + (c = fgetc(ifp)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (c != EOF && mark >> 4 != 0xffd); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > getbits(-1); > ~~~~~~~~~~~~ > } > ~ > FORC3 row[c] = (jh->row + ((jrow & 1) + 1) * (jh->wide*jh->clrs*((jrow+c) & 1))); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < jh->wide; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(jh->clrs) { > ~~~~~~~~~~~~~~~~ > diff = ljpeg_diff (jh->huff[c]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (jh->sraw && c <= jh->sraw && (col | c)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pred = spred; > ~~~~~~~~~~~~~ > else if (col) pred = row[0][-jh->clrs]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else pred = (jh->vpred[c] += diff) - diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (jh->psv != 1 && jrow && col) switch (jh->psv) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 2: pred = row[1][0]; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 3: pred = row[1][-jh->clrs]; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 7: pred = (pred + row[1][0]) >> 1; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > default: pred = 0; > ~~~~~~~~~~~~~~~~~~ > } > ~ > if (UNLIKELY((**row = pred + diff) >> jh->bits)) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (c <= jh->sraw) spred = **row; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row[0]++; row[1]++; > ~~~~~~~~~~~~~~~~~~~ > } > ~ > return row[2]; > ~~~~~~~~~~~~~~ > } > ~ > > > void CLASS lossless_jpeg_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > struct jhead jh; > ~~~~~~~~~~~~~~~~ > int row=0, col=0; > ~~~~~~~~~~~~~~~~~ > > > if (!ljpeg_start (&jh, 0)) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int jwide = jh.wide * jh.clrs; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort *rp[2]; > ~~~~~~~~~~~~~~ > rp[0] = ljpeg_row (0, &jh); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > for (int jrow=0; jrow < jh.high; jrow++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #ifdef _OPENMP > ~~~~~~~~~~~~~~ > #pragma omp parallel sections > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #endif > ~~~~~~ > { > ~ > #ifdef _OPENMP > ~~~~~~~~~~~~~~ > #pragma omp section > ~~~~~~~~~~~~~~~~~~~ > #endif > ~~~~~~ > { > ~ > if(jrow < jh.high - 1) > ~~~~~~~~~~~~~~~~~~~~~~ > rp[(jrow + 1)&1] = ljpeg_row (jrow + 1, &jh); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > #ifdef _OPENMP > ~~~~~~~~~~~~~~ > #pragma omp section > ~~~~~~~~~~~~~~~~~~~ > #endif > ~~~~~~ > { > ~ > if (load_flags & 1) > ~~~~~~~~~~~~~~~~~~~ > row = jrow & 1 ? height-1-jrow/2 : jrow/2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (int jcol=0; jcol < jwide; jcol++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int val = curve[*rp[jrow&1]++]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (cr2_slice[0]) { > ~~~~~~~~~~~~~~~~~~~ > int jidx = jrow*jwide + jcol; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int i = jidx / (cr2_slice[1]*raw_height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int j; > ~~~~~~ > if ((j = i >= cr2_slice[0])) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = cr2_slice[0]; > ~~~~~~~~~~~~~~~~~~ > jidx -= i * (cr2_slice[1]*raw_height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row = jidx / cr2_slice[1+j]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > col = jidx % cr2_slice[1+j] + i*cr2_slice[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (raw_width == 3984 && (col -= 2) < 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > col += (row--,raw_width); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((unsigned) row < raw_height) RAW(row,col) = val; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (++col >= raw_width) > ~~~~~~~~~~~~~~~~~~~~~~~ > col = (row++,0); > ~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > } > ~ > ljpeg_end (&jh); > ~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS canon_sraw_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > struct jhead jh; > ~~~~~~~~~~~~~~~~ > short *rp=0, (*ip)[4]; > ~~~~~~~~~~~~~~~~~~~~~~ > int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int v[3]={0,0,0}, ver, hue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > char *cp; > ~~~~~~~~~ > > > if (!ljpeg_start (&jh, 0) || jh.clrs < 4) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jwide = (jh.wide >>= 1) * jh.clrs; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > for (ecol=slice=0; slice <= cr2_slice[0]; slice++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > scol = ecol; > ~~~~~~~~~~~~ > ecol += cr2_slice[1] * 2 / jh.clrs; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!cr2_slice[0] || ecol > raw_width-1) ecol = raw_width & -2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < height; row += (jh.clrs >> 1) - 1) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ip = (short (*)[4]) image + row*width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=scol; col < ecol; col+=2, jcol+=jh.clrs) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((jcol %= jwide) == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~ > rp = (short *) ljpeg_row (jrow++, &jh); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col >= width) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC (jh.clrs-2) > ~~~~~~~~~~~~~~~~ > ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ip[col][1] = rp[jcol+jh.clrs-2] - 16384; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ip[col][2] = rp[jcol+jh.clrs-1] - 16384; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > for (cp=model2; *cp && !isdigit(*cp); cp++); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sscanf (cp, "%d.%d.%d", v, v+1, v+2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ver = (v[0]*1000 + v[1])*1000 + v[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > hue = (jh.sraw+1) << 2; > ~~~~~~~~~~~~~~~~~~~~~~~ > if (unique_id >= 0x80000281 || (unique_id == 0x80000218 && ver > 1000006)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > hue = jh.sraw << 1; > ~~~~~~~~~~~~~~~~~~~ > ip = (short (*)[4]) image; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > rp = ip[0]; > ~~~~~~~~~~~ > for (row=0; row < height; row++, ip+=width) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (row & (jh.sraw >> 1)) > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col+=2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (c=1; c < 3; c++) > ~~~~~~~~~~~~~~~~~~~~~ > if (row == height-1) > ~~~~~~~~~~~~~~~~~~~~ > ip[col][c] = ip[col-width][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else ip[col][c] = (ip[col-width][c] + ip[col+width][c] + 1) >> 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=1; col < width; col+=2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (c=1; c < 3; c++) > ~~~~~~~~~~~~~~~~~~~~~ > if (col == width-1) > ~~~~~~~~~~~~~~~~~~~ > ip[col][c] = ip[col-1][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else ip[col][c] = (ip[col-1][c] + ip[col+1][c] + 1) >> 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for ( ; rp < ip[0]; rp+=4) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (unique_id == 0x80000218 || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unique_id == 0x80000250 || > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > unique_id == 0x80000261 || > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > unique_id == 0x80000281 || > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > unique_id == 0x80000287) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > rp[1] = (rp[1] << 2) + hue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > rp[2] = (rp[2] << 2) + hue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[0] = rp[0] + (( 50*rp[1] + 22929*rp[2]) >> 14); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[2] = rp[0] + ((29040*rp[1] - 101*rp[2]) >> 14); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else { > ~~~~~~~~ > if (unique_id < 0x80000218) rp[0] -= 512; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[0] = rp[0] + rp[2]; > ~~~~~~~~~~~~~~~~~~~~~~~ > pix[2] = rp[0] + rp[1]; > ~~~~~~~~~~~~~~~~~~~~~~~ > pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > FORC3 rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > ljpeg_end (&jh); > ~~~~~~~~~~~~~~~~ > maximum = 0x3fff; > ~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS adobe_copy_pixel (unsigned row, unsigned col, ushort **rp) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int c; > ~~~~~~ > > > if (tiff_samples == 2 && shot_select) (*rp)++; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (raw_image) { > ~~~~~~~~~~~~~~~~ > if (row < raw_height && col < raw_width) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = curve[**rp]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > *rp += tiff_samples; > ~~~~~~~~~~~~~~~~~~~~ > } else { > ~~~~~~~~ > if (row < height && col < width) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(tiff_samples) > ~~~~~~~~~~~~~~~~~~ > image[row*width+col][c] = curve[(*rp)[c]]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > *rp += tiff_samples; > ~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (tiff_samples == 2 && shot_select) (*rp)--; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS ljpeg_idct (struct jhead *jh) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int c, i, j, len, skip, coef; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float work[3][8][8]; > ~~~~~~~~~~~~~~~~~~~~ > static float cs[106] = { 0 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > static const uchar zigzag[80] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0, 1, 8,16, 9, 2, 3,10,17,24,32,25,18,11, 4, 5,12,19,26,33, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 40,48,41,34,27,20,13, 6, 7,14,21,28,35,42,49,56,57,50,43,36, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 47,55,62,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > if (!cs[0]) > ~~~~~~~~~~~ > FORC(106) cs[c] = cos((c & 31)*M_PI/16)/2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memset (work, 0, sizeof work); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > work[0][0][0] = jh->vpred[0] += ljpeg_diff (jh->huff[0]) * jh->quant[0]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=1; i < 64; i++ ) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > len = gethuff (jh->huff[16]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i += skip = len >> 4; > ~~~~~~~~~~~~~~~~~~~~~ > if (!(len &= 15) && skip < 15) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > coef = getbits(len); > ~~~~~~~~~~~~~~~~~~~~ > if ((coef & (1 << (len-1))) == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > coef -= (1 << len) - 1; > ~~~~~~~~~~~~~~~~~~~~~~~ > ((float *)work)[zigzag[i]] = coef * jh->quant[i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > FORC(8) work[0][0][c] *= M_SQRT1_2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(8) work[0][c][0] *= M_SQRT1_2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 8; i++) > ~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 8; j++) > ~~~~~~~~~~~~~~~~~~~~~ > FORC(8) work[1][i][j] += work[0][i][c] * cs[(j*2+1)*c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 8; i++) > ~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 8; j++) > ~~~~~~~~~~~~~~~~~~~~~ > FORC(8) work[2][i][j] += work[1][c][j] * cs[(i*2+1)*c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > FORC(64) jh->idct[c] = CLIP(((float *)work[2])[c]+0.5); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS lossless_dng_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col, i, j; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > struct jhead jh; > ~~~~~~~~~~~~~~~~ > ushort *rp; > ~~~~~~~~~~~ > > > while (trow < raw_height) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > save = ftell(ifp); > ~~~~~~~~~~~~~~~~~~ > if (tile_length < INT_MAX) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, get4(), SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!ljpeg_start (&jh, 0)) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jwide = jh.wide; > ~~~~~~~~~~~~~~~~ > if (filters) jwide *= jh.clrs; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jwide /= MIN (is_raw, tiff_samples); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > switch (jh.algo) { > ~~~~~~~~~~~~~~~~~~ > case 0xc1: > ~~~~~~~~~~ > jh.vpred[0] = 16384; > ~~~~~~~~~~~~~~~~~~~~ > getbits(-1); > ~~~~~~~~~~~~ > for (jrow=0; jrow+7 < jh.high; jrow += 8) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (jcol=0; jcol+7 < jh.wide; jcol += 8) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ljpeg_idct (&jh); > ~~~~~~~~~~~~~~~~~ > rp = jh.idct; > ~~~~~~~~~~~~~ > row = trow + jcol/tile_width + jrow*2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > col = tcol + jcol%tile_width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 16; i+=2) > ~~~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 8; j++) > ~~~~~~~~~~~~~~~~~~~~~ > adobe_copy_pixel (row+i, col+j, &rp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > break; > ~~~~~~ > case 0xc3: > ~~~~~~~~~~ > for (row=col=jrow=0; jrow < jh.high; jrow++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > rp = ljpeg_row (jrow, &jh); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (jcol=0; jcol < jwide; jcol++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > adobe_copy_pixel (trow+row, tcol+col, &rp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (++col >= tile_width || col >= raw_width) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row += 1 + (col = 0); > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } } > ~~~~~~ > fseek (ifp, save+4, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((tcol += tile_width) >= raw_width) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > trow += tile_length + (tcol = 0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ljpeg_end (&jh); > ~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS packed_dng_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > ushort *pixel, *rp; > ~~~~~~~~~~~~~~~~~~~ > int row, col; > ~~~~~~~~~~~~~ > > > pixel = (ushort *) calloc (raw_width, tiff_samples*sizeof *pixel); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (pixel, "packed_dng_load_raw()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tiff_bps == 16) > ~~~~~~~~~~~~~~~~~~~ > read_shorts (pixel, raw_width * tiff_samples); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else { > ~~~~~~ > getbits(-1); > ~~~~~~~~~~~~ > for (col=0; col < raw_width * tiff_samples; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pixel[col] = getbits(tiff_bps); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (rp=pixel, col=0; col < raw_width; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > adobe_copy_pixel (row, col, &rp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > free (pixel); > ~~~~~~~~~~~~~ > } > ~ > > > void CLASS pentax_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > ushort bit[2][15], huff[4097]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int dep, row, col, diff, c, i; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort vpred[2][2] = {{0,0},{0,0}}, hpred[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > fseek (ifp, meta_offset, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > dep = (get2() + 12) & 15; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 12, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(dep) bit[0][c] = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(dep) bit[1][c] = fgetc(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(dep) > ~~~~~~~~~ > for (i=bit[0][c]; i <= ((bit[0][c]+(4096 >> bit[1][c])-1) & 4095); ) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > huff[++i] = bit[1][c] << 8 | c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > huff[0] = 12; > ~~~~~~~~~~~~~ > fseek (ifp, data_offset, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > getbits(-1); > ~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff = ljpeg_diff (huff); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col < 2) hpred[col] = vpred[row & 1][col] += diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else hpred[col & 1] += diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = hpred[col & 1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (hpred[col & 1] >> tiff_bps) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS nikon_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const uchar nikon_tree[][32] = { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 5,4,3,6,2,7,1,0,8,9,11,10,12 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy after split */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, /* 12-bit lossless */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 5,4,6,3,7,2,8,1,9,0,10,11,12 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0, /* 14-bit lossy */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0, /* 14-bit lossy after split */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0, /* 14-bit lossless */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort *huff, ver0, ver1, vpred[2][2], hpred[2], csize; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int i, min, max, step=0, tree=0, split=0, row, col, len, shl, diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > fseek (ifp, meta_offset, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ver0 = fgetc(ifp); > ~~~~~~~~~~~~~~~~~~ > ver1 = fgetc(ifp); > ~~~~~~~~~~~~~~~~~~ > if (ver0 == 0x49 || ver1 == 0x58) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 2110, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ver0 == 0x46) tree = 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tiff_bps == 14) tree += 3; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > read_shorts (vpred[0], 4); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > max = 1 << tiff_bps & 0x7fff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((csize = get2()) > 1) > ~~~~~~~~~~~~~~~~~~~~~~~~~ > step = max / (csize-1); > ~~~~~~~~~~~~~~~~~~~~~~~ > if (ver0 == 0x44 && ver1 == 0x20 && step > 0) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < csize; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~ > curve[i*step] = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < max; i++) > ~~~~~~~~~~~~~~~~~~~~~~~ > curve[i] = ( curve[i-i%step]*(step-i%step) + > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > curve[i-i%step+step]*(i%step) ) / step; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, meta_offset+562, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > split = get2(); > ~~~~~~~~~~~~~~~ > } else if (ver0 != 0x46 && csize <= 0x4001) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > read_shorts (curve, max=csize); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (curve[max-2] == curve[max-1]) max--; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > huff = make_decoder (nikon_tree[tree]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, data_offset, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > getbits(-1); > ~~~~~~~~~~~~ > for (min=row=0; row < height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (split && row == split) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > free (huff); > ~~~~~~~~~~~~ > huff = make_decoder (nikon_tree[tree+1]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > max += (min = 16) << 1; > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (col=0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = gethuff(huff); > ~~~~~~~~~~~~~~~~~~ > len = i & 15; > ~~~~~~~~~~~~~ > shl = i >> 4; > ~~~~~~~~~~~~~ > diff = ((getbits(len-shl) << 1) + 1) << shl >> 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((diff & (1 << (len-1))) == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff -= (1 << len) - !shl; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col < 2) hpred[col] = vpred[row & 1][col] += diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else hpred[col & 1] += diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((ushort)(hpred[col & 1] + min) >= max) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = curve[LIM((short)hpred[col & 1],0,0x3fff)]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > free (huff); > ~~~~~~~~~~~~ > } > ~ > > > void CLASS nikon_yuv_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int row, col, yuv[4], rgb[3], b, c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > UINT64 bitbuf=0; > ~~~~~~~~~~~~~~~~ > > > for (row=0; row < raw_height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!(b = col & 1)) { > ~~~~~~~~~~~~~~~~~~~~~ > bitbuf = 0; > ~~~~~~~~~~~ > FORC(6) bitbuf |= (UINT64) fgetc(ifp) << c*8; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(4) yuv[c] = (bitbuf >> c*12 & 0xfff) - (c >> 1 << 11); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > rgb[0] = yuv[b] + 1.370705*yuv[3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > rgb[1] = yuv[b] - 0.337633*yuv[2] - 0.698001*yuv[3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > rgb[2] = yuv[b] + 1.732446*yuv[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,0xfff)] / cam_mul[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > /* > ~~ > Returns 1 for a Coolpix 995, 0 for anything else. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > int CLASS nikon_e995() > ~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int i, histo[256]; > ~~~~~~~~~~~~~~~~~~ > const uchar often[] = { 0x00, 0x55, 0xaa, 0xff }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > memset (histo, 0, sizeof histo); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, -2000, SEEK_END); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 2000; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > histo[fgetc(ifp)]++; > ~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 4; i++) > ~~~~~~~~~~~~~~~~~~~~~ > if (histo[often[i]] < 200) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > return 0; > ~~~~~~~~~ > return 1; > ~~~~~~~~~ > } > ~ > > > /* > ~~ > Returns 1 for a Coolpix 2100, 0 for anything else. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > int CLASS nikon_e2100() > ~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar t[12]; > ~~~~~~~~~~~~ > int i; > ~~~~~~ > > > fseek (ifp, 0, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 1024; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (t, 1, 12, ifp); > ~~~~~~~~~~~~~~~~~~~~~~ > if (((t[2] & t[4] & t[7] & t[9]) >> 4 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > & t[1] & t[6] & t[8] & t[11] & 3) != 3) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return 0; > ~~~~~~~~~ > } > ~ > return 1; > ~~~~~~~~~ > } > ~ > > > void CLASS nikon_3700() > ~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int bits, i; > ~~~~~~~~~~~~ > uchar dp[24]; > ~~~~~~~~~~~~~ > static const struct { > ~~~~~~~~~~~~~~~~~~~~~ > int bits; > ~~~~~~~~~ > char make[12], model[15]; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > } table[] = { > ~~~~~~~~~~~~~ > { 0x00, "Pentax", "Optio 33WR" }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0x03, "Nikon", "E3200" }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0x32, "Nikon", "E3700" }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0x33, "Olympus", "C740UZ" } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > fseek (ifp, 3072, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (dp, 1, 24, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~ > bits = (dp[8] & 3) << 4 | (dp[20] & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < sizeof table / sizeof *table; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (bits == table[i].bits) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > strcpy (make, table[i].make ); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > strcpy (model, table[i].model); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > /* > ~~ > Separates a Minolta DiMAGE Z2 from a Nikon E4300. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > int CLASS minolta_z2() > ~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int i, nz; > ~~~~~~~~~~ > char tail[424]; > ~~~~~~~~~~~~~~~ > > > fseek (ifp, -(int)sizeof tail, SEEK_END); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (tail, 1, sizeof tail, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (nz=i=0; i < sizeof tail; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tail[i]) nz++; > ~~~~~~~~~~~~~~~~~~ > return nz > 20; > ~~~~~~~~~~~~~~~ > } > ~ > > > /*RT void CLASS jpeg_thumb(); */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > void CLASS ppm_thumb() > ~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > char *thumb; > ~~~~~~~~~~~~ > thumb_length = thumb_width*thumb_height*3; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > thumb = (char *) malloc (thumb_length); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (thumb, "ppm_thumb()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (thumb, 1, thumb_length, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fwrite (thumb, 1, thumb_length, ofp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > free (thumb); > ~~~~~~~~~~~~~ > } > ~ > > > void CLASS ppm16_thumb() > ~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int i; > ~~~~~~ > char *thumb; > ~~~~~~~~~~~~ > thumb_length = thumb_width*thumb_height*3; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > thumb = (char *) calloc (thumb_length, 2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (thumb, "ppm16_thumb()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > read_shorts ((ushort *) thumb, thumb_length); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < thumb_length; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > thumb[i] = ((ushort *) thumb)[i] >> 8; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fwrite (thumb, 1, thumb_length, ofp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > free (thumb); > ~~~~~~~~~~~~~ > } > ~ > > > void CLASS layer_thumb() > ~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int i, c; > ~~~~~~~~~ > char *thumb, map[][4] = { "012","102" }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > colors = thumb_misc >> 5 & 7; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > thumb_length = thumb_width*thumb_height; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > thumb = (char *) calloc (colors, thumb_length); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (thumb, "layer_thumb()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fprintf (ofp, "P%d\n%d %d\n255\n", > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 5 + (colors >> 1), thumb_width, thumb_height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (thumb, thumb_length, colors, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < thumb_length; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORCC putc (thumb[i+thumb_length*(map[thumb_misc >> 8][c]-'0')], ofp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > free (thumb); > ~~~~~~~~~~~~~ > } > ~ > > > void CLASS rollei_thumb() > ~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned i; > ~~~~~~~~~~~ > ushort *thumb; > ~~~~~~~~~~~~~~ > > > thumb_length = thumb_width * thumb_height; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > thumb = (ushort *) calloc (thumb_length, 2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (thumb, "rollei_thumb()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > read_shorts (thumb, thumb_length); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < thumb_length; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > putc (thumb[i] << 3, ofp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > putc (thumb[i] >> 5 << 2, ofp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > putc (thumb[i] >> 11 << 3, ofp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > free (thumb); > ~~~~~~~~~~~~~ > } > ~ > > > void CLASS rollei_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar pixel[10]; > ~~~~~~~~~~~~~~~~ > unsigned iten=0, isix, i, buffer=0, todo[16]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > isix = raw_width * raw_height * 5 / 8; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (fread (pixel, 1, 10, ifp) == 10) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 10; i+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > todo[i] = iten++; > ~~~~~~~~~~~~~~~~~~~ > todo[i+1] = pixel[i] << 8 | pixel[i+1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > buffer = pixel[i] >> 2 | buffer << 6; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for ( ; i < 16; i+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > todo[i] = isix++; > ~~~~~~~~~~~~~~~~~~~ > todo[i+1] = buffer >> (14-i)*5; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (i=0; i < 16; i+=2) > ~~~~~~~~~~~~~~~~~~~~~~~ > raw_image[todo[i]] = (todo[i+1] & 0x3ff); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > maximum = 0x3ff; > ~~~~~~~~~~~~~~~~ > } > ~ > > > int CLASS raw (unsigned row, unsigned col) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > return (row < raw_height && col < raw_width) ? RAW(row,col) : 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS phase_one_flat_field (int is_float, int nc) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > ushort head[8]; > ~~~~~~~~~~~~~~~ > unsigned wide, high, y, x, c, rend, cend, row, col; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float *mrow, num, mult[4]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > read_shorts (head, 8); > ~~~~~~~~~~~~~~~~~~~~~~ > if (head[2] * head[3] * head[4] * head[5] == 0) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > wide = head[2] / head[4] + (head[2] % head[4] != 0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > high = head[3] / head[5] + (head[3] % head[5] != 0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > mrow = (float *) calloc (nc*wide, sizeof *mrow); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (mrow, "phase_one_flat_field()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (y=0; y < high; y++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (x=0; x < wide; x++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > for (c=0; c < nc; c+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > num = is_float ? getreal(11) : get2()/32768.0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (y==0) mrow[c*wide+x] = num; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else mrow[(c+1)*wide+x] = (num - mrow[c*wide+x]) / head[5]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (y==0) continue; > ~~~~~~~~~~~~~~~~~~~ > rend = head[1] + y*head[5]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row = rend-head[5]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > row < raw_height && row < rend && > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row < head[1]+head[3]-head[5]; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (x=1; x < wide; x++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (c=0; c < nc; c+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > mult[c] = mrow[c*wide+x-1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > mult[c+1] = (mrow[c*wide+x] - mult[c]) / head[4]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > cend = head[0] + x*head[4]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col = cend-head[4]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > col < raw_width && > ~~~~~~~~~~~~~~~~~~ > col < cend && col < head[0]+head[2]-head[4]; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > c = nc > 2 ? FC(row-top_margin,col-left_margin) : 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!(c & 1)) { > ~~~~~~~~~~~~~~~ > c = RAW(row,col) * mult[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = LIM(c,0,65535); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (c=0; c < nc; c+=2) > ~~~~~~~~~~~~~~~~~~~~~~~ > mult[c] += mult[c+1]; > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > for (x=0; x < wide; x++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > for (c=0; c < nc; c+=2) > ~~~~~~~~~~~~~~~~~~~~~~~ > mrow[c*wide+x] += mrow[(c+1)*wide+x]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > free (mrow); > ~~~~~~~~~~~~ > } > ~ > > > void CLASS phase_one_correct() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned entries, tag, data, save, col, row, type; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int len, i, j, k, cip, val[4], dev[4], sum, max; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int head[9], diff, mindiff=INT_MAX, off_412=0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > static const signed char dir[12][2] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { {-1,-1}, {-1,1}, {1,-1}, {1,1}, {-2,0}, {0,-2}, {0,2}, {2,0}, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > {-2,-2}, {-2,2}, {2,-2}, {2,2} }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float poly[8], num, cfrac, frac, mult[2], *yval[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort *xval[2]; > ~~~~~~~~~~~~~~~~ > int qmult_applied = 0, qlin_applied = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > if (half_size || !meta_length) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (verbose) fprintf (stderr,_("Phase One correction...\n")); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, meta_offset, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > order = get2(); > ~~~~~~~~~~~~~~~ > fseek (ifp, 6, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, meta_offset+get4(), SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > entries = get4(); get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (entries--) { > ~~~~~~~~~~~~~~~~~~~ > tag = get4(); > ~~~~~~~~~~~~~~ > len = get4(); > ~~~~~~~~~~~~~~ > data = get4(); > ~~~~~~~~~~~~~~ > save = ftell(ifp); > ~~~~~~~~~~~~~~~~~~ > fseek (ifp, meta_offset+data, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0x419) { /* Polynomial curve */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (get4(), i=0; i < 8; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > poly[i] = getreal(11); > ~~~~~~~~~~~~~~~~~~~~~~ > poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 0x10000; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > num = (poly[5]*i + poly[3])*i + poly[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > curve[i] = LIM(num,0,65535); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } goto apply; /* apply to right half */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else if (tag == 0x41a) { /* Polynomial curve */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 4; i++) > ~~~~~~~~~~~~~~~~~~~~~ > poly[i] = getreal(11); > ~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 0x10000; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (num=0, j=4; j--; ) > ~~~~~~~~~~~~~~~~~~~~~~~ > num = num * i + poly[j]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > curve[i] = LIM(num+i,0,65535); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } apply: /* apply to whole image */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col = (tag & 1)*ph1.split_col; col < raw_width; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = curve[RAW(row,col)]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else if (tag == 0x400) { /* Sensor defects */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while ((len -= 8) >= 0) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > col = get2(); > ~~~~~~~~~~~~~~ > row = get2(); > ~~~~~~~~~~~~~~ > type = get2(); get2(); > ~~~~~~~~~~~~~~~~~~~~~~ > if (col >= raw_width) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (type == 131 || type == 137) /* Bad column */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (FC(row-top_margin,col-left_margin) == 1) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (sum=i=0; i < 4; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~ > sum += val[i] = raw (row+dir[i][0], col+dir[i][1]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (max=i=0; i < 4; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > dev[i] = abs((val[i] << 2) - sum); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (dev[max] < dev[i]) max = i; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > RAW(row,col) = (sum - val[max])/3.0 + 0.5; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else { > ~~~~~~~~ > for (sum=0, i=8; i < 12; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sum += raw (row+dir[i][0], col+dir[i][1]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = 0.5 + sum * 0.0732233 + > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (raw(row,col-2) + raw(row,col+2)) * 0.3535534; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > else if (type == 129) { /* Bad pixel */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (row >= raw_height) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > j = (FC(row-top_margin,col-left_margin) != 1) * 4; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (sum=0, i=j; i < j+8; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sum += raw (row+dir[i][0], col+dir[i][1]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = (sum + 4) >> 3; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } else if (tag == 0x401) { /* All-color flat fields */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > phase_one_flat_field (1, 2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else if (tag == 0x416 || tag == 0x410) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > phase_one_flat_field (0, 2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else if (tag == 0x40b) { /* Red+blue flat field */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > phase_one_flat_field (0, 4); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else if (tag == 0x412) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 36, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff = abs (get2() - ph1.tag_21a); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (mindiff > diff) { > ~~~~~~~~~~~~~~~~~~~~~ > mindiff = diff; > ~~~~~~~~~~~~~~~ > off_412 = ftell(ifp) - 38; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } else if (tag == 0x41f && !qlin_applied) { /* Quadrant linearization */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort lc[2][2][16], ref[16]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int qr, qc; > ~~~~~~~~~~~ > for (qr = 0; qr < 2; qr++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (qc = 0; qc < 2; qc++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i = 0; i < 16; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > lc[qr][qc][i] = get4(); > ~~~~~~~~~~~~~~~~~~~~~~~ > for (i = 0; i < 16; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > int v = 0; > ~~~~~~~~~~ > for (qr = 0; qr < 2; qr++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (qc = 0; qc < 2; qc++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > v += lc[qr][qc][i]; > ~~~~~~~~~~~~~~~~~~~ > ref[i] = (v + 2) >> 2; > ~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (qr = 0; qr < 2; qr++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (qc = 0; qc < 2; qc++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int cx[19], cf[19]; > ~~~~~~~~~~~~~~~~~~~ > for (i = 0; i < 16; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > cx[1+i] = lc[qr][qc][i]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > cf[1+i] = ref[i]; > ~~~~~~~~~~~~~~~~~ > } > ~ > cx[0] = cf[0] = 0; > ~~~~~~~~~~~~~~~~~~ > cx[17] = cf[17] = ((unsigned) ref[15] * 65535) / lc[qr][qc][15]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cx[18] = cf[18] = 65535; > ~~~~~~~~~~~~~~~~~~~~~~~~ > cubic_spline(cx, cf, 19); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row = (qr ? ph1.split_row : 0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row < (qr ? raw_height : ph1.split_row); row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col = (qc ? ph1.split_col : 0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > col < (qc ? raw_width : ph1.split_col); col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = curve[RAW(row,col)]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > qlin_applied = 1; > ~~~~~~~~~~~~~~~~~ > } else if (tag == 0x41e && !qmult_applied) { /* Quadrant multipliers */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float qmult[2][2] = { { 1, 1 }, { 1, 1 } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > get4(); get4(); get4(); get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > qmult[0][0] = 1.0 + getreal(11); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > get4(); get4(); get4(); get4(); get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > qmult[0][1] = 1.0 + getreal(11); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > get4(); get4(); get4(); > ~~~~~~~~~~~~~~~~~~~~~~~ > qmult[1][0] = 1.0 + getreal(11); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > get4(); get4(); get4(); > ~~~~~~~~~~~~~~~~~~~~~~~ > qmult[1][1] = 1.0 + getreal(11); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = qmult[row >= ph1.split_row][col >= ph1.split_col] * RAW(row,col); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = LIM(i,0,65535); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > qmult_applied = 1; > ~~~~~~~~~~~~~~~~~~ > } else if (tag == 0x431 && !qmult_applied) { /* Quadrant combined */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort lc[2][2][7], ref[7]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int qr, qc; > ~~~~~~~~~~~ > for (i = 0; i < 7; i++) > ~~~~~~~~~~~~~~~~~~~~~~~ > ref[i] = get4(); > ~~~~~~~~~~~~~~~~ > for (qr = 0; qr < 2; qr++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (qc = 0; qc < 2; qc++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i = 0; i < 7; i++) > ~~~~~~~~~~~~~~~~~~~~~~~ > lc[qr][qc][i] = get4(); > ~~~~~~~~~~~~~~~~~~~~~~~ > for (qr = 0; qr < 2; qr++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (qc = 0; qc < 2; qc++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int cx[9], cf[9]; > ~~~~~~~~~~~~~~~~~ > for (i = 0; i < 7; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > cx[1+i] = ref[i]; > ~~~~~~~~~~~~~~~~~ > cf[1+i] = ((unsigned) ref[i] * lc[qr][qc][i]) / 10000; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > cx[0] = cf[0] = 0; > ~~~~~~~~~~~~~~~~~~ > cx[8] = cf[8] = 65535; > ~~~~~~~~~~~~~~~~~~~~~~ > cubic_spline(cx, cf, 9); > ~~~~~~~~~~~~~~~~~~~~~~~~ > for (row = (qr ? ph1.split_row : 0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row < (qr ? raw_height : ph1.split_row); row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col = (qc ? ph1.split_col : 0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > col < (qc ? raw_width : ph1.split_col); col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = curve[RAW(row,col)]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > qmult_applied = 1; > ~~~~~~~~~~~~~~~~~~ > qlin_applied = 1; > ~~~~~~~~~~~~~~~~~ > } > ~ > fseek (ifp, save, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (off_412) { > ~~~~~~~~~~~~~~ > fseek (ifp, off_412, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 9; i++) head[i] = get4() & 0x7fff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > yval[0] = (float *) calloc (head[1]*head[3] + head[2]*head[4], 6); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (yval[0], "phase_one_correct()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > yval[1] = (float *) (yval[0] + head[1]*head[3]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > xval[0] = (ushort *) (yval[1] + head[2]*head[4]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > xval[1] = (ushort *) (xval[0] + head[1]*head[3]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > get2(); > ~~~~~~~ > for (i=0; i < 2; i++) > ~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < head[i+1]*head[i+3]; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > yval[i][j] = getreal(11); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 2; i++) > ~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < head[i+1]*head[i+3]; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > xval[i][j] = get2(); > ~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cfrac = (float) col * head[3] / raw_width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cfrac -= cip = cfrac; > ~~~~~~~~~~~~~~~~~~~~~ > num = RAW(row,col) * 0.5; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=cip; i < cip+2; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (k=j=0; j < head[1]; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (num < xval[0][k = head[1]*i+j]) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > frac = (j == 0 || j == head[1]) ? 0 : > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (xval[0][k] - num) / (xval[0][k] - xval[0][k-1]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > mult[i-cip] = yval[0][k-1] * frac + yval[0][k] * (1-frac); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > i = ((mult[0] * (1-cfrac) + mult[1] * cfrac) * row + num) * 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = LIM(i,0,65535); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > free (yval[0]); > ~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS phase_one_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int a, b, i; > ~~~~~~~~~~~~ > ushort akey, bkey, mask; > ~~~~~~~~~~~~~~~~~~~~~~~~ > > > fseek (ifp, ph1.key_off, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > akey = get2(); > ~~~~~~~~~~~~~~ > bkey = get2(); > ~~~~~~~~~~~~~~ > mask = ph1.format == 1 ? 0x5555:0x1354; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, data_offset, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > read_shorts (raw_image, raw_width*raw_height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ph1.format) > ~~~~~~~~~~~~~~~ > for (i=0; i < raw_width*raw_height; i+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > a = raw_image[i+0] ^ akey; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > b = raw_image[i+1] ^ bkey; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > raw_image[i+0] = (a & mask) | (b & ~mask); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > raw_image[i+1] = (b & mask) | (a & ~mask); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > unsigned CLASS ph1_bithuff_t::operator() (int nbits, ushort *huff) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > /*RT static UINT64 bitbuf=0; */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > /*RT static int vbits=0; */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unsigned c; > ~~~~~~~~~~~ > > > if (nbits == -1) > ~~~~~~~~~~~~~~~~ > return bitbuf = vbits = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (nbits == 0) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if (vbits < nbits) { > ~~~~~~~~~~~~~~~~~~~~ > bitbuf = bitbuf << 32 | get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > vbits += 32; > ~~~~~~~~~~~~ > } > ~ > c = bitbuf << (64-vbits) >> (64-nbits); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (huff) { > ~~~~~~~~~~~ > vbits -= huff[c] >> 8; > ~~~~~~~~~~~~~~~~~~~~~~ > return (uchar) huff[c]; > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > vbits -= nbits; > ~~~~~~~~~~~~~~~ > return c; > ~~~~~~~~~ > } > ~ > #define ph1_bits(n) ph1_bithuff(n,0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define ph1_huff(h) ph1_bithuff(*h,h+1) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > void CLASS phase_one_load_raw_c() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const int length[] = { 8,7,6,9,11,10,5,12,14,13 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int *offset, len[2], pred[2], row, col, i, j; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort *pixel; > ~~~~~~~~~~~~~~ > short (*cblack)[2], (*rblack)[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > pixel = (ushort *) calloc (raw_width*3 + raw_height*4, 2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (pixel, "phase_one_load_raw_c()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > offset = (int *) (pixel + raw_width); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, strip_offset, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > offset[row] = get4(); > ~~~~~~~~~~~~~~~~~~~~~ > cblack = (short (*)[2]) (offset + raw_height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, ph1.black_col, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ph1.black_col) > ~~~~~~~~~~~~~~~~~~ > read_shorts ((ushort *) cblack[0], raw_height*2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > rblack = cblack + raw_height; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, ph1.black_row, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ph1.black_row) > ~~~~~~~~~~~~~~~~~~ > read_shorts ((ushort *) rblack[0], raw_width*2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 256; i++) > ~~~~~~~~~~~~~~~~~~~~~~~ > curve[i] = i*i / 3.969 + 0.5; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, data_offset + offset[row], SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ph1_bits(-1); > ~~~~~~~~~~~~~ > pred[0] = pred[1] = 0; > ~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col >= (raw_width & -8)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > len[0] = len[1] = 14; > ~~~~~~~~~~~~~~~~~~~~~ > else if ((col & 7) == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 2; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 5 && !ph1_bits(1); j++); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (j--) len[i] = length[j*2 + ph1_bits(1)]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if ((i = len[col & 1]) == 14) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pixel[col] = pred[col & 1] = ph1_bits(16); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else > ~~~~ > pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (pred[col & 1] >> 16) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ph1.format == 5 && pixel[col] < 256) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pixel[col] = curve[pixel[col]]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (col=0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = (pixel[col] << 2*(ph1.format != 8)) - ph1.black > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > + cblack[row][col >= ph1.split_col] > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > + rblack[col][row >= ph1.split_row]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (i > 0) RAW(row,col) = i; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > free (pixel); > ~~~~~~~~~~~~~ > maximum = 0xfffc - ph1.black; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS parse_hasselblad_gain() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > /* > ~~ > Reverse-engineer's notes: > ~~~~~~~~~~~~~~~~~~~~~~~~~ > > > The Hasselblad gain tag (0x19 in makernotes) is only available in the 3FR format and > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > is applied and removed when Hasselblad Phocus converts it to the FFF format. It's > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > always 0x300000 bytes large regardless of (tested) model, not all space in it is > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > used though. > ~~~~~~~~~~~~ > > > It contains individual calibration information from the factory to tune the sensor > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > performance. > ~~~~~~~~~~~~ > > > There is more calibration data in the tag than what is applied in conversion to FFF, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > I've only cared to figure out the data which is actually used, but have some leads on > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > remaining info. > ~~~~~~~~~~~~~~~ > > > The format is not equal between all models. Due to lack of 3FR files (harder to get > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > than FFF) only a subset of the models have been reverse-engineered. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > The header space is 512 bytes and is a mix of 16 and 32 bit values. Offset to blocks > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > are 32 bit values, but all information seems to be encoded in 16 bit values. Many > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > values in the header can be zeroed with no effect on FFF conversion, and their > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > meaning, if any, have not been further investigated. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > Formats: > ~~~~~~~~ > hdr16[22] = raw width > ~~~~~~~~~~~~~~~~~~~~~ > hdr16[23] = raw height > ~~~~~~~~~~~~~~~~~~~~~~ > hdr32[24] = offset to level corr block > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > Data block format. Seems to differ depending on sensor type. For tested H4D-50 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > and H3D-31: 10 16 bit signed values per row > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > value 0: a correction factor (k) used on even columns, where the new pixel value is > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > calulated as follows: > ~~~~~~~~~~~~~~~~~~~~~ > new_value = old_value + (2 * ((k * (old_value_on_row_above-256)) / 32767) - 2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > note the connection to the value on the row above, seems to be some sort of signal > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > leakage correction. > ~~~~~~~~~~~~~~~~~~~ > value 1: same as value 0 but using old value on row below instead of above > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > value 2-3: same as value 0-1 but for odd columns > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > value 4-9: has some effect if non-zero (probably similar to the others) but not > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > investigated which, as it's seems to be always zero for the tested cameras. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > hdr32[25] = probably offset to "bad/unreliable pixels" info, always 512 as it starts > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > directly after the header. Not applied in FFF conversion (at least > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > typically). > ~~~~~~~~~~~ > Data block format guess: raw_height packets of > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > <type?><number of coords><coords...> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > hdr32[27] = offset to unknown data (bad colulmns?), of the form: > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > <packet count><packets><0> > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > packet: <column><?><?><?>. > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > hdr32[34] = curves offset, seems to be A/D curves (one per channel) on newer models > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > and some sort of a film curve on older. Not applied in FFF conversion. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > hdr32[36] = flatfield correction, not available in older models. Data format: > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > <1><block width><block height><rows><cols><11 * 2 pad><packets> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > packet: <R><G1><G2><B> > ~~~~~~~~~~~~~~~~~~~~~~ > > > The header pad is not zeroed and might seem to contain some sort of > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > information, but it makes no difference if set to zero. See > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > hasselblad_correct() how the flatfield is applied. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > Applied in FFF conversion is levels, flatfield correction, and the bad columns(?) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > data. A/D curves are surprisingly not applied, maybe pre-applied in hardware and > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > only available as information? Levels are applied before flatfield, further > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ordering has not been investigated. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > Not all combinations/models have been tested so there may be gaps. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > Most clipped pixels in a 3FR is at 65535, but there's also some at 65534. Both > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > are set to 65535 when calibrated, while 65533 is treated as a normal value. In > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > the calibration process smaller values can be scaled to 65534 (which should > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > not be seen as clipped). > ~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > > > ushort raw_h, count, ch_count, u16; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int i, offset; > ~~~~~~~~~~~~~~ > off_t base; > ~~~~~~~~~~~ > > > base = ftell(ifp); > ~~~~~~~~~~~~~~~~~~ > fseek(ifp, 2 * 23, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > raw_h = get2(); > ~~~~~~~~~~~~~~~ > fseek(ifp, 48, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > offset = get4(); > ~~~~~~~~~~~~~~~~ > hbd.levels = offset ? base + offset : 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek(ifp, 8, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~ > offset = get4(); > ~~~~~~~~~~~~~~~~ > hbd.unknown1 = offset ? base + offset : 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek(ifp, 32, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > offset = get4(); > ~~~~~~~~~~~~~~~~ > hbd.flatfield = offset ? base + offset : 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS hasselblad_correct() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned col, row; > ~~~~~~~~~~~~~~~~~~ > > > /* > ~~ > > > This function applies 3FR calibration data. At the time of writing it supports a > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > subset, so here's a todo list: > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > TODO: > ~~~~~ > - Support all gain tag formats > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > - The 0x19 tag varies a bit between models. We don't have parsers for all models. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > - The reference model used was during inital reverse-engineering was a H4D-50, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > we probably support the Hasselblads with Kodak 31, 39, 40 and 50 megapixels > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > well, but more work is needed for Kodak 16 and 22, Dalsa 60 and Sony 50. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > - Apply bad column(?) data (hbd.unknown1) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > - It was left out in this initial release since the effect is very small. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > - Apply black(?) data, tag 0x1a and 0x1b is not parsed, it has however marginal > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > effect (at least for shorter exposures) so it's not too important. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > While there are things to do, the current implementation supports the most > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > important aspects, the faltfield and levels calibrations applied can have strong > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > visible effects. > ~~~~~~~~~~~~~~~~ > > > */ > ~~ > > > if (hbd.levels) { > ~~~~~~~~~~~~~~~~~ > int i; > ~~~~~~ > fseek(ifp, hbd.levels, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > /* skip the first set (not used as we don't apply on first/last row), we look at it though to see if > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > the levels format is one that we support (there are other formats on some models which is not > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > supported here) */ > ~~~~~~~~~~~~~~~~~~ > short test[10]; > ~~~~~~~~~~~~~~~ > for (i = 0; i < 10; i++) test[i] = (short)get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (test[5] == 0 && test[6] == 0 && test[7] == 0 && test[8] == 0 && test[9] == 0) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int corr[4]; > ~~~~~~~~~~~~ > ushort *row_above = (ushort *)malloc(sizeof(ushort) * raw_width); // we need to cache row above as we write new values as we go > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col = 0; col < raw_width; col++) row_above[col] = RAW(0,col); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row = 1; row < raw_height-1; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i = 0; i < 4; i++) corr[i] = (short)get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek(ifp, 6 * 2, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col = 0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unsigned v = RAW(row,col); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (v >= 65534) { > ~~~~~~~~~~~~~~~~~ > v = 65535; > ~~~~~~~~~~ > } else { > ~~~~~~~~ > if (corr[((col & 1)<<1)+0] && row_above[col] > black) v += 2 * ((corr[((col & 1)<<1)+0] * (row_above[col]-(int)black)) / 32767) - 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (corr[((col & 1)<<1)+1] && RAW(row+1,col) > black) v += 2 * ((corr[((col & 1)<<1)+1] * (RAW(row+1,col)-(int)black)) / 32767) - 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > row_above[col] = RAW(row,col); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = CLIP(v); > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > free(row_above); > ~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > if (hbd.flatfield) { > ~~~~~~~~~~~~~~~~~~~~ > int bw, bh, ffrows, ffcols, i, c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort ref[4], ref_max; > ~~~~~~~~~~~~~~~~~~~~~~~ > fseek(ifp, hbd.flatfield, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > get2(); > ~~~~~~~ > bw = get2(); > ~~~~~~~~~~~~ > bh = get2(); > ~~~~~~~~~~~~ > ffcols = get2(); > ~~~~~~~~~~~~~~~~ > ffrows = get2(); > ~~~~~~~~~~~~~~~~ > fseek(ifp, hbd.flatfield + 16 * 2, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > ushort *ffmap = (ushort *)malloc(sizeof(*ffmap) * 4 * ffcols * ffrows); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i = 0; i < 4 * ffcols * ffrows; i++) ffmap[i] = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > /* Get reference values from center of field. This seems to be what Phocus does too, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > but haven't cared to figure out exactly at which coordinate */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = 4 * (ffcols * ffrows / 2 + ffcols / 2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ref[0] = ffmap[i+0]; > ~~~~~~~~~~~~~~~~~~~~ > ref[1] = ffmap[i+1]; > ~~~~~~~~~~~~~~~~~~~~ > ref[3] = ffmap[i+2]; // G2 = index 3 in dcraw, 2 in 3FR > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ref[2] = ffmap[i+3]; > ~~~~~~~~~~~~~~~~~~~~ > ref_max = 0; > ~~~~~~~~~~~~ > FORC4 if (ref[c] > ref_max) ref_max = ref[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ref_max == 0) ref[0] = ref[1] = ref[2] = ref[3] = ref_max = 10000; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > /* Convert measured flatfield values to actual multipliers. The measured flatfield > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > can have vignetting which should be normalized, only color cast should be corrected. */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i = 0; i < 4 * ffcols * ffrows; i += 4) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > double base, min = 65535.0, max = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > double cur[4]; > ~~~~~~~~~~~~~~ > cur[0] = (double)ffmap[i+0] / ref[0]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cur[1] = (double)ffmap[i+1] / ref[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cur[3] = (double)ffmap[i+2] / ref[3]; // G2 index differs in dcraw and 3FR > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cur[2] = (double)ffmap[i+3] / ref[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 { > ~~~~~~~ > if (cur[c] < min) min = cur[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (cur[c] > max) max = cur[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (max == 0) max = 1.0; > ~~~~~~~~~~~~~~~~~~~~~~~~ > base = (cur[0]+cur[1]+cur[2]+cur[3])/(max*4); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 cur[c] = cur[c] == 0 ? 1.0 : (base * max) / cur[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > /* convert to integer multiplier and store back to ffmap, we limit > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > range to 4 (16384*4) which should be fine for flatfield */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 { > ~~~~~~~ > cur[c] *= 16384.0; > ~~~~~~~~~~~~~~~~~~ > if (cur[c] > 65535.0) cur[c] = 65535.0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ffmap[i+c] = (ushort)cur[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > // of the cameras we've tested we know the exact placement of the flatfield map > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int row_offset, col_offset; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > switch (raw_width) { > ~~~~~~~~~~~~~~~~~~~~ > case 8282: // 50 megapixel Kodak > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row_offset = 21; > ~~~~~~~~~~~~~~~~ > col_offset = 71; > ~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > default: > ~~~~~~~~ > /* Default case for camera models we've not tested. We center the map, which may > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > not be exactly where it should be but close enough for the smooth flatfield */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row_offset = (raw_height - bh * ffrows) / 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > col_offset = (raw_width - bw * ffcols) / 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > } > ~ > > > /* > ~~ > Concerning smoothing between blocks in the map Phocus makes it only vertically, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > probably because it's simpler and faster. Looking at actual flatfield data it seems > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > like it's better to smooth in both directions. Possibly flatfield could be used for > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > correcting tiling on Dalsa sensors (H4D-60) like partly done in Phase One IIQ format, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > and then sharp edges may be beneficial at least at the tiling seams, but at the time > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > of writing I've had no H4D-60 3FR files to test with to verify that. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > Meanwhile we do both vertical and horizontal smoothing/blurring. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > > > /* pre-calculate constants for blurring. We probably should make a more efficient > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > blur than this, but this does not need any buffer and makes nice-looking > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > radial gradients */ > ~~~~~~~~~~~~~~~~~~~ > ushort *corners_weight = (ushort *)malloc(bw*bh*9*sizeof(*corners_weight)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > const int corners_mix[9][4][2] = { { {0,0}, {0,1}, {1,0}, {1,1} }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { {0,1}, {1,1}, {-1,-1}, {-1,-1} }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { {0,1}, {0,2}, {1,1}, {1,2} }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { {1,0}, {1,1}, {-1,-1}, {-1,-1} }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { {1,1}, {-1,-1}, {-1,-1}, {-1,-1} }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { {1,1}, {1,2}, {-1,-1}, {-1,-1} }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { {1,0}, {1,1}, {2,0}, {2,1} }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { {1,1}, {2,1}, {-1,-1}, {-1,-1} }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { {1,1}, {1,2}, {2,1}, {2,2} } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > const ushort corners_shift[9] = { 2, 1, 2, 1, 0, 1, 2, 1, 2 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row = 0; row < bh; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > const ushort maxdist = bw < bh ? bw/2-1 : bh/2-1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > const unsigned bwu = (unsigned)bw; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > const unsigned bhu = (unsigned)bh; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > const unsigned corners[9][2] = {{0,0}, {0,bwu/2}, {0,bwu-1}, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > {bhu/2,0},{bhu/2,bwu/2},{bhu/2,bwu-1}, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > {bhu-1,0},{bhu-1,bwu/2},{bhu-1,bwu-1}}; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col = 0; col < bw; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i = 0; i < 9; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort dist = (ushort)sqrt(abs(corners[i][0] - row) * abs(corners[i][0] - row) + abs(corners[i][1] - col) * abs(corners[i][1] - col)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort weight = dist > maxdist ? 0 : maxdist - dist; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > corners_weight[9*(row*bw+col)+i] = weight; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > > > // apply flatfield > ~~~~~~~~~~~~~~~~~~ > #pragma omp parallel for > ~~~~~~~~~~~~~~~~~~~~~~~~ > for (int row = 0; row < raw_height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int ffs, cur_ffr, i, c; > ~~~~~~~~~~~~~~~~~~~~~~~ > if (row < row_offset) { > ~~~~~~~~~~~~~~~~~~~~~~~ > cur_ffr = row_offset; > ~~~~~~~~~~~~~~~~~~~~~ > ffs = 0; > ~~~~~~~~ > } else if (row >= row_offset + ffrows * bh) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cur_ffr = row_offset + (ffrows-1) * bh; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ffs = 4 * ffcols * (ffrows-1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else { > ~~~~~~~~ > cur_ffr = row_offset + bh * ((row - row_offset) / bh); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ffs = 4 * ffcols * ((row - row_offset) / bh); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > int next_ffc = 0, cur_ffc = col_offset; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int ffc = ffs; > ~~~~~~~~~~~~~~ > ushort *cur[3][3]; // points to local ffmap entries with center at cur[1][1] > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (int col = 0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col == next_ffc) { > ~~~~~~~~~~~~~~~~~~~~~~ > int rowsub = ffs == 0 ? 0 : ffcols*4; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int rowadd = ffs == 4 * ffcols * (ffrows-1) ? 0 : ffcols * 4; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int colsub = ffc == ffs ? 0 : 4; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int coladd = ffc == ffs + 4 * (ffcols-1) ? 0 : 4; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col != 0) cur_ffc = next_ffc; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else next_ffc += col_offset; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > next_ffc += bw; > ~~~~~~~~~~~~~~~ > > > cur[0][0] = &ffmap[ffc-rowsub-colsub]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cur[0][1] = &ffmap[ffc-rowsub]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cur[0][2] = &ffmap[ffc-rowsub+coladd]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > cur[1][0] = &ffmap[ffc-colsub]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cur[1][1] = &ffmap[ffc]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > cur[1][2] = &ffmap[ffc+coladd]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > cur[2][0] = &ffmap[ffc+rowadd-colsub]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cur[2][1] = &ffmap[ffc+rowadd]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cur[2][2] = &ffmap[ffc+rowadd+coladd]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > ffc += 4; > ~~~~~~~~~ > if (ffc == ffs + 4 * ffcols) next_ffc += raw_width; // last col in map, avoid stepping further > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > unsigned v = RAW(row,col); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (v > black && v < 65535) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > c = FC(row,col); > ~~~~~~~~~~~~~~~~ > unsigned x = col < cur_ffc ? 0 : col - cur_ffc; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unsigned y = row < cur_ffr ? 0 : row - cur_ffr; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (x >= bw) x = bw-1; > ~~~~~~~~~~~~~~~~~~~~~~ > if (y >= bh) y = bh-1; > ~~~~~~~~~~~~~~~~~~~~~~ > unsigned wsum = 0; > ~~~~~~~~~~~~~~~~~~ > unsigned mul = 0; > ~~~~~~~~~~~~~~~~~ > for (i = 0; i < 9; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort cw = corners_weight[9*(y*bw+x)+i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (cw) { > ~~~~~~~~~ > unsigned m = 0; > ~~~~~~~~~~~~~~~ > int j; > ~~~~~~ > for (j = 0; j < 1 << corners_shift[i]; j++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int cr = corners_mix[i][j][0], cc = corners_mix[i][j][1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > m += cur[cr][cc][c]; > ~~~~~~~~~~~~~~~~~~~~ > } > ~ > m >>= corners_shift[i]; > ~~~~~~~~~~~~~~~~~~~~~~~ > mul += m * cw; > ~~~~~~~~~~~~~~ > wsum += cw; > ~~~~~~~~~~~ > } > ~ > } > ~ > mul /= wsum; > ~~~~~~~~~~~~ > v = black + ((v-black) * mul) / 16384; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = v > 65535 ? 65535 : v; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > free(ffmap); > ~~~~~~~~~~~~ > free(corners_weight); > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS hasselblad_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > struct jhead jh; > ~~~~~~~~~~~~~~~~ > int shot, row, col, *back[5], len[2], diff[12], pred, sh, f, s, c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unsigned upix, urow, ucol; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort *ip; > ~~~~~~~~~~~ > > > if (!ljpeg_start (&jh, 0)) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > order = 0x4949; > ~~~~~~~~~~~~~~~ > ph1_bits(-1); > ~~~~~~~~~~~~~ > back[4] = (int *) calloc (raw_width, 3*sizeof **back); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (back[4], "hasselblad_load_raw()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 back[c] = back[4] + c*raw_width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cblack[6] >>= sh = tiff_samples > 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > shot = LIM(shot_select, 1, tiff_samples) - 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 back[(c+3) & 3] = back[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width; col+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (s=0; s < tiff_samples*2; s+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(2) len[c] = ph1_huff(jh.huff[0]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(2) { > ~~~~~~~~~ > diff[s+c] = ph1_bits(len[c]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((diff[s+c] & (1 << (len[c]-1))) == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff[s+c] -= (1 << len[c]) - 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (diff[s+c] == 65535) diff[s+c] = -32768; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > for (s=col; s < col+2; s++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pred = 0x8000 + load_flags; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col) pred = back[2][s-2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col && row > 1) switch (jh.psv) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 11: pred += back[0][s]/2 - back[0][s-2]/2; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > f = (row & 1)*3 ^ ((col+s) & 1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC (tiff_samples) { > ~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:2131:2: note: in expansion of macro 'FORC' > FORC (tiff_samples) { > ^~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::unpacked_load_raw()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:2186:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > while (1 << ++bits < maximum); > ~~~~~~~~~~~~^~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::kodak_radc_load_raw()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:2536:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (s=i=0; i < sizeof src; i+=2) > ~~^~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:2542:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (i=0; i < sizeof(buf)/sizeof(short); i++) > ~~^~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:2551:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (i=0; i < sizeof(buf[0])/sizeof(short); i++) > ~~^~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::smal_decode_segment(unsigned int (*)[2], int)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:3182:27: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (pix=seg[0][0]; pix < seg[1][0]; pix++) { > ~~~~^~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:3197:7: warning: this 'for' clause does not guard... [-Wmisleading-indentation] > for (bin=0; hist[s][bin+5] > count; bin++); > ^~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:3198:3: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for' > low = hist[s][bin+5] * (high >> 4) >> 2; > ^~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:3222:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if (ftell(ifp) + 12 >= seg[1][1]) > ~~~~~~~~~~~~~~~~^~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::foveon_decoder(unsigned int, unsigned int)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:3365:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (i=0; i < size; i++) > ~~^~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:3376:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (i=0; i < size; i++) > ~~^~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::foveon_interpolate()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:3807:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if ((irow = frow) == dim[2]-1) irow--; > ~~~~~~~~~~~~~~^~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:3809:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (i=0; i < dim[1]; i++) > ~~^~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:3843:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (i=0; i < dim[0]; i++) { > ~~^~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:3846:29: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if ((unsigned)(row-1) > height-3 || (unsigned)(col-1) > width-3) > ~~~~~~~~~~~~~~~~~~^~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:3846:61: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if ((unsigned)(row-1) > height-3 || (unsigned)(col-1) > width-3) > ~~~~~~~~~~~~~~~~~~^~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::scale_colors()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:4534:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if (val > maximum-25) goto skip_block; > ~~~~^~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:4607:9: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if (ur > iheight-2) continue; > ~~~^~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:4611:11: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if (uc > iwidth-2) continue; > ~~~^~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::pre_interpolate()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:4636:6: warning: this 'if' clause does not guard... [-Wmisleading-indentation] > if (!(image[row*width+col][0] | image[row*width+col][2])) > ^~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:4637:22: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if' > goto break2; break2: > ^~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::parse_makernote(int, int)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:5303:36: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > while ((c = fgetc(ifp)) && c != EOF) > ^ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::parse_gps(int)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:124:19: warning: this 'for' clause does not guard... [-Wmisleading-indentation] > #define FORC(cnt) for (c=0; c < cnt; c++) > ^ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:5525:2: note: in expansion of macro 'FORC' > FORC(6) gpsdata[tag/3*6+c] = get4(); break; > ^~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:5525:40: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for' > FORC(6) gpsdata[tag/3*6+c] = get4(); break; > ^~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:124:19: warning: this 'for' clause does not guard... [-Wmisleading-indentation] > #define FORC(cnt) for (c=0; c < cnt; c++) > ^ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:5527:2: note: in expansion of macro 'FORC' > FORC(2) gpsdata[18+c] = get4(); break; > ^~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:5527:36: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for' > FORC(2) gpsdata[18+c] = get4(); break; > ^~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::parse_kodak_ifd(int)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:5646:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if (tag == 2120 + wbi && wbi >= 0) > ~~~~^~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:5648:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if (tag == 2130 + wbi) > ~~~~^~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:5650:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if (tag == 2140 + wbi && wbi >= 0) > ~~~~^~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:5659:35: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if ((unsigned) wbi < 7 && tag == wbtag[wbi]) > ~~~~^~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'int DCraw::parse_tiff_ifd(int)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:5741:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if (tiff_bps < tiff_ifd[ifd].bps) > ~~~~~~~~~^~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:5868:32: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++) > ~~^~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:5901:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (colors=cfa=i=0; i < plen && colors < 4; i++) { > ~~^~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:124:31: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > #define FORC(cnt) for (c=0; c < cnt; c++) > ~~^~~~~~~~~~~ > #define FORC3 FORC(3) > ~~~~~~~~~~~~~~~~~~~~~ > #define FORC4 FORC(4) > ~~~~~~~~~~~~~~~~~~~~~ > #define FORCC FORC(colors) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > #define SQR(x) rtengine::SQR(x) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define MIN(a,b) rtengine::min(a,static_cast<__typeof__(a)>(b)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define MAX(a,b) rtengine::max(a,static_cast<__typeof__(a)>(b)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define LIM(x,min,max) rtengine::LIM(x,static_cast<__typeof__(x)>(min),static_cast<__typeof__(x)>(max)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define ULIM(x,y,z) rtengine::median(x,static_cast<__typeof__(x)>(y),static_cast<__typeof__(x)>(z)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define CLIP(x) rtengine::CLIP(x) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; } > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > /* > ~~ > In order to inline this calculation, I make the risky > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > assumption that all filter patterns can be described > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > by a repeating pattern of eight rows and two columns > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > Do not use the FC or BAYER macros with the Leaf CatchLight, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > because its pattern is 16x16, not 2x8. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4: > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0 G M G M G M 0 C Y C Y C Y 0 Y C Y C Y C 0 G M G M G M > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 1 C Y C Y C Y 1 M G M G M G 1 M G M G M G 1 Y C Y C Y C > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 3 C Y C Y C Y 3 G M G M G M 3 G M G M G M > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 4 C Y C Y C Y 4 Y C Y C Y C > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > PowerShot A5 5 G M G M G M 5 G M G M G M > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 7 M G M G M G 7 M G M G M G > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0 1 2 3 4 5 > ~~~~~~~~~~~ > 0 C Y C Y C Y > ~~~~~~~~~~~~~ > 1 G M G M G M > ~~~~~~~~~~~~~ > 2 C Y C Y C Y > ~~~~~~~~~~~~~ > 3 M G M G M G > ~~~~~~~~~~~~~ > > > All RGB cameras use one of these Bayer grids: > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > 0x16161616: 0x61616161: 0x49494949: 0x94949494: > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0 B G B G B G 0 G R G R G R 0 G B G B G B 0 R G R G R G > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 1 G R G R G R 1 B G B G B G 1 R G R G R G 1 G B G B G B > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 2 B G B G B G 2 G R G R G R 2 G B G B G B 2 R G R G R G > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 3 G R G R G R 3 B G B G B G 3 R G R G R G 3 G B G B G B > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > > > #define RAW(row,col) \ > ~~~~~~~~~~~~~~~~~~~~~~ > raw_image[(row)*raw_width+(col)] > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > #define FC(row,col) \ > ~~~~~~~~~~~~~~~~~~~~~ > (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > #define BAYER(row,col) \ > ~~~~~~~~~~~~~~~~~~~~~~~~ > image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)] > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > #define BAYER2(row,col) \ > ~~~~~~~~~~~~~~~~~~~~~~~~~ > image[((row) >> shrink)*iwidth + ((col) >> shrink)][fcol(row,col)] > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > int CLASS fcol (int row, int col) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const char filter[16][16] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (filters == 9) return xtrans[(row+6) % 6][(col+6) % 6]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > return FC(row,col); > ~~~~~~~~~~~~~~~~~~~ > } > ~ > > > #ifndef __GLIBC__ > ~~~~~~~~~~~~~~~~~ > char *my_memmem (char *haystack, size_t haystacklen, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > char *needle, size_t needlelen) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > char *c; > ~~~~~~~~ > for (c = haystack; c <= haystack + haystacklen - needlelen; c++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!memcmp (c, needle, needlelen)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return c; > ~~~~~~~~~ > return 0; > ~~~~~~~~~ > } > ~ > #define memmem my_memmem > ~~~~~~~~~~~~~~~~~~~~~~~~ > char *my_strcasestr (char *haystack, const char *needle) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > char *c; > ~~~~~~~~ > for (c = haystack; *c; c++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!strncasecmp(c, needle, strlen(needle))) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return c; > ~~~~~~~~~ > return 0; > ~~~~~~~~~ > } > ~ > #define strcasestr my_strcasestr > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #endif > ~~~~~~ > > > void CLASS merror (void *ptr, const char *where) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > if (ptr) return; > ~~~~~~~~~~~~~~~~ > fprintf (stderr,_("%s: Out of memory in %s\n"), ifname, where); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > longjmp (failure, 1); > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS derror() > ~~~~~~~~~~~~~~~~~~~ > { > ~ > if (!data_error) { > ~~~~~~~~~~~~~~~~~~ > fprintf (stderr, "%s: ", ifname); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (feof(ifp)) > ~~~~~~~~~~~~~~ > fprintf (stderr,_("Unexpected end of file\n")); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else > ~~~~ > fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > data_error++; > ~~~~~~~~~~~~~ > /*RT Issue 2467 longjmp (failure, 1);*/ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > ushort CLASS sget2 (uchar *s) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > if (order == 0x4949) /* "II" means little-endian */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return s[0] | s[1] << 8; > ~~~~~~~~~~~~~~~~~~~~~~~~ > else /* "MM" means big-endian */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return s[0] << 8 | s[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > ushort CLASS get2() > ~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar str[2] = { 0xff,0xff }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (str, 1, 2, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~ > return sget2(str); > ~~~~~~~~~~~~~~~~~~ > } > ~ > > > unsigned CLASS sget4 (uchar *s) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > if (order == 0x4949) > ~~~~~~~~~~~~~~~~~~~~ > return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else > ~~~~ > return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > #define sget4(s) sget4((uchar *)s) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > unsigned CLASS get4() > ~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar str[4] = { 0xff,0xff,0xff,0xff }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (str, 1, 4, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~ > return sget4(str); > ~~~~~~~~~~~~~~~~~~ > } > ~ > > > unsigned CLASS getint (int type) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > return type == 3 ? get2() : get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > float CLASS int_to_float (int i) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > union { int i; float f; } u; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > u.i = i; > ~~~~~~~~ > return u.f; > ~~~~~~~~~~~ > } > ~ > > > double CLASS getreal (int type) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > union { char c[8]; double d; } u; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int i, rev; > ~~~~~~~~~~~ > > > switch (type) { > ~~~~~~~~~~~~~~~ > case 3: return (unsigned short) get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 4: return (unsigned int) get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 5: u.d = (unsigned int) get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return u.d / (unsigned int) get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 8: return (signed short) get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 9: return (signed int) get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 10: u.d = (signed int) get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return u.d / (signed int) get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 11: return int_to_float (get4()); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 12: > ~~~~~~~~ > rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 8; i++) > ~~~~~~~~~~~~~~~~~~~~~ > u.c[i ^ rev] = fgetc(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > return u.d; > ~~~~~~~~~~~ > default: return fgetc(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS read_shorts (ushort *pixel, int count) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > if (fread (pixel, 2, count, ifp) < count) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > swab ((char*)pixel, (char*)pixel, count*2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS cubic_spline (const int *x_, const int *y_, const int len) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > float **A, *b, *c, *d, *x, *y; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int i, j; > ~~~~~~~~~ > > > A = (float **) calloc (((2*len + 4)*sizeof **A + sizeof *A), 2*len); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!A) return; > ~~~~~~~~~~~~~~~ > A[0] = (float *) (A + 2*len); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i = 1; i < 2*len; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > A[i] = A[0] + 2*len*i; > ~~~~~~~~~~~~~~~~~~~~~~ > y = len + (x = i + (d = i + (c = i + (b = A[0] + i*i)))); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i = 0; i < len; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > x[i] = x_[i] / 65535.0; > ~~~~~~~~~~~~~~~~~~~~~~~ > y[i] = y_[i] / 65535.0; > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (i = len-1; i > 0; i--) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > b[i] = (y[i] - y[i-1]) / (x[i] - x[i-1]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > d[i-1] = x[i] - x[i-1]; > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (i = 1; i < len-1; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > A[i][i] = 2 * (d[i-1] + d[i]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (i > 1) { > ~~~~~~~~~~~~ > A[i][i-1] = d[i-1]; > ~~~~~~~~~~~~~~~~~~~ > A[i-1][i] = d[i-1]; > ~~~~~~~~~~~~~~~~~~~ > } > ~ > A[i][len-1] = 6 * (b[i+1] - b[i]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for(i = 1; i < len-2; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float v = A[i+1][i] / A[i][i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for(j = 1; j <= len-1; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > A[i+1][j] -= v * A[i][j]; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for(i = len-2; i > 0; i--) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float acc = 0; > ~~~~~~~~~~~~~~ > for(j = i; j <= len-2; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > acc += A[i][j]*c[j]; > ~~~~~~~~~~~~~~~~~~~~ > c[i] = (A[i][len-1] - acc) / A[i][i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (i = 0; i < 0x10000; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float x_out = (float)(i / 65535.0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float y_out = 0; > ~~~~~~~~~~~~~~~~ > for (j = 0; j < len-1; j++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (x[j] <= x_out && x_out <= x[j+1]) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float v = x_out - x[j]; > ~~~~~~~~~~~~~~~~~~~~~~~ > y_out = y[j] + > ~~~~~~~~~~~~~~ > ((y[j+1] - y[j]) / d[j] - (2 * d[j] * c[j] + c[j+1] * d[j])/6) * v > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > + (c[j] * 0.5) * v*v + ((c[j+1] - c[j]) / (6 * d[j])) * v*v*v; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > curve[i] = y_out < 0.0 ? 0 : (y_out >= 1.0 ? 65535 : > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (ushort)(y_out * 65535.0 + 0.5)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > free (A); > ~~~~~~~~~ > } > ~ > > > void CLASS canon_600_fixed_wb (int temp) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const short mul[4][5] = { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 667, 358,397,565,452 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 731, 390,367,499,517 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 1119, 396,348,448,537 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 1399, 485,431,508,688 } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int lo, hi, i; > ~~~~~~~~~~~~~~ > float frac=0; > ~~~~~~~~~~~~~ > > > for (lo=4; --lo; ) > ~~~~~~~~~~~~~~~~~~ > if (*mul[lo] <= temp) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (hi=0; hi < 3; hi++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (*mul[hi] >= temp) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (lo != hi) > ~~~~~~~~~~~~~ > frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=1; i < 5; i++) > ~~~~~~~~~~~~~~~~~~~~~ > pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > /* Return values: 0 = white 1 = near white 2 = not white */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int CLASS canon_600_color (int ratio[2], int mar) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int clipped=0, target, miss; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > if (flash_used) { > ~~~~~~~~~~~~~~~~~ > if (ratio[1] < -104) > ~~~~~~~~~~~~~~~~~~~~ > { ratio[1] = -104; clipped = 1; } > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ratio[1] > 12) > ~~~~~~~~~~~~~~~~~~~~ > { ratio[1] = 12; clipped = 1; } > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else { > ~~~~~~~~ > if (ratio[1] < -264 || ratio[1] > 461) return 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ratio[1] < -50) > ~~~~~~~~~~~~~~~~~~~ > { ratio[1] = -50; clipped = 1; } > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ratio[1] > 307) > ~~~~~~~~~~~~~~~~~~~ > { ratio[1] = 307; clipped = 1; } > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > target = flash_used || ratio[1] < 197 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ? -38 - (398 * ratio[1] >> 10) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > : -123 + (48 * ratio[1] >> 10); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (target - mar <= ratio[0] && > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > target + 20 >= ratio[0] && !clipped) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > miss = target - ratio[0]; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if (abs(miss) >= mar*4) return 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (miss < -20) miss = -20; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (miss > mar) miss = mar; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ratio[0] = target - miss; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > return 1; > ~~~~~~~~~ > } > ~ > > > void CLASS canon_600_auto_wb() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int mar, row, col, i, j, st, count[] = { 0,0 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int test[8], total[2][8], ratio[2][2], stat[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > memset (&total, 0, sizeof total); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = canon_ev + 0.5; > ~~~~~~~~~~~~~~~~~~~ > if (i < 10) mar = 150; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else if (i > 12) mar = 20; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > else mar = 280 - 20 * i; > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (flash_used) mar = 80; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=14; row < height-14; row+=4) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=10; col < width; col+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 8; i++) > ~~~~~~~~~~~~~~~~~~~~~ > test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > BAYER(row+(i >> 1),col+(i & 1)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 8; i++) > ~~~~~~~~~~~~~~~~~~~~~ > if (test[i] < 150 || test[i] > 1500) goto next; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 4; i++) > ~~~~~~~~~~~~~~~~~~~~~ > if (abs(test[i] - test[i+4]) > 50) goto next; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 2; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 4; j+=2) > ~~~~~~~~~~~~~~~~~~~~~~ > ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > stat[i] = canon_600_color (ratio[i], mar); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if ((st = stat[0] | stat[1]) > 1) goto next; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 2; i++) > ~~~~~~~~~~~~~~~~~~~~~ > if (stat[i]) > ~~~~~~~~~~~~ > for (j=0; j < 2; j++) > ~~~~~~~~~~~~~~~~~~~~~ > test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 8; i++) > ~~~~~~~~~~~~~~~~~~~~~ > total[st][i] += test[i]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > count[st]++; > ~~~~~~~~~~~~ > next: ; > ~~~~~~~ > } > ~ > if (count[0] | count[1]) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > st = count[0]*200 < count[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 4; i++) > ~~~~~~~~~~~~~~~~~~~~~ > pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS canon_600_coeff() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const short table[6][12] = { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int t=0, i, c; > ~~~~~~~~~~~~~~ > float mc, yc; > ~~~~~~~~~~~~~ > > > mc = pre_mul[1] / pre_mul[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > yc = pre_mul[3] / pre_mul[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (mc > 1.28 && mc <= 2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (yc < 0.8789) t=3; > ~~~~~~~~~~~~~~~~~~~~~~ > else if (yc <= 2) t=4; > ~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (flash_used) t=5; > ~~~~~~~~~~~~~~~~~~~~ > for (raw_color = i=0; i < 3; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS canon_600_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar data[1120], *dp; > ~~~~~~~~~~~~~~~~~~~~~~~ > ushort *pix; > ~~~~~~~~~~~~ > int irow, row; > ~~~~~~~~~~~~~~ > > > for (irow=row=0; irow < height; irow++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (fread (data, 1, 1120, ifp) < 1120) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix = raw_image + row*raw_width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (dp=data; dp < data+1120; dp+=10, pix+=8) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[0] = (dp[0] << 2) + (dp[1] >> 6 ); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[3] = (dp[4] << 2) + (dp[1] & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[4] = (dp[5] << 2) + (dp[9] & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[7] = (dp[8] << 2) + (dp[9] >> 6 ); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if ((row+=2) > height) row = 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS canon_600_correct() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int row, col, val; > ~~~~~~~~~~~~~~~~~~ > static const short mul[4][2] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > for (row=0; row < height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((val = BAYER(row,col) - black) < 0) val = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > val = val * mul[row & 3][col & 1] >> 9; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > BAYER(row,col) = val; > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > canon_600_fixed_wb(1311); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > canon_600_auto_wb(); > ~~~~~~~~~~~~~~~~~~~~ > canon_600_coeff(); > ~~~~~~~~~~~~~~~~~~ > maximum = (0x3ff - black) * 1109 >> 9; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > black = 0; > ~~~~~~~~~~ > } > ~ > > > int CLASS canon_s2is() > ~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned row; > ~~~~~~~~~~~~~ > > > for (row=0; row < 100; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, row*3340 + 3284, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (getc(ifp) > 15) return 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > return 0; > ~~~~~~~~~ > } > ~ > > > inline unsigned CLASS getbithuff_t::operator() (int nbits, ushort *huff) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > /*RT static unsigned bitbuf=0; */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > /*RT static int vbits=0, reset=0; */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unsigned c; > ~~~~~~~~~~~ > > > if (UNLIKELY(nbits > 25)) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (nbits < 0) > ~~~~~~~~~~~~~~ > return bitbuf = vbits = reset = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (nbits == 0 || vbits < 0) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (!reset && vbits < nbits && (c = fgetc(ifp)) != EOF && > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > !(reset = zero_after_ff && c == 0xff && fgetc(ifp))) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > bitbuf = (bitbuf << 8) + (uchar) c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > vbits += 8; > ~~~~~~~~~~~ > } > ~ > c = bitbuf << (32-vbits) >> (32-nbits); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (huff) { > ~~~~~~~~~~~ > vbits -= huff[c] >> 8; > ~~~~~~~~~~~~~~~~~~~~~~ > c = (uchar) huff[c]; > ~~~~~~~~~~~~~~~~~~~~ > } else > ~~~~~~ > vbits -= nbits; > ~~~~~~~~~~~~~~~ > if (vbits < 0) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~ > return c; > ~~~~~~~~~ > } > ~ > > > #define getbits(n) getbithuff(n,0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define gethuff(h) getbithuff(*h,h+1) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > /* > ~~ > Construct a decode tree according the specification in *source. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > The first 16 bytes specify how many codes should be 1-bit, 2-bit > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 3-bit, etc. Bytes after that are the leaf values. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > For example, if the source is > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > then the code is > ~~~~~~~~~~~~~~~~ > > > 00 0x04 > ~~~~~~~~ > 010 0x03 > ~~~~~~~~~ > 011 0x05 > ~~~~~~~~~ > 100 0x06 > ~~~~~~~~~ > 101 0x02 > ~~~~~~~~~ > 1100 0x07 > ~~~~~~~~~~ > 1101 0x01 > ~~~~~~~~~~ > 11100 0x08 > ~~~~~~~~~~~ > 11101 0x09 > ~~~~~~~~~~~ > 11110 0x00 > ~~~~~~~~~~~ > 111110 0x0a > ~~~~~~~~~~~~ > 1111110 0x0b > ~~~~~~~~~~~~~ > 1111111 0xff > ~~~~~~~~~~~~~ > */ > ~~ > ushort * CLASS make_decoder_ref (const uchar **source) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int max, len, h, i, j; > ~~~~~~~~~~~~~~~~~~~~~~ > const uchar *count; > ~~~~~~~~~~~~~~~~~~~ > ushort *huff; > ~~~~~~~~~~~~~ > > > count = (*source += 16) - 17; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (max=16; max && !count[max]; max--); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > huff = (ushort *) calloc (1 + (1 << max), sizeof *huff); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (huff, "make_decoder()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > huff[0] = max; > ~~~~~~~~~~~~~~ > for (h=len=1; len <= max; len++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < count[len]; i++, ++*source) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 1 << (max-len); j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (h <= 1 << max) > ~~~~~~~~~~~~~~~~~~ > huff[h++] = len << 8 | **source; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return huff; > ~~~~~~~~~~~~ > } > ~ > > > ushort * CLASS make_decoder (const uchar *source) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > return make_decoder_ref (&source); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS crw_init_tables (unsigned table, ushort *huff[2]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const uchar first_tree[3][29] = { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > }; > ~~ > static const uchar second_tree[3][180] = { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff } > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > }; > ~~ > if (table > 2) table = 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > huff[0] = make_decoder ( first_tree[table]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > huff[1] = make_decoder (second_tree[table]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > /* > ~~ > Return 0 if the image starts with compressed data, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 1 if it starts with uncompressed low-order bits. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > In Canon compressed data, 0xff is always followed by 0x00. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > int CLASS canon_has_lowbits() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar test[0x4000]; > ~~~~~~~~~~~~~~~~~~~ > int ret=1, i; > ~~~~~~~~~~~~~ > > > fseek (ifp, 0, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (test, 1, sizeof test, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=540; i < sizeof test - 1; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (test[i] == 0xff) { > ~~~~~~~~~~~~~~~~~~~~~~ > if (test[i+1]) return 1; > ~~~~~~~~~~~~~~~~~~~~~~~~ > ret=0; > ~~~~~~ > } > ~ > return ret; > ~~~~~~~~~~~ > } > ~ > > > void CLASS canon_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > ushort *pixel, *prow, *huff[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int nblocks, lowbits, i, c, row, r, save, val; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > crw_init_tables (tiff_compress, huff); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > lowbits = canon_has_lowbits(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!lowbits) maximum = 0x3ff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > zero_after_ff = 1; > ~~~~~~~~~~~~~~~~~~ > getbits(-1); > ~~~~~~~~~~~~ > for (row=0; row < raw_height; row+=8) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pixel = raw_image + row*raw_width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > nblocks = MIN (8, raw_height-row) * raw_width >> 6; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (block=0; block < nblocks; block++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memset (diffbuf, 0, sizeof diffbuf); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 64; i++ ) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > leaf = gethuff(huff[i > 0]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (leaf == 0 && i) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (leaf == 0xff) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i += leaf >> 4; > ~~~~~~~~~~~~~~~~ > len = leaf & 15; > ~~~~~~~~~~~~~~~~ > if (len == 0) continue; > ~~~~~~~~~~~~~~~~~~~~~~~ > diff = getbits(len); > ~~~~~~~~~~~~~~~~~~~~ > if ((diff & (1 << (len-1))) == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff -= (1 << len) - 1; > ~~~~~~~~~~~~~~~~~~~~~~~ > if (i < 64) diffbuf[i] = diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > diffbuf[0] += carry; > ~~~~~~~~~~~~~~~~~~~~ > carry = diffbuf[0]; > ~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 64; i++ ) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if (pnum++ % raw_width == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > base[0] = base[1] = 512; > ~~~~~~~~~~~~~~~~~~~~~~~~ > if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > derror(); > ~~~~~~~~~ > } > ~ > } > ~ > if (lowbits) { > ~~~~~~~~~~~~~~ > save = ftell(ifp); > ~~~~~~~~~~~~~~~~~~ > fseek (ifp, 26 + row*raw_width/4, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (prow=pixel, i=0; i < raw_width*2; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > c = fgetc(ifp); > ~~~~~~~~~~~~~~~ > for (r=0; r < 8; r+=2, prow++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > val = (*prow << 2) + ((c >> r) & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (raw_width == 2672 && val < 512) val += 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > *prow = val; > ~~~~~~~~~~~~ > } > ~ > } > ~ > fseek (ifp, save, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > FORC(2) free (huff[c]); > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > /* > ~~ > Not a full implementation of Lossless JPEG, just > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > enough to decode Canon, Kodak and Adobe DNG images. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > struct jhead { > ~~~~~~~~~~~~~~ > int bits, high, wide, clrs, sraw, psv, restart, vpred[6]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort *huff[6], *free[4], *row; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > }; > ~~ > > > int CLASS ljpeg_start (struct jhead *jh, int info_only) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > ushort c, tag, len; > ~~~~~~~~~~~~~~~~~~~ > uchar data[0x10000]; > ~~~~~~~~~~~~~~~~~~~~ > const uchar *dp; > ~~~~~~~~~~~~~~~~ > > > memset (jh, 0, sizeof *jh); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jh->restart = INT_MAX; > ~~~~~~~~~~~~~~~~~~~~~~ > if ((fgetc(ifp),fgetc(ifp)) != 0xd8) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > do { > ~~~~ > if (!fread (data, 2, 2, ifp)) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tag = data[0] << 8 | data[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > len = (data[2] << 8 | data[3]) - 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag <= 0xff00) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (data, 1, len, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > switch (tag) { > ~~~~~~~~~~~~~~ > case 0xffc3: > ~~~~~~~~~~~~ > jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 0xffc1: > ~~~~~~~~~~~~ > case 0xffc0: > ~~~~~~~~~~~~ > jh->algo = tag & 0xff; > ~~~~~~~~~~~~~~~~~~~~~~ > jh->bits = data[0]; > ~~~~~~~~~~~~~~~~~~~ > jh->high = data[1] << 8 | data[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jh->wide = data[3] << 8 | data[4]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jh->clrs = data[5] + jh->sraw; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (len == 9 && !dng_version) getc(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 0xffc4: > ~~~~~~~~~~~~ > if (info_only) break; > ~~~~~~~~~~~~~~~~~~~~~ > for (dp = data; dp < data+len && !((c = *dp++) & -20); ) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jh->free[c] = jh->huff[c] = make_decoder_ref (&dp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 0xffda: > ~~~~~~~~~~~~ > jh->psv = data[1+data[0]*2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jh->bits -= data[3+data[0]*2] & 15; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 0xffdb: > ~~~~~~~~~~~~ > FORC(64) jh->quant[c] = data[c*2+1] << 8 | data[c*2+2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 0xffdd: > ~~~~~~~~~~~~ > jh->restart = data[0] << 8 | data[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } while (tag != 0xffda); > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (jh->bits > 16 || jh->clrs > 6 || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > !jh->bits || !jh->high || !jh->wide || !jh->clrs) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (info_only) return 1; > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (!jh->huff[0]) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(19) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (jh->sraw) { > ~~~~~~~~~~~~~~~ > FORC(4) jh->huff[2+c] = jh->huff[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(jh->sraw) jh->huff[1+c] = jh->huff[0]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > jh->row = (ushort *) calloc (2 * jh->wide*jh->clrs, 4); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (jh->row, "ljpeg_start()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return zero_after_ff = 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS ljpeg_end (struct jhead *jh) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int c; > ~~~~~~ > FORC4 if (jh->free[c]) free (jh->free[c]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > free (jh->row); > ~~~~~~~~~~~~~~~ > } > ~ > > > inline int CLASS ljpeg_diff (ushort *huff) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int len, diff; > ~~~~~~~~~~~~~~ > > > len = gethuff(huff); > ~~~~~~~~~~~~~~~~~~~~ > if (len == 16 && (!dng_version || dng_version >= 0x1010000)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return -32768; > ~~~~~~~~~~~~~~ > diff = getbits(len); > ~~~~~~~~~~~~~~~~~~~~ > if ((diff & (1 << (len-1))) == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff -= (1 << len) - 1; > ~~~~~~~~~~~~~~~~~~~~~~~ > return diff; > ~~~~~~~~~~~~ > } > ~ > > > ushort * CLASS ljpeg_row (int jrow, struct jhead *jh) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int col, c, diff, pred, spred=0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort mark=0, *row[3]; > ~~~~~~~~~~~~~~~~~~~~~~~ > > > if (jrow * jh->wide % jh->restart == 0) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(6) jh->vpred[c] = 1 << (jh->bits-1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (jrow) { > ~~~~~~~~~~~ > fseek (ifp, -2, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > do mark = (mark << 8) + (c = fgetc(ifp)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (c != EOF && mark >> 4 != 0xffd); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > getbits(-1); > ~~~~~~~~~~~~ > } > ~ > FORC3 row[c] = (jh->row + ((jrow & 1) + 1) * (jh->wide*jh->clrs*((jrow+c) & 1))); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < jh->wide; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(jh->clrs) { > ~~~~~~~~~~~~~~~~ > diff = ljpeg_diff (jh->huff[c]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (jh->sraw && c <= jh->sraw && (col | c)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pred = spred; > ~~~~~~~~~~~~~ > else if (col) pred = row[0][-jh->clrs]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else pred = (jh->vpred[c] += diff) - diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (jh->psv != 1 && jrow && col) switch (jh->psv) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 2: pred = row[1][0]; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 3: pred = row[1][-jh->clrs]; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 7: pred = (pred + row[1][0]) >> 1; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > default: pred = 0; > ~~~~~~~~~~~~~~~~~~ > } > ~ > if (UNLIKELY((**row = pred + diff) >> jh->bits)) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (c <= jh->sraw) spred = **row; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row[0]++; row[1]++; > ~~~~~~~~~~~~~~~~~~~ > } > ~ > return row[2]; > ~~~~~~~~~~~~~~ > } > ~ > > > void CLASS lossless_jpeg_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > struct jhead jh; > ~~~~~~~~~~~~~~~~ > int row=0, col=0; > ~~~~~~~~~~~~~~~~~ > > > if (!ljpeg_start (&jh, 0)) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int jwide = jh.wide * jh.clrs; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort *rp[2]; > ~~~~~~~~~~~~~~ > rp[0] = ljpeg_row (0, &jh); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > for (int jrow=0; jrow < jh.high; jrow++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #ifdef _OPENMP > ~~~~~~~~~~~~~~ > #pragma omp parallel sections > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #endif > ~~~~~~ > { > ~ > #ifdef _OPENMP > ~~~~~~~~~~~~~~ > #pragma omp section > ~~~~~~~~~~~~~~~~~~~ > #endif > ~~~~~~ > { > ~ > if(jrow < jh.high - 1) > ~~~~~~~~~~~~~~~~~~~~~~ > rp[(jrow + 1)&1] = ljpeg_row (jrow + 1, &jh); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > #ifdef _OPENMP > ~~~~~~~~~~~~~~ > #pragma omp section > ~~~~~~~~~~~~~~~~~~~ > #endif > ~~~~~~ > { > ~ > if (load_flags & 1) > ~~~~~~~~~~~~~~~~~~~ > row = jrow & 1 ? height-1-jrow/2 : jrow/2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (int jcol=0; jcol < jwide; jcol++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int val = curve[*rp[jrow&1]++]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (cr2_slice[0]) { > ~~~~~~~~~~~~~~~~~~~ > int jidx = jrow*jwide + jcol; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int i = jidx / (cr2_slice[1]*raw_height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int j; > ~~~~~~ > if ((j = i >= cr2_slice[0])) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = cr2_slice[0]; > ~~~~~~~~~~~~~~~~~~ > jidx -= i * (cr2_slice[1]*raw_height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row = jidx / cr2_slice[1+j]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > col = jidx % cr2_slice[1+j] + i*cr2_slice[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (raw_width == 3984 && (col -= 2) < 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > col += (row--,raw_width); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((unsigned) row < raw_height) RAW(row,col) = val; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (++col >= raw_width) > ~~~~~~~~~~~~~~~~~~~~~~~ > col = (row++,0); > ~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > } > ~ > ljpeg_end (&jh); > ~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS canon_sraw_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > struct jhead jh; > ~~~~~~~~~~~~~~~~ > short *rp=0, (*ip)[4]; > ~~~~~~~~~~~~~~~~~~~~~~ > int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int v[3]={0,0,0}, ver, hue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > char *cp; > ~~~~~~~~~ > > > if (!ljpeg_start (&jh, 0) || jh.clrs < 4) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jwide = (jh.wide >>= 1) * jh.clrs; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > for (ecol=slice=0; slice <= cr2_slice[0]; slice++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > scol = ecol; > ~~~~~~~~~~~~ > ecol += cr2_slice[1] * 2 / jh.clrs; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!cr2_slice[0] || ecol > raw_width-1) ecol = raw_width & -2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < height; row += (jh.clrs >> 1) - 1) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ip = (short (*)[4]) image + row*width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=scol; col < ecol; col+=2, jcol+=jh.clrs) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((jcol %= jwide) == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~ > rp = (short *) ljpeg_row (jrow++, &jh); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col >= width) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC (jh.clrs-2) > ~~~~~~~~~~~~~~~~ > ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ip[col][1] = rp[jcol+jh.clrs-2] - 16384; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ip[col][2] = rp[jcol+jh.clrs-1] - 16384; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > for (cp=model2; *cp && !isdigit(*cp); cp++); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sscanf (cp, "%d.%d.%d", v, v+1, v+2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ver = (v[0]*1000 + v[1])*1000 + v[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > hue = (jh.sraw+1) << 2; > ~~~~~~~~~~~~~~~~~~~~~~~ > if (unique_id >= 0x80000281 || (unique_id == 0x80000218 && ver > 1000006)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > hue = jh.sraw << 1; > ~~~~~~~~~~~~~~~~~~~ > ip = (short (*)[4]) image; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > rp = ip[0]; > ~~~~~~~~~~~ > for (row=0; row < height; row++, ip+=width) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (row & (jh.sraw >> 1)) > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col+=2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (c=1; c < 3; c++) > ~~~~~~~~~~~~~~~~~~~~~ > if (row == height-1) > ~~~~~~~~~~~~~~~~~~~~ > ip[col][c] = ip[col-width][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else ip[col][c] = (ip[col-width][c] + ip[col+width][c] + 1) >> 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=1; col < width; col+=2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (c=1; c < 3; c++) > ~~~~~~~~~~~~~~~~~~~~~ > if (col == width-1) > ~~~~~~~~~~~~~~~~~~~ > ip[col][c] = ip[col-1][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else ip[col][c] = (ip[col-1][c] + ip[col+1][c] + 1) >> 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for ( ; rp < ip[0]; rp+=4) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (unique_id == 0x80000218 || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unique_id == 0x80000250 || > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > unique_id == 0x80000261 || > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > unique_id == 0x80000281 || > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > unique_id == 0x80000287) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > rp[1] = (rp[1] << 2) + hue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > rp[2] = (rp[2] << 2) + hue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[0] = rp[0] + (( 50*rp[1] + 22929*rp[2]) >> 14); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[2] = rp[0] + ((29040*rp[1] - 101*rp[2]) >> 14); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else { > ~~~~~~~~ > if (unique_id < 0x80000218) rp[0] -= 512; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[0] = rp[0] + rp[2]; > ~~~~~~~~~~~~~~~~~~~~~~~ > pix[2] = rp[0] + rp[1]; > ~~~~~~~~~~~~~~~~~~~~~~~ > pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > FORC3 rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > ljpeg_end (&jh); > ~~~~~~~~~~~~~~~~ > maximum = 0x3fff; > ~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS adobe_copy_pixel (unsigned row, unsigned col, ushort **rp) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int c; > ~~~~~~ > > > if (tiff_samples == 2 && shot_select) (*rp)++; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (raw_image) { > ~~~~~~~~~~~~~~~~ > if (row < raw_height && col < raw_width) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = curve[**rp]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > *rp += tiff_samples; > ~~~~~~~~~~~~~~~~~~~~ > } else { > ~~~~~~~~ > if (row < height && col < width) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(tiff_samples) > ~~~~~~~~~~~~~~~~~~ > image[row*width+col][c] = curve[(*rp)[c]]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > *rp += tiff_samples; > ~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (tiff_samples == 2 && shot_select) (*rp)--; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS ljpeg_idct (struct jhead *jh) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int c, i, j, len, skip, coef; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float work[3][8][8]; > ~~~~~~~~~~~~~~~~~~~~ > static float cs[106] = { 0 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > static const uchar zigzag[80] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0, 1, 8,16, 9, 2, 3,10,17,24,32,25,18,11, 4, 5,12,19,26,33, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 40,48,41,34,27,20,13, 6, 7,14,21,28,35,42,49,56,57,50,43,36, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 47,55,62,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > if (!cs[0]) > ~~~~~~~~~~~ > FORC(106) cs[c] = cos((c & 31)*M_PI/16)/2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memset (work, 0, sizeof work); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > work[0][0][0] = jh->vpred[0] += ljpeg_diff (jh->huff[0]) * jh->quant[0]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=1; i < 64; i++ ) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > len = gethuff (jh->huff[16]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i += skip = len >> 4; > ~~~~~~~~~~~~~~~~~~~~~ > if (!(len &= 15) && skip < 15) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > coef = getbits(len); > ~~~~~~~~~~~~~~~~~~~~ > if ((coef & (1 << (len-1))) == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > coef -= (1 << len) - 1; > ~~~~~~~~~~~~~~~~~~~~~~~ > ((float *)work)[zigzag[i]] = coef * jh->quant[i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > FORC(8) work[0][0][c] *= M_SQRT1_2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(8) work[0][c][0] *= M_SQRT1_2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 8; i++) > ~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 8; j++) > ~~~~~~~~~~~~~~~~~~~~~ > FORC(8) work[1][i][j] += work[0][i][c] * cs[(j*2+1)*c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 8; i++) > ~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 8; j++) > ~~~~~~~~~~~~~~~~~~~~~ > FORC(8) work[2][i][j] += work[1][c][j] * cs[(i*2+1)*c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > FORC(64) jh->idct[c] = CLIP(((float *)work[2])[c]+0.5); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS lossless_dng_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col, i, j; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > struct jhead jh; > ~~~~~~~~~~~~~~~~ > ushort *rp; > ~~~~~~~~~~~ > > > while (trow < raw_height) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > save = ftell(ifp); > ~~~~~~~~~~~~~~~~~~ > if (tile_length < INT_MAX) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, get4(), SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!ljpeg_start (&jh, 0)) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jwide = jh.wide; > ~~~~~~~~~~~~~~~~ > if (filters) jwide *= jh.clrs; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jwide /= MIN (is_raw, tiff_samples); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > switch (jh.algo) { > ~~~~~~~~~~~~~~~~~~ > case 0xc1: > ~~~~~~~~~~ > jh.vpred[0] = 16384; > ~~~~~~~~~~~~~~~~~~~~ > getbits(-1); > ~~~~~~~~~~~~ > for (jrow=0; jrow+7 < jh.high; jrow += 8) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (jcol=0; jcol+7 < jh.wide; jcol += 8) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ljpeg_idct (&jh); > ~~~~~~~~~~~~~~~~~ > rp = jh.idct; > ~~~~~~~~~~~~~ > row = trow + jcol/tile_width + jrow*2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > col = tcol + jcol%tile_width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 16; i+=2) > ~~~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 8; j++) > ~~~~~~~~~~~~~~~~~~~~~ > adobe_copy_pixel (row+i, col+j, &rp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > break; > ~~~~~~ > case 0xc3: > ~~~~~~~~~~ > for (row=col=jrow=0; jrow < jh.high; jrow++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > rp = ljpeg_row (jrow, &jh); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (jcol=0; jcol < jwide; jcol++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > adobe_copy_pixel (trow+row, tcol+col, &rp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (++col >= tile_width || col >= raw_width) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row += 1 + (col = 0); > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } } > ~~~~~~ > fseek (ifp, save+4, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((tcol += tile_width) >= raw_width) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > trow += tile_length + (tcol = 0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ljpeg_end (&jh); > ~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS packed_dng_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > ushort *pixel, *rp; > ~~~~~~~~~~~~~~~~~~~ > int row, col; > ~~~~~~~~~~~~~ > > > pixel = (ushort *) calloc (raw_width, tiff_samples*sizeof *pixel); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (pixel, "packed_dng_load_raw()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tiff_bps == 16) > ~~~~~~~~~~~~~~~~~~~ > read_shorts (pixel, raw_width * tiff_samples); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else { > ~~~~~~ > getbits(-1); > ~~~~~~~~~~~~ > for (col=0; col < raw_width * tiff_samples; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pixel[col] = getbits(tiff_bps); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (rp=pixel, col=0; col < raw_width; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > adobe_copy_pixel (row, col, &rp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > free (pixel); > ~~~~~~~~~~~~~ > } > ~ > > > void CLASS pentax_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > ushort bit[2][15], huff[4097]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int dep, row, col, diff, c, i; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort vpred[2][2] = {{0,0},{0,0}}, hpred[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > fseek (ifp, meta_offset, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > dep = (get2() + 12) & 15; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 12, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(dep) bit[0][c] = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(dep) bit[1][c] = fgetc(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(dep) > ~~~~~~~~~ > for (i=bit[0][c]; i <= ((bit[0][c]+(4096 >> bit[1][c])-1) & 4095); ) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > huff[++i] = bit[1][c] << 8 | c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > huff[0] = 12; > ~~~~~~~~~~~~~ > fseek (ifp, data_offset, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > getbits(-1); > ~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff = ljpeg_diff (huff); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col < 2) hpred[col] = vpred[row & 1][col] += diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else hpred[col & 1] += diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = hpred[col & 1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (hpred[col & 1] >> tiff_bps) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS nikon_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const uchar nikon_tree[][32] = { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 5,4,3,6,2,7,1,0,8,9,11,10,12 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy after split */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, /* 12-bit lossless */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 5,4,6,3,7,2,8,1,9,0,10,11,12 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0, /* 14-bit lossy */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0, /* 14-bit lossy after split */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0, /* 14-bit lossless */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort *huff, ver0, ver1, vpred[2][2], hpred[2], csize; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int i, min, max, step=0, tree=0, split=0, row, col, len, shl, diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > fseek (ifp, meta_offset, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ver0 = fgetc(ifp); > ~~~~~~~~~~~~~~~~~~ > ver1 = fgetc(ifp); > ~~~~~~~~~~~~~~~~~~ > if (ver0 == 0x49 || ver1 == 0x58) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 2110, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ver0 == 0x46) tree = 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tiff_bps == 14) tree += 3; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > read_shorts (vpred[0], 4); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > max = 1 << tiff_bps & 0x7fff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((csize = get2()) > 1) > ~~~~~~~~~~~~~~~~~~~~~~~~~ > step = max / (csize-1); > ~~~~~~~~~~~~~~~~~~~~~~~ > if (ver0 == 0x44 && ver1 == 0x20 && step > 0) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < csize; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~ > curve[i*step] = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < max; i++) > ~~~~~~~~~~~~~~~~~~~~~~~ > curve[i] = ( curve[i-i%step]*(step-i%step) + > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > curve[i-i%step+step]*(i%step) ) / step; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, meta_offset+562, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > split = get2(); > ~~~~~~~~~~~~~~~ > } else if (ver0 != 0x46 && csize <= 0x4001) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > read_shorts (curve, max=csize); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (curve[max-2] == curve[max-1]) max--; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > huff = make_decoder (nikon_tree[tree]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, data_offset, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > getbits(-1); > ~~~~~~~~~~~~ > for (min=row=0; row < height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (split && row == split) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > free (huff); > ~~~~~~~~~~~~ > huff = make_decoder (nikon_tree[tree+1]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > max += (min = 16) << 1; > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (col=0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = gethuff(huff); > ~~~~~~~~~~~~~~~~~~ > len = i & 15; > ~~~~~~~~~~~~~ > shl = i >> 4; > ~~~~~~~~~~~~~ > diff = ((getbits(len-shl) << 1) + 1) << shl >> 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((diff & (1 << (len-1))) == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff -= (1 << len) - !shl; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col < 2) hpred[col] = vpred[row & 1][col] += diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else hpred[col & 1] += diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((ushort)(hpred[col & 1] + min) >= max) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = curve[LIM((short)hpred[col & 1],0,0x3fff)]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > free (huff); > ~~~~~~~~~~~~ > } > ~ > > > void CLASS nikon_yuv_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int row, col, yuv[4], rgb[3], b, c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > UINT64 bitbuf=0; > ~~~~~~~~~~~~~~~~ > > > for (row=0; row < raw_height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!(b = col & 1)) { > ~~~~~~~~~~~~~~~~~~~~~ > bitbuf = 0; > ~~~~~~~~~~~ > FORC(6) bitbuf |= (UINT64) fgetc(ifp) << c*8; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(4) yuv[c] = (bitbuf >> c*12 & 0xfff) - (c >> 1 << 11); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > rgb[0] = yuv[b] + 1.370705*yuv[3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > rgb[1] = yuv[b] - 0.337633*yuv[2] - 0.698001*yuv[3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > rgb[2] = yuv[b] + 1.732446*yuv[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,0xfff)] / cam_mul[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > /* > ~~ > Returns 1 for a Coolpix 995, 0 for anything else. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > int CLASS nikon_e995() > ~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int i, histo[256]; > ~~~~~~~~~~~~~~~~~~ > const uchar often[] = { 0x00, 0x55, 0xaa, 0xff }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > memset (histo, 0, sizeof histo); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, -2000, SEEK_END); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 2000; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > histo[fgetc(ifp)]++; > ~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 4; i++) > ~~~~~~~~~~~~~~~~~~~~~ > if (histo[often[i]] < 200) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > return 0; > ~~~~~~~~~ > return 1; > ~~~~~~~~~ > } > ~ > > > /* > ~~ > Returns 1 for a Coolpix 2100, 0 for anything else. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > int CLASS nikon_e2100() > ~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar t[12]; > ~~~~~~~~~~~~ > int i; > ~~~~~~ > > > fseek (ifp, 0, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 1024; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (t, 1, 12, ifp); > ~~~~~~~~~~~~~~~~~~~~~~ > if (((t[2] & t[4] & t[7] & t[9]) >> 4 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > & t[1] & t[6] & t[8] & t[11] & 3) != 3) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return 0; > ~~~~~~~~~ > } > ~ > return 1; > ~~~~~~~~~ > } > ~ > > > void CLASS nikon_3700() > ~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int bits, i; > ~~~~~~~~~~~~ > uchar dp[24]; > ~~~~~~~~~~~~~ > static const struct { > ~~~~~~~~~~~~~~~~~~~~~ > int bits; > ~~~~~~~~~ > char make[12], model[15]; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > } table[] = { > ~~~~~~~~~~~~~ > { 0x00, "Pentax", "Optio 33WR" }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0x03, "Nikon", "E3200" }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0x32, "Nikon", "E3700" }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0x33, "Olympus", "C740UZ" } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > fseek (ifp, 3072, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (dp, 1, 24, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~ > bits = (dp[8] & 3) << 4 | (dp[20] & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < sizeof table / sizeof *table; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (bits == table[i].bits) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > strcpy (make, table[i].make ); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > strcpy (model, table[i].model); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > /* > ~~ > Separates a Minolta DiMAGE Z2 from a Nikon E4300. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > int CLASS minolta_z2() > ~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int i, nz; > ~~~~~~~~~~ > char tail[424]; > ~~~~~~~~~~~~~~~ > > > fseek (ifp, -(int)sizeof tail, SEEK_END); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (tail, 1, sizeof tail, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (nz=i=0; i < sizeof tail; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tail[i]) nz++; > ~~~~~~~~~~~~~~~~~~ > return nz > 20; > ~~~~~~~~~~~~~~~ > } > ~ > > > /*RT void CLASS jpeg_thumb(); */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > void CLASS ppm_thumb() > ~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > char *thumb; > ~~~~~~~~~~~~ > thumb_length = thumb_width*thumb_height*3; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > thumb = (char *) malloc (thumb_length); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (thumb, "ppm_thumb()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (thumb, 1, thumb_length, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fwrite (thumb, 1, thumb_length, ofp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > free (thumb); > ~~~~~~~~~~~~~ > } > ~ > > > void CLASS ppm16_thumb() > ~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int i; > ~~~~~~ > char *thumb; > ~~~~~~~~~~~~ > thumb_length = thumb_width*thumb_height*3; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > thumb = (char *) calloc (thumb_length, 2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (thumb, "ppm16_thumb()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > read_shorts ((ushort *) thumb, thumb_length); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < thumb_length; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > thumb[i] = ((ushort *) thumb)[i] >> 8; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fwrite (thumb, 1, thumb_length, ofp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > free (thumb); > ~~~~~~~~~~~~~ > } > ~ > > > void CLASS layer_thumb() > ~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int i, c; > ~~~~~~~~~ > char *thumb, map[][4] = { "012","102" }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > colors = thumb_misc >> 5 & 7; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > thumb_length = thumb_width*thumb_height; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > thumb = (char *) calloc (colors, thumb_length); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (thumb, "layer_thumb()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fprintf (ofp, "P%d\n%d %d\n255\n", > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 5 + (colors >> 1), thumb_width, thumb_height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (thumb, thumb_length, colors, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < thumb_length; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORCC putc (thumb[i+thumb_length*(map[thumb_misc >> 8][c]-'0')], ofp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > free (thumb); > ~~~~~~~~~~~~~ > } > ~ > > > void CLASS rollei_thumb() > ~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned i; > ~~~~~~~~~~~ > ushort *thumb; > ~~~~~~~~~~~~~~ > > > thumb_length = thumb_width * thumb_height; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > thumb = (ushort *) calloc (thumb_length, 2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (thumb, "rollei_thumb()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > read_shorts (thumb, thumb_length); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < thumb_length; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > putc (thumb[i] << 3, ofp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > putc (thumb[i] >> 5 << 2, ofp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > putc (thumb[i] >> 11 << 3, ofp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > free (thumb); > ~~~~~~~~~~~~~ > } > ~ > > > void CLASS rollei_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar pixel[10]; > ~~~~~~~~~~~~~~~~ > unsigned iten=0, isix, i, buffer=0, todo[16]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > isix = raw_width * raw_height * 5 / 8; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (fread (pixel, 1, 10, ifp) == 10) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 10; i+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > todo[i] = iten++; > ~~~~~~~~~~~~~~~~~~~ > todo[i+1] = pixel[i] << 8 | pixel[i+1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > buffer = pixel[i] >> 2 | buffer << 6; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for ( ; i < 16; i+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > todo[i] = isix++; > ~~~~~~~~~~~~~~~~~~~ > todo[i+1] = buffer >> (14-i)*5; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (i=0; i < 16; i+=2) > ~~~~~~~~~~~~~~~~~~~~~~~ > raw_image[todo[i]] = (todo[i+1] & 0x3ff); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > maximum = 0x3ff; > ~~~~~~~~~~~~~~~~ > } > ~ > > > int CLASS raw (unsigned row, unsigned col) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > return (row < raw_height && col < raw_width) ? RAW(row,col) : 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS phase_one_flat_field (int is_float, int nc) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > ushort head[8]; > ~~~~~~~~~~~~~~~ > unsigned wide, high, y, x, c, rend, cend, row, col; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float *mrow, num, mult[4]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > read_shorts (head, 8); > ~~~~~~~~~~~~~~~~~~~~~~ > if (head[2] * head[3] * head[4] * head[5] == 0) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > wide = head[2] / head[4] + (head[2] % head[4] != 0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > high = head[3] / head[5] + (head[3] % head[5] != 0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > mrow = (float *) calloc (nc*wide, sizeof *mrow); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (mrow, "phase_one_flat_field()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (y=0; y < high; y++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (x=0; x < wide; x++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > for (c=0; c < nc; c+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > num = is_float ? getreal(11) : get2()/32768.0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (y==0) mrow[c*wide+x] = num; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else mrow[(c+1)*wide+x] = (num - mrow[c*wide+x]) / head[5]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (y==0) continue; > ~~~~~~~~~~~~~~~~~~~ > rend = head[1] + y*head[5]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row = rend-head[5]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > row < raw_height && row < rend && > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row < head[1]+head[3]-head[5]; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (x=1; x < wide; x++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (c=0; c < nc; c+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > mult[c] = mrow[c*wide+x-1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > mult[c+1] = (mrow[c*wide+x] - mult[c]) / head[4]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > cend = head[0] + x*head[4]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col = cend-head[4]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > col < raw_width && > ~~~~~~~~~~~~~~~~~~ > col < cend && col < head[0]+head[2]-head[4]; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > c = nc > 2 ? FC(row-top_margin,col-left_margin) : 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!(c & 1)) { > ~~~~~~~~~~~~~~~ > c = RAW(row,col) * mult[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = LIM(c,0,65535); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (c=0; c < nc; c+=2) > ~~~~~~~~~~~~~~~~~~~~~~~ > mult[c] += mult[c+1]; > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > for (x=0; x < wide; x++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > for (c=0; c < nc; c+=2) > ~~~~~~~~~~~~~~~~~~~~~~~ > mrow[c*wide+x] += mrow[(c+1)*wide+x]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > free (mrow); > ~~~~~~~~~~~~ > } > ~ > > > void CLASS phase_one_correct() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned entries, tag, data, save, col, row, type; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int len, i, j, k, cip, val[4], dev[4], sum, max; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int head[9], diff, mindiff=INT_MAX, off_412=0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > static const signed char dir[12][2] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { {-1,-1}, {-1,1}, {1,-1}, {1,1}, {-2,0}, {0,-2}, {0,2}, {2,0}, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > {-2,-2}, {-2,2}, {2,-2}, {2,2} }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float poly[8], num, cfrac, frac, mult[2], *yval[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort *xval[2]; > ~~~~~~~~~~~~~~~~ > int qmult_applied = 0, qlin_applied = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > if (half_size || !meta_length) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (verbose) fprintf (stderr,_("Phase One correction...\n")); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, meta_offset, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > order = get2(); > ~~~~~~~~~~~~~~~ > fseek (ifp, 6, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, meta_offset+get4(), SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > entries = get4(); get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (entries--) { > ~~~~~~~~~~~~~~~~~~~ > tag = get4(); > ~~~~~~~~~~~~~~ > len = get4(); > ~~~~~~~~~~~~~~ > data = get4(); > ~~~~~~~~~~~~~~ > save = ftell(ifp); > ~~~~~~~~~~~~~~~~~~ > fseek (ifp, meta_offset+data, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0x419) { /* Polynomial curve */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (get4(), i=0; i < 8; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > poly[i] = getreal(11); > ~~~~~~~~~~~~~~~~~~~~~~ > poly[3] += (ph1.tag_210 - poly[7]) * poly[6] + 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 0x10000; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > num = (poly[5]*i + poly[3])*i + poly[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > curve[i] = LIM(num,0,65535); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } goto apply; /* apply to right half */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else if (tag == 0x41a) { /* Polynomial curve */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 4; i++) > ~~~~~~~~~~~~~~~~~~~~~ > poly[i] = getreal(11); > ~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 0x10000; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (num=0, j=4; j--; ) > ~~~~~~~~~~~~~~~~~~~~~~~ > num = num * i + poly[j]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > curve[i] = LIM(num+i,0,65535); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } apply: /* apply to whole image */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col = (tag & 1)*ph1.split_col; col < raw_width; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = curve[RAW(row,col)]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else if (tag == 0x400) { /* Sensor defects */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while ((len -= 8) >= 0) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > col = get2(); > ~~~~~~~~~~~~~~ > row = get2(); > ~~~~~~~~~~~~~~ > type = get2(); get2(); > ~~~~~~~~~~~~~~~~~~~~~~ > if (col >= raw_width) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (type == 131 || type == 137) /* Bad column */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (FC(row-top_margin,col-left_margin) == 1) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (sum=i=0; i < 4; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~ > sum += val[i] = raw (row+dir[i][0], col+dir[i][1]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (max=i=0; i < 4; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > dev[i] = abs((val[i] << 2) - sum); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (dev[max] < dev[i]) max = i; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > RAW(row,col) = (sum - val[max])/3.0 + 0.5; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else { > ~~~~~~~~ > for (sum=0, i=8; i < 12; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sum += raw (row+dir[i][0], col+dir[i][1]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = 0.5 + sum * 0.0732233 + > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (raw(row,col-2) + raw(row,col+2)) * 0.3535534; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > else if (type == 129) { /* Bad pixel */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (row >= raw_height) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > j = (FC(row-top_margin,col-left_margin) != 1) * 4; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (sum=0, i=j; i < j+8; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sum += raw (row+dir[i][0], col+dir[i][1]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = (sum + 4) >> 3; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } else if (tag == 0x401) { /* All-color flat fields */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > phase_one_flat_field (1, 2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else if (tag == 0x416 || tag == 0x410) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > phase_one_flat_field (0, 2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else if (tag == 0x40b) { /* Red+blue flat field */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > phase_one_flat_field (0, 4); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else if (tag == 0x412) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 36, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff = abs (get2() - ph1.tag_21a); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (mindiff > diff) { > ~~~~~~~~~~~~~~~~~~~~~ > mindiff = diff; > ~~~~~~~~~~~~~~~ > off_412 = ftell(ifp) - 38; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } else if (tag == 0x41f && !qlin_applied) { /* Quadrant linearization */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort lc[2][2][16], ref[16]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int qr, qc; > ~~~~~~~~~~~ > for (qr = 0; qr < 2; qr++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (qc = 0; qc < 2; qc++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i = 0; i < 16; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > lc[qr][qc][i] = get4(); > ~~~~~~~~~~~~~~~~~~~~~~~ > for (i = 0; i < 16; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > int v = 0; > ~~~~~~~~~~ > for (qr = 0; qr < 2; qr++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (qc = 0; qc < 2; qc++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > v += lc[qr][qc][i]; > ~~~~~~~~~~~~~~~~~~~ > ref[i] = (v + 2) >> 2; > ~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (qr = 0; qr < 2; qr++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (qc = 0; qc < 2; qc++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int cx[19], cf[19]; > ~~~~~~~~~~~~~~~~~~~ > for (i = 0; i < 16; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > cx[1+i] = lc[qr][qc][i]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > cf[1+i] = ref[i]; > ~~~~~~~~~~~~~~~~~ > } > ~ > cx[0] = cf[0] = 0; > ~~~~~~~~~~~~~~~~~~ > cx[17] = cf[17] = ((unsigned) ref[15] * 65535) / lc[qr][qc][15]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cx[18] = cf[18] = 65535; > ~~~~~~~~~~~~~~~~~~~~~~~~ > cubic_spline(cx, cf, 19); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row = (qr ? ph1.split_row : 0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row < (qr ? raw_height : ph1.split_row); row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col = (qc ? ph1.split_col : 0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > col < (qc ? raw_width : ph1.split_col); col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = curve[RAW(row,col)]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > qlin_applied = 1; > ~~~~~~~~~~~~~~~~~ > } else if (tag == 0x41e && !qmult_applied) { /* Quadrant multipliers */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float qmult[2][2] = { { 1, 1 }, { 1, 1 } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > get4(); get4(); get4(); get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > qmult[0][0] = 1.0 + getreal(11); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > get4(); get4(); get4(); get4(); get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > qmult[0][1] = 1.0 + getreal(11); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > get4(); get4(); get4(); > ~~~~~~~~~~~~~~~~~~~~~~~ > qmult[1][0] = 1.0 + getreal(11); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > get4(); get4(); get4(); > ~~~~~~~~~~~~~~~~~~~~~~~ > qmult[1][1] = 1.0 + getreal(11); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = qmult[row >= ph1.split_row][col >= ph1.split_col] * RAW(row,col); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = LIM(i,0,65535); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > qmult_applied = 1; > ~~~~~~~~~~~~~~~~~~ > } else if (tag == 0x431 && !qmult_applied) { /* Quadrant combined */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort lc[2][2][7], ref[7]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int qr, qc; > ~~~~~~~~~~~ > for (i = 0; i < 7; i++) > ~~~~~~~~~~~~~~~~~~~~~~~ > ref[i] = get4(); > ~~~~~~~~~~~~~~~~ > for (qr = 0; qr < 2; qr++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (qc = 0; qc < 2; qc++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i = 0; i < 7; i++) > ~~~~~~~~~~~~~~~~~~~~~~~ > lc[qr][qc][i] = get4(); > ~~~~~~~~~~~~~~~~~~~~~~~ > for (qr = 0; qr < 2; qr++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (qc = 0; qc < 2; qc++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int cx[9], cf[9]; > ~~~~~~~~~~~~~~~~~ > for (i = 0; i < 7; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > cx[1+i] = ref[i]; > ~~~~~~~~~~~~~~~~~ > cf[1+i] = ((unsigned) ref[i] * lc[qr][qc][i]) / 10000; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > cx[0] = cf[0] = 0; > ~~~~~~~~~~~~~~~~~~ > cx[8] = cf[8] = 65535; > ~~~~~~~~~~~~~~~~~~~~~~ > cubic_spline(cx, cf, 9); > ~~~~~~~~~~~~~~~~~~~~~~~~ > for (row = (qr ? ph1.split_row : 0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row < (qr ? raw_height : ph1.split_row); row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col = (qc ? ph1.split_col : 0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > col < (qc ? raw_width : ph1.split_col); col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = curve[RAW(row,col)]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > qmult_applied = 1; > ~~~~~~~~~~~~~~~~~~ > qlin_applied = 1; > ~~~~~~~~~~~~~~~~~ > } > ~ > fseek (ifp, save, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (off_412) { > ~~~~~~~~~~~~~~ > fseek (ifp, off_412, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 9; i++) head[i] = get4() & 0x7fff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > yval[0] = (float *) calloc (head[1]*head[3] + head[2]*head[4], 6); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (yval[0], "phase_one_correct()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > yval[1] = (float *) (yval[0] + head[1]*head[3]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > xval[0] = (ushort *) (yval[1] + head[2]*head[4]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > xval[1] = (ushort *) (xval[0] + head[1]*head[3]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > get2(); > ~~~~~~~ > for (i=0; i < 2; i++) > ~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < head[i+1]*head[i+3]; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > yval[i][j] = getreal(11); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 2; i++) > ~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < head[i+1]*head[i+3]; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > xval[i][j] = get2(); > ~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cfrac = (float) col * head[3] / raw_width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cfrac -= cip = cfrac; > ~~~~~~~~~~~~~~~~~~~~~ > num = RAW(row,col) * 0.5; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=cip; i < cip+2; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (k=j=0; j < head[1]; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (num < xval[0][k = head[1]*i+j]) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > frac = (j == 0 || j == head[1]) ? 0 : > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (xval[0][k] - num) / (xval[0][k] - xval[0][k-1]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > mult[i-cip] = yval[0][k-1] * frac + yval[0][k] * (1-frac); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > i = ((mult[0] * (1-cfrac) + mult[1] * cfrac) * row + num) * 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = LIM(i,0,65535); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > free (yval[0]); > ~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS phase_one_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int a, b, i; > ~~~~~~~~~~~~ > ushort akey, bkey, mask; > ~~~~~~~~~~~~~~~~~~~~~~~~ > > > fseek (ifp, ph1.key_off, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > akey = get2(); > ~~~~~~~~~~~~~~ > bkey = get2(); > ~~~~~~~~~~~~~~ > mask = ph1.format == 1 ? 0x5555:0x1354; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, data_offset, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > read_shorts (raw_image, raw_width*raw_height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ph1.format) > ~~~~~~~~~~~~~~~ > for (i=0; i < raw_width*raw_height; i+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > a = raw_image[i+0] ^ akey; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > b = raw_image[i+1] ^ bkey; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > raw_image[i+0] = (a & mask) | (b & ~mask); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > raw_image[i+1] = (b & mask) | (a & ~mask); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > unsigned CLASS ph1_bithuff_t::operator() (int nbits, ushort *huff) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > /*RT static UINT64 bitbuf=0; */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > /*RT static int vbits=0; */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unsigned c; > ~~~~~~~~~~~ > > > if (nbits == -1) > ~~~~~~~~~~~~~~~~ > return bitbuf = vbits = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (nbits == 0) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if (vbits < nbits) { > ~~~~~~~~~~~~~~~~~~~~ > bitbuf = bitbuf << 32 | get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > vbits += 32; > ~~~~~~~~~~~~ > } > ~ > c = bitbuf << (64-vbits) >> (64-nbits); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (huff) { > ~~~~~~~~~~~ > vbits -= huff[c] >> 8; > ~~~~~~~~~~~~~~~~~~~~~~ > return (uchar) huff[c]; > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > vbits -= nbits; > ~~~~~~~~~~~~~~~ > return c; > ~~~~~~~~~ > } > ~ > #define ph1_bits(n) ph1_bithuff(n,0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #define ph1_huff(h) ph1_bithuff(*h,h+1) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > void CLASS phase_one_load_raw_c() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const int length[] = { 8,7,6,9,11,10,5,12,14,13 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int *offset, len[2], pred[2], row, col, i, j; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort *pixel; > ~~~~~~~~~~~~~~ > short (*cblack)[2], (*rblack)[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > pixel = (ushort *) calloc (raw_width*3 + raw_height*4, 2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (pixel, "phase_one_load_raw_c()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > offset = (int *) (pixel + raw_width); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, strip_offset, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > offset[row] = get4(); > ~~~~~~~~~~~~~~~~~~~~~ > cblack = (short (*)[2]) (offset + raw_height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, ph1.black_col, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ph1.black_col) > ~~~~~~~~~~~~~~~~~~ > read_shorts ((ushort *) cblack[0], raw_height*2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > rblack = cblack + raw_height; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, ph1.black_row, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ph1.black_row) > ~~~~~~~~~~~~~~~~~~ > read_shorts ((ushort *) rblack[0], raw_width*2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 256; i++) > ~~~~~~~~~~~~~~~~~~~~~~~ > curve[i] = i*i / 3.969 + 0.5; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, data_offset + offset[row], SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ph1_bits(-1); > ~~~~~~~~~~~~~ > pred[0] = pred[1] = 0; > ~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col >= (raw_width & -8)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > len[0] = len[1] = 14; > ~~~~~~~~~~~~~~~~~~~~~ > else if ((col & 7) == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 2; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 5 && !ph1_bits(1); j++); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (j--) len[i] = length[j*2 + ph1_bits(1)]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if ((i = len[col & 1]) == 14) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pixel[col] = pred[col & 1] = ph1_bits(16); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else > ~~~~ > pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (pred[col & 1] >> 16) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ph1.format == 5 && pixel[col] < 256) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pixel[col] = curve[pixel[col]]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (col=0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = (pixel[col] << 2*(ph1.format != 8)) - ph1.black > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > + cblack[row][col >= ph1.split_col] > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > + rblack[col][row >= ph1.split_row]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (i > 0) RAW(row,col) = i; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > free (pixel); > ~~~~~~~~~~~~~ > maximum = 0xfffc - ph1.black; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS parse_hasselblad_gain() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > /* > ~~ > Reverse-engineer's notes: > ~~~~~~~~~~~~~~~~~~~~~~~~~ > > > The Hasselblad gain tag (0x19 in makernotes) is only available in the 3FR format and > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > is applied and removed when Hasselblad Phocus converts it to the FFF format. It's > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > always 0x300000 bytes large regardless of (tested) model, not all space in it is > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > used though. > ~~~~~~~~~~~~ > > > It contains individual calibration information from the factory to tune the sensor > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > performance. > ~~~~~~~~~~~~ > > > There is more calibration data in the tag than what is applied in conversion to FFF, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > I've only cared to figure out the data which is actually used, but have some leads on > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > remaining info. > ~~~~~~~~~~~~~~~ > > > The format is not equal between all models. Due to lack of 3FR files (harder to get > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > than FFF) only a subset of the models have been reverse-engineered. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > The header space is 512 bytes and is a mix of 16 and 32 bit values. Offset to blocks > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > are 32 bit values, but all information seems to be encoded in 16 bit values. Many > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > values in the header can be zeroed with no effect on FFF conversion, and their > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > meaning, if any, have not been further investigated. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > Formats: > ~~~~~~~~ > hdr16[22] = raw width > ~~~~~~~~~~~~~~~~~~~~~ > hdr16[23] = raw height > ~~~~~~~~~~~~~~~~~~~~~~ > hdr32[24] = offset to level corr block > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > Data block format. Seems to differ depending on sensor type. For tested H4D-50 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > and H3D-31: 10 16 bit signed values per row > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > value 0: a correction factor (k) used on even columns, where the new pixel value is > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > calulated as follows: > ~~~~~~~~~~~~~~~~~~~~~ > new_value = old_value + (2 * ((k * (old_value_on_row_above-256)) / 32767) - 2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > note the connection to the value on the row above, seems to be some sort of signal > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > leakage correction. > ~~~~~~~~~~~~~~~~~~~ > value 1: same as value 0 but using old value on row below instead of above > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > value 2-3: same as value 0-1 but for odd columns > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > value 4-9: has some effect if non-zero (probably similar to the others) but not > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > investigated which, as it's seems to be always zero for the tested cameras. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > hdr32[25] = probably offset to "bad/unreliable pixels" info, always 512 as it starts > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > directly after the header. Not applied in FFF conversion (at least > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > typically). > ~~~~~~~~~~~ > Data block format guess: raw_height packets of > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > <type?><number of coords><coords...> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > hdr32[27] = offset to unknown data (bad colulmns?), of the form: > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > <packet count><packets><0> > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > packet: <column><?><?><?>. > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > hdr32[34] = curves offset, seems to be A/D curves (one per channel) on newer models > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > and some sort of a film curve on older. Not applied in FFF conversion. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > hdr32[36] = flatfield correction, not available in older models. Data format: > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > <1><block width><block height><rows><cols><11 * 2 pad><packets> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > packet: <R><G1><G2><B> > ~~~~~~~~~~~~~~~~~~~~~~ > > > The header pad is not zeroed and might seem to contain some sort of > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > information, but it makes no difference if set to zero. See > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > hasselblad_correct() how the flatfield is applied. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > Applied in FFF conversion is levels, flatfield correction, and the bad columns(?) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > data. A/D curves are surprisingly not applied, maybe pre-applied in hardware and > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > only available as information? Levels are applied before flatfield, further > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ordering has not been investigated. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > Not all combinations/models have been tested so there may be gaps. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > Most clipped pixels in a 3FR is at 65535, but there's also some at 65534. Both > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > are set to 65535 when calibrated, while 65533 is treated as a normal value. In > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > the calibration process smaller values can be scaled to 65534 (which should > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > not be seen as clipped). > ~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > > > ushort raw_h, count, ch_count, u16; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int i, offset; > ~~~~~~~~~~~~~~ > off_t base; > ~~~~~~~~~~~ > > > base = ftell(ifp); > ~~~~~~~~~~~~~~~~~~ > fseek(ifp, 2 * 23, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > raw_h = get2(); > ~~~~~~~~~~~~~~~ > fseek(ifp, 48, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > offset = get4(); > ~~~~~~~~~~~~~~~~ > hbd.levels = offset ? base + offset : 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek(ifp, 8, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~ > offset = get4(); > ~~~~~~~~~~~~~~~~ > hbd.unknown1 = offset ? base + offset : 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek(ifp, 32, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > offset = get4(); > ~~~~~~~~~~~~~~~~ > hbd.flatfield = offset ? base + offset : 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS hasselblad_correct() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned col, row; > ~~~~~~~~~~~~~~~~~~ > > > /* > ~~ > > > This function applies 3FR calibration data. At the time of writing it supports a > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > subset, so here's a todo list: > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > TODO: > ~~~~~ > - Support all gain tag formats > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > - The 0x19 tag varies a bit between models. We don't have parsers for all models. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > - The reference model used was during inital reverse-engineering was a H4D-50, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > we probably support the Hasselblads with Kodak 31, 39, 40 and 50 megapixels > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > well, but more work is needed for Kodak 16 and 22, Dalsa 60 and Sony 50. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > - Apply bad column(?) data (hbd.unknown1) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > - It was left out in this initial release since the effect is very small. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > - Apply black(?) data, tag 0x1a and 0x1b is not parsed, it has however marginal > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > effect (at least for shorter exposures) so it's not too important. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > While there are things to do, the current implementation supports the most > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > important aspects, the faltfield and levels calibrations applied can have strong > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > visible effects. > ~~~~~~~~~~~~~~~~ > > > */ > ~~ > > > if (hbd.levels) { > ~~~~~~~~~~~~~~~~~ > int i; > ~~~~~~ > fseek(ifp, hbd.levels, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > /* skip the first set (not used as we don't apply on first/last row), we look at it though to see if > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > the levels format is one that we support (there are other formats on some models which is not > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > supported here) */ > ~~~~~~~~~~~~~~~~~~ > short test[10]; > ~~~~~~~~~~~~~~~ > for (i = 0; i < 10; i++) test[i] = (short)get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (test[5] == 0 && test[6] == 0 && test[7] == 0 && test[8] == 0 && test[9] == 0) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int corr[4]; > ~~~~~~~~~~~~ > ushort *row_above = (ushort *)malloc(sizeof(ushort) * raw_width); // we need to cache row above as we write new values as we go > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col = 0; col < raw_width; col++) row_above[col] = RAW(0,col); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row = 1; row < raw_height-1; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i = 0; i < 4; i++) corr[i] = (short)get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek(ifp, 6 * 2, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col = 0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unsigned v = RAW(row,col); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (v >= 65534) { > ~~~~~~~~~~~~~~~~~ > v = 65535; > ~~~~~~~~~~ > } else { > ~~~~~~~~ > if (corr[((col & 1)<<1)+0] && row_above[col] > black) v += 2 * ((corr[((col & 1)<<1)+0] * (row_above[col]-(int)black)) / 32767) - 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (corr[((col & 1)<<1)+1] && RAW(row+1,col) > black) v += 2 * ((corr[((col & 1)<<1)+1] * (RAW(row+1,col)-(int)black)) / 32767) - 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > row_above[col] = RAW(row,col); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = CLIP(v); > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > free(row_above); > ~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > if (hbd.flatfield) { > ~~~~~~~~~~~~~~~~~~~~ > int bw, bh, ffrows, ffcols, i, c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort ref[4], ref_max; > ~~~~~~~~~~~~~~~~~~~~~~~ > fseek(ifp, hbd.flatfield, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > get2(); > ~~~~~~~ > bw = get2(); > ~~~~~~~~~~~~ > bh = get2(); > ~~~~~~~~~~~~ > ffcols = get2(); > ~~~~~~~~~~~~~~~~ > ffrows = get2(); > ~~~~~~~~~~~~~~~~ > fseek(ifp, hbd.flatfield + 16 * 2, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > ushort *ffmap = (ushort *)malloc(sizeof(*ffmap) * 4 * ffcols * ffrows); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i = 0; i < 4 * ffcols * ffrows; i++) ffmap[i] = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > /* Get reference values from center of field. This seems to be what Phocus does too, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > but haven't cared to figure out exactly at which coordinate */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = 4 * (ffcols * ffrows / 2 + ffcols / 2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ref[0] = ffmap[i+0]; > ~~~~~~~~~~~~~~~~~~~~ > ref[1] = ffmap[i+1]; > ~~~~~~~~~~~~~~~~~~~~ > ref[3] = ffmap[i+2]; // G2 = index 3 in dcraw, 2 in 3FR > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ref[2] = ffmap[i+3]; > ~~~~~~~~~~~~~~~~~~~~ > ref_max = 0; > ~~~~~~~~~~~~ > FORC4 if (ref[c] > ref_max) ref_max = ref[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ref_max == 0) ref[0] = ref[1] = ref[2] = ref[3] = ref_max = 10000; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > /* Convert measured flatfield values to actual multipliers. The measured flatfield > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > can have vignetting which should be normalized, only color cast should be corrected. */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i = 0; i < 4 * ffcols * ffrows; i += 4) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > double base, min = 65535.0, max = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > double cur[4]; > ~~~~~~~~~~~~~~ > cur[0] = (double)ffmap[i+0] / ref[0]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cur[1] = (double)ffmap[i+1] / ref[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cur[3] = (double)ffmap[i+2] / ref[3]; // G2 index differs in dcraw and 3FR > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cur[2] = (double)ffmap[i+3] / ref[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 { > ~~~~~~~ > if (cur[c] < min) min = cur[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (cur[c] > max) max = cur[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (max == 0) max = 1.0; > ~~~~~~~~~~~~~~~~~~~~~~~~ > base = (cur[0]+cur[1]+cur[2]+cur[3])/(max*4); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 cur[c] = cur[c] == 0 ? 1.0 : (base * max) / cur[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > /* convert to integer multiplier and store back to ffmap, we limit > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > range to 4 (16384*4) which should be fine for flatfield */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 { > ~~~~~~~ > cur[c] *= 16384.0; > ~~~~~~~~~~~~~~~~~~ > if (cur[c] > 65535.0) cur[c] = 65535.0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ffmap[i+c] = (ushort)cur[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > // of the cameras we've tested we know the exact placement of the flatfield map > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int row_offset, col_offset; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > switch (raw_width) { > ~~~~~~~~~~~~~~~~~~~~ > case 8282: // 50 megapixel Kodak > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row_offset = 21; > ~~~~~~~~~~~~~~~~ > col_offset = 71; > ~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > default: > ~~~~~~~~ > /* Default case for camera models we've not tested. We center the map, which may > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > not be exactly where it should be but close enough for the smooth flatfield */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row_offset = (raw_height - bh * ffrows) / 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > col_offset = (raw_width - bw * ffcols) / 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > } > ~ > > > /* > ~~ > Concerning smoothing between blocks in the map Phocus makes it only vertically, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > probably because it's simpler and faster. Looking at actual flatfield data it seems > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > like it's better to smooth in both directions. Possibly flatfield could be used for > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > correcting tiling on Dalsa sensors (H4D-60) like partly done in Phase One IIQ format, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > and then sharp edges may be beneficial at least at the tiling seams, but at the time > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > of writing I've had no H4D-60 3FR files to test with to verify that. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > Meanwhile we do both vertical and horizontal smoothing/blurring. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > > > /* pre-calculate constants for blurring. We probably should make a more efficient > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > blur than this, but this does not need any buffer and makes nice-looking > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > radial gradients */ > ~~~~~~~~~~~~~~~~~~~ > ushort *corners_weight = (ushort *)malloc(bw*bh*9*sizeof(*corners_weight)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > const int corners_mix[9][4][2] = { { {0,0}, {0,1}, {1,0}, {1,1} }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { {0,1}, {1,1}, {-1,-1}, {-1,-1} }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { {0,1}, {0,2}, {1,1}, {1,2} }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { {1,0}, {1,1}, {-1,-1}, {-1,-1} }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { {1,1}, {-1,-1}, {-1,-1}, {-1,-1} }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { {1,1}, {1,2}, {-1,-1}, {-1,-1} }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { {1,0}, {1,1}, {2,0}, {2,1} }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { {1,1}, {2,1}, {-1,-1}, {-1,-1} }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { {1,1}, {1,2}, {2,1}, {2,2} } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > const ushort corners_shift[9] = { 2, 1, 2, 1, 0, 1, 2, 1, 2 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row = 0; row < bh; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > const ushort maxdist = bw < bh ? bw/2-1 : bh/2-1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > const unsigned bwu = (unsigned)bw; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > const unsigned bhu = (unsigned)bh; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > const unsigned corners[9][2] = {{0,0}, {0,bwu/2}, {0,bwu-1}, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > {bhu/2,0},{bhu/2,bwu/2},{bhu/2,bwu-1}, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > {bhu-1,0},{bhu-1,bwu/2},{bhu-1,bwu-1}}; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col = 0; col < bw; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i = 0; i < 9; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort dist = (ushort)sqrt(abs(corners[i][0] - row) * abs(corners[i][0] - row) + abs(corners[i][1] - col) * abs(corners[i][1] - col)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort weight = dist > maxdist ? 0 : maxdist - dist; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > corners_weight[9*(row*bw+col)+i] = weight; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > > > // apply flatfield > ~~~~~~~~~~~~~~~~~~ > #pragma omp parallel for > ~~~~~~~~~~~~~~~~~~~~~~~~ > for (int row = 0; row < raw_height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int ffs, cur_ffr, i, c; > ~~~~~~~~~~~~~~~~~~~~~~~ > if (row < row_offset) { > ~~~~~~~~~~~~~~~~~~~~~~~ > cur_ffr = row_offset; > ~~~~~~~~~~~~~~~~~~~~~ > ffs = 0; > ~~~~~~~~ > } else if (row >= row_offset + ffrows * bh) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cur_ffr = row_offset + (ffrows-1) * bh; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ffs = 4 * ffcols * (ffrows-1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else { > ~~~~~~~~ > cur_ffr = row_offset + bh * ((row - row_offset) / bh); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ffs = 4 * ffcols * ((row - row_offset) / bh); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > int next_ffc = 0, cur_ffc = col_offset; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int ffc = ffs; > ~~~~~~~~~~~~~~ > ushort *cur[3][3]; // points to local ffmap entries with center at cur[1][1] > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (int col = 0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col == next_ffc) { > ~~~~~~~~~~~~~~~~~~~~~~ > int rowsub = ffs == 0 ? 0 : ffcols*4; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int rowadd = ffs == 4 * ffcols * (ffrows-1) ? 0 : ffcols * 4; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int colsub = ffc == ffs ? 0 : 4; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int coladd = ffc == ffs + 4 * (ffcols-1) ? 0 : 4; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col != 0) cur_ffc = next_ffc; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else next_ffc += col_offset; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > next_ffc += bw; > ~~~~~~~~~~~~~~~ > > > cur[0][0] = &ffmap[ffc-rowsub-colsub]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cur[0][1] = &ffmap[ffc-rowsub]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cur[0][2] = &ffmap[ffc-rowsub+coladd]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > cur[1][0] = &ffmap[ffc-colsub]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cur[1][1] = &ffmap[ffc]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > cur[1][2] = &ffmap[ffc+coladd]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > cur[2][0] = &ffmap[ffc+rowadd-colsub]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cur[2][1] = &ffmap[ffc+rowadd]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cur[2][2] = &ffmap[ffc+rowadd+coladd]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > ffc += 4; > ~~~~~~~~~ > if (ffc == ffs + 4 * ffcols) next_ffc += raw_width; // last col in map, avoid stepping further > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > unsigned v = RAW(row,col); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (v > black && v < 65535) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > c = FC(row,col); > ~~~~~~~~~~~~~~~~ > unsigned x = col < cur_ffc ? 0 : col - cur_ffc; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unsigned y = row < cur_ffr ? 0 : row - cur_ffr; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (x >= bw) x = bw-1; > ~~~~~~~~~~~~~~~~~~~~~~ > if (y >= bh) y = bh-1; > ~~~~~~~~~~~~~~~~~~~~~~ > unsigned wsum = 0; > ~~~~~~~~~~~~~~~~~~ > unsigned mul = 0; > ~~~~~~~~~~~~~~~~~ > for (i = 0; i < 9; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort cw = corners_weight[9*(y*bw+x)+i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (cw) { > ~~~~~~~~~ > unsigned m = 0; > ~~~~~~~~~~~~~~~ > int j; > ~~~~~~ > for (j = 0; j < 1 << corners_shift[i]; j++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int cr = corners_mix[i][j][0], cc = corners_mix[i][j][1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > m += cur[cr][cc][c]; > ~~~~~~~~~~~~~~~~~~~~ > } > ~ > m >>= corners_shift[i]; > ~~~~~~~~~~~~~~~~~~~~~~~ > mul += m * cw; > ~~~~~~~~~~~~~~ > wsum += cw; > ~~~~~~~~~~~ > } > ~ > } > ~ > mul /= wsum; > ~~~~~~~~~~~~ > v = black + ((v-black) * mul) / 16384; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = v > 65535 ? 65535 : v; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > free(ffmap); > ~~~~~~~~~~~~ > free(corners_weight); > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS hasselblad_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > struct jhead jh; > ~~~~~~~~~~~~~~~~ > int shot, row, col, *back[5], len[2], diff[12], pred, sh, f, s, c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unsigned upix, urow, ucol; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort *ip; > ~~~~~~~~~~~ > > > if (!ljpeg_start (&jh, 0)) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > order = 0x4949; > ~~~~~~~~~~~~~~~ > ph1_bits(-1); > ~~~~~~~~~~~~~ > back[4] = (int *) calloc (raw_width, 3*sizeof **back); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (back[4], "hasselblad_load_raw()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 back[c] = back[4] + c*raw_width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cblack[6] >>= sh = tiff_samples > 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > shot = LIM(shot_select, 1, tiff_samples) - 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 back[(c+3) & 3] = back[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width; col+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (s=0; s < tiff_samples*2; s+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(2) len[c] = ph1_huff(jh.huff[0]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(2) { > ~~~~~~~~~ > diff[s+c] = ph1_bits(len[c]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((diff[s+c] & (1 << (len[c]-1))) == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff[s+c] -= (1 << len[c]) - 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (diff[s+c] == 65535) diff[s+c] = -32768; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > for (s=col; s < col+2; s++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pred = 0x8000 + load_flags; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col) pred = back[2][s-2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col && row > 1) switch (jh.psv) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 11: pred += back[0][s]/2 - back[0][s-2]/2; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > f = (row & 1)*3 ^ ((col+s) & 1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC (tiff_samples) { > ~~~~~~~~~~~~~~~~~~~~~ > pred += diff[(s & 1)*tiff_samples+c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > upix = pred >> sh & 0xffff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (raw_image && c == shot) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,s) = upix; > ~~~~~~~~~~~~~~~~~~ > if (image) { > ~~~~~~~~~~~~ > urow = row-top_margin + (c & 1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ucol = col-left_margin - ((c >> 1) & 1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ip = &image[urow*width+ucol][f]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (urow < height && ucol < width) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > *ip = c < 4 ? upix : (*ip + upix) >> 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > back[2][s] = pred; > ~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > free (back[4]); > ~~~~~~~~~~~~~~~ > ljpeg_end (&jh); > ~~~~~~~~~~~~~~~~ > if (image) mix_green = 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS leaf_hdr_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > ushort *pixel=0; > ~~~~~~~~~~~~~~~~ > unsigned tile=0, r, c, row, col; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > if (!filters) { > ~~~~~~~~~~~~~~~ > pixel = (ushort *) calloc (raw_width, sizeof *pixel); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (pixel, "leaf_hdr_load_raw()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > FORC(tiff_samples) > ~~~~~~~~~~~~~~~~~~ > for (r=0; r < raw_height; r++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (r % tile_length == 0) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, data_offset + 4*tile++, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, get4(), SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (filters && c != shot_select) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (filters) pixel = raw_image + r*raw_width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > read_shorts (pixel, raw_width); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!filters && (row = r - top_margin) < height) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > image[row*width+col][c] = pixel[col+left_margin]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (!filters) { > ~~~~~~~~~~~~~~~ > maximum = 0xffff; > ~~~~~~~~~~~~~~~~~ > raw_color = 1; > ~~~~~~~~~~~~~~ > free (pixel); > ~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS unpacked_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int row, col, bits=0; > ~~~~~~~~~~~~~~~~~~~~~ > > > while (1 << ++bits < maximum); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > read_shorts (raw_image, raw_width*raw_height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((RAW(row,col) >>= load_flags) >> bits > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > && (unsigned) (row-top_margin) < height > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > && (unsigned) (col-left_margin) < width) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS sinar_4shot_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > ushort *pixel; > ~~~~~~~~~~~~~~ > unsigned shot, row, col, r, c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > if (raw_image) { > ~~~~~~~~~~~~~~~~ > shot = LIM (shot_select, 1, 4) - 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, data_offset + shot*4, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, get4(), SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unpacked_load_raw(); > ~~~~~~~~~~~~~~~~~~~~ > return; > ~~~~~~~ > } > ~ > pixel = (ushort *) calloc (raw_width, sizeof *pixel); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (pixel, "sinar_4shot_load_raw()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (shot=0; shot < 4; shot++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, data_offset + shot*4, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, get4(), SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > read_shorts (pixel, raw_width); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((c = col-left_margin - (shot & 1)) >= width) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > image[r*width+c][(row & 1)*3 ^ (~col & 1)] = pixel[col]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > free (pixel); > ~~~~~~~~~~~~~ > mix_green = 1; > ~~~~~~~~~~~~~~ > } > ~ > > > void CLASS imacon_full_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int row, col; > ~~~~~~~~~~~~~ > > > if (!image) return; > ~~~~~~~~~~~~~~~~~~~ > for (row=0; row < height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > read_shorts (image[row*width+col], 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS packed_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int vbits=0, bwide, rbits, bite, half, irow, row, col, val, i; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > UINT64 bitbuf=0; > ~~~~~~~~~~~~~~~~ > > > bwide = raw_width * tiff_bps / 8; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > bwide += bwide & load_flags >> 7; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > rbits = bwide * 8 - raw_width * tiff_bps; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (load_flags & 1) bwide = bwide * 16 / 15; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > bite = 8 + (load_flags & 24); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > half = (raw_height+1) >> 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (irow=0; irow < raw_height; irow++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row = irow; > ~~~~~~~~~~~ > if (load_flags & 2 && > ~~~~~~~~~~~~~~~~~~~~~ > (row = irow % half * 2 + irow / half) == 1 && > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > load_flags & 4) { > ~~~~~~~~~~~~~~~~~ > if (vbits=0, tiff_compress) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, data_offset - (-half*bwide & -2048), SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else { > ~~~~~~ > fseek (ifp, 0, SEEK_END); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, ftell(ifp) >> 3 << 2, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > for (col=0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (vbits -= tiff_bps; vbits < 0; vbits += bite) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > bitbuf <<= bite; > ~~~~~~~~~~~~~~~~ > for (i=0; i < bite; i+=8) > ~~~~~~~~~~~~~~~~~~~~~~~~~ > bitbuf |= (unsigned) (fgetc(ifp) << i); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > val = bitbuf << (64-tiff_bps-vbits) >> (64-tiff_bps); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col ^ (load_flags >> 6 & 1)) = val; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (load_flags & 1 && (col % 10) == 9 && fgetc(ifp) && > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row < height+top_margin && col < width+left_margin) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > vbits -= rbits; > ~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS nokia_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar *data, *dp; > ~~~~~~~~~~~~~~~~~~~ > int rev, dwide, row, col, c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > double sum[]={0,0}; > ~~~~~~~~~~~~~~~~~~~ > > > rev = 3 * (order == 0x4949); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > dwide = (raw_width * 5 + 1) / 4; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > data = (uchar *) malloc (dwide*2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (data, "nokia_load_raw()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (fread (data+dwide, 1, dwide, ifp) < dwide) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(dwide) data[c] = data[dwide+(c ^ rev)]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (dp=data, col=0; col < raw_width; dp+=5, col+=4) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 RAW(row,col+c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > free (data); > ~~~~~~~~~~~~ > maximum = 0x3ff; > ~~~~~~~~~~~~~~~~ > if (strcmp(make,"OmniVision")) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row = raw_height/2; > ~~~~~~~~~~~~~~~~~~~ > FORC(width-1) { > ~~~~~~~~~~~~~~~ > sum[ c & 1] += SQR(RAW(row,c)-RAW(row+1,c+1)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sum[~c & 1] += SQR(RAW(row+1,c)-RAW(row,c+1)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (sum[1] > sum[0]) filters = 0x4b4b4b4b; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS canon_rmf_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int row, col, bits, orow, ocol, c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > for (row=0; row < raw_height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width-2; col+=3) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > bits = get4(); > ~~~~~~~~~~~~~~ > FORC3 { > ~~~~~~~ > orow = row; > ~~~~~~~~~~~ > if ((ocol = col+c-4) < 0) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ocol += raw_width; > ~~~~~~~~~~~~~~~~~~ > if ((orow -= 2) < 0) > ~~~~~~~~~~~~~~~~~~~~ > orow += raw_height; > ~~~~~~~~~~~~~~~~~~~ > } > ~ > RAW(orow,ocol) = curve[bits >> (10*c+2) & 0x3ff]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > maximum = curve[0x3ff]; > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > unsigned CLASS pana_bits_t::operator() (int nbits) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > /*RT static uchar buf[0x4000]; */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > /*RT static int vbits;*/ > ~~~~~~~~~~~~~~~~~~~~~~~~~ > int byte; > ~~~~~~~~~ > > > if (!nbits) return vbits=0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!vbits) { > ~~~~~~~~~~~~~ > fread (buf+load_flags, 1, 0x4000-load_flags, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (buf, 1, load_flags, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > vbits = (vbits - nbits) & 0x1ffff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > byte = vbits >> 3 ^ 0x3ff0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS panasonic_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int row, col, i, j, sh=0, pred[2], nonz[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > pana_bits(0); > ~~~~~~~~~~~~~ > for (row=0; row < height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((i = col % 14) == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~ > pred[0] = pred[1] = nonz[0] = nonz[1] = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (nonz[i & 1]) { > ~~~~~~~~~~~~~~~~~~ > if ((j = pana_bits(8))) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pred[i & 1] &= ~(-1 << sh); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pred[i & 1] += j << sh; > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } else if ((nonz[i & 1] = pana_bits(8)) || i > 11) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((RAW(row,col) = pred[col & 1]) > 4098 && col < width) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS olympus_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > ushort huff[4096]; > ~~~~~~~~~~~~~~~~~~ > int row, col, nbits, sign, low, high, i, c, w, n, nw; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int acarry[2][3], *carry, pred, diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > huff[n=0] = 0xc0c; > ~~~~~~~~~~~~~~~~~~ > for (i=12; i--; ) > ~~~~~~~~~~~~~~~~~ > FORC(2048 >> i) huff[++n] = (i+1) << 8 | i; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 7, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > getbits(-1); > ~~~~~~~~~~~~ > for (row=0; row < height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memset (acarry, 0, sizeof acarry); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > carry = acarry[col & 1]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > i = 2 * (carry[2] < 3); > ~~~~~~~~~~~~~~~~~~~~~~~ > for (nbits=2+i; (ushort) carry[0] >> (nbits+i); nbits++); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > low = (sign = getbits(3)) & 3; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sign = sign << 29 >> 31; > ~~~~~~~~~~~~~~~~~~~~~~~~ > if ((high = getbithuff(12,huff)) == 12) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > high = getbits(16-nbits) >> 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > carry[0] = (high << nbits) | getbits(nbits); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff = (carry[0] ^ sign) + carry[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > carry[1] = (diff*3 + carry[1]) >> 5; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > carry[2] = carry[0] > 16 ? 0 : carry[2]+1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col >= width) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (row < 2 && col < 2) pred = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else if (row < 2) pred = RAW(row,col-2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else if (col < 2) pred = RAW(row-2,col); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else { > ~~~~~~ > w = RAW(row,col-2); > ~~~~~~~~~~~~~~~~~~~~ > n = RAW(row-2,col); > ~~~~~~~~~~~~~~~~~~~~ > nw = RAW(row-2,col-2); > ~~~~~~~~~~~~~~~~~~~~~~ > if ((w < nw && nw < n) || (n < nw && nw < w)) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ABS(w-nw) > 32 || ABS(n-nw) > 32) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pred = w + n - nw; > ~~~~~~~~~~~~~~~~~~ > else pred = (w + n) >> 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > } else pred = ABS(w-nw) > ABS(n-nw) ? w : n; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if ((RAW(row,col) = pred + ((diff << 2) | low)) >> 12) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > > > void CLASS minolta_rd175_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar pixel[768]; > ~~~~~~~~~~~~~~~~~ > unsigned irow, box, row, col; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > for (irow=0; irow < 1481; irow++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (fread (pixel, 1, 768, ifp) < 768) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > box = irow / 82; > ~~~~~~~~~~~~~~~~ > row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > switch (irow) { > ~~~~~~~~~~~~~~~ > case 1477: case 1479: continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 1476: row = 984; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 1480: row = 985; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 1478: row = 985; box = 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if ((box < 12) && (box & 1)) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < 1533; col++, row ^= 1) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col != 1) RAW(row,col) = (col+1) & 2 ? > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pixel[col/2-1] + pixel[col/2+1] : pixel[col/2] << 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,1) = pixel[1] << 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,1533) = pixel[765] << 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else > ~~~~~~ > for (col=row & 1; col < 1534; col+=2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = pixel[col/2] << 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > maximum = 0xff << 1; > ~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS quicktake_100_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar pixel[484][644]; > ~~~~~~~~~~~~~~~~~~~~~~ > static const short gstep[16] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -89,-60,-44,-32,-22,-15,-8,-2,2,8,15,22,32,44,60,89 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > static const short rstep[6][4] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { { -3,-1,1,3 }, { -5,-1,1,5 }, { -8,-2,2,8 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -13,-3,3,13 }, { -19,-4,4,19 }, { -28,-6,6,28 } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > static const short curve[256] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,53, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,74,75,76,77,78, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 79,80,81,82,83,84,86,88,90,92,94,97,99,101,103,105,107,110,112,114,116, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 118,120,123,125,127,129,131,134,136,138,140,142,144,147,149,151,153,155, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 158,160,162,164,166,168,171,173,175,177,179,181,184,186,188,190,192,195, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 197,199,201,203,205,208,210,212,214,216,218,221,223,226,230,235,239,244, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 248,252,257,261,265,270,274,278,283,287,291,296,300,305,309,313,318,322, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 326,331,335,339,344,348,352,357,361,365,370,374,379,383,387,392,396,400, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 405,409,413,418,422,426,431,435,440,444,448,453,457,461,466,470,474,479, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 483,487,492,496,500,508,519,531,542,553,564,575,587,598,609,620,631,643, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 654,665,676,687,698,710,721,732,743,754,766,777,788,799,810,822,833,844, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 855,866,878,889,900,911,922,933,945,956,967,978,989,1001,1012,1023 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int rb, row, col, sharp, val=0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > getbits(-1); > ~~~~~~~~~~~~ > memset (pixel, 0x80, sizeof pixel); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=2; row < height+2; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=2+(row & 1); col < width+2; col+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > val = ((pixel[row-1][col-1] + 2*pixel[row-1][col+1] + > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pixel[row][col-2]) >> 2) + gstep[getbits(4)]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pixel[row][col] = val = LIM(val,0,255); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col < 4) > ~~~~~~~~~~~~ > pixel[row][col-2] = pixel[row+1][~row & 1] = val; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (row == 2) > ~~~~~~~~~~~~~ > pixel[row-1][col+1] = pixel[row-1][col+3] = val; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > pixel[row][col] = val; > ~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (rb=0; rb < 2; rb++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=2+rb; row < height+2; row+=2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=3-(row & 1); col < width+2; col+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (row < 4 || col < 4) sharp = 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else { > ~~~~~~ > val = ABS(pixel[row-2][col] - pixel[row][col-2]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > + ABS(pixel[row-2][col] - pixel[row-2][col-2]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > + ABS(pixel[row][col-2] - pixel[row-2][col-2]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sharp = val < 4 ? 0 : val < 8 ? 1 : val < 16 ? 2 : > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > val < 32 ? 3 : val < 48 ? 4 : 5; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > val = ((pixel[row-2][col] + pixel[row][col-2]) >> 1) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > + rstep[sharp][getbits(2)]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pixel[row][col] = val = LIM(val,0,255); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (row < 4) pixel[row-2][col+2] = val; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col < 4) pixel[row+2][col-2] = val; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (row=2; row < height+2; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=3-(row & 1); col < width+2; col+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > val = ((pixel[row][col-1] + (pixel[row][col] << 2) + > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pixel[row][col+1]) >> 1) - 0x100; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pixel[row][col] = LIM(val,0,255); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (row=0; row < height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = curve[pixel[row+2][col+2]]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > maximum = 0x3ff; > ~~~~~~~~~~~~~~~~ > } > ~ > > > #define radc_token(tree) ((signed char) getbithuff(8,huff[tree])) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > #define FORYX for (y=1; y < 3; y++) for (x=col+1; x >= col; x--) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > #define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > : (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > void CLASS kodak_radc_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const signed char src[] = { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 1,0, 2,2, 2,-2, > ~~~~~~~~~~~~~~~ > 1,-3, 1,3, > ~~~~~~~~~~ > 2,-17, 2,-5, 2,5, 2,17, > ~~~~~~~~~~~~~~~~~~~~~~~ > 2,-7, 2,2, 2,9, 2,18, > ~~~~~~~~~~~~~~~~~~~~~ > 2,-18, 2,-9, 2,-2, 2,7, > ~~~~~~~~~~~~~~~~~~~~~~~ > 2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 2,-1, 2,13, 2,26, 3,39, 4,-16, 5,55, 6,-37, 6,76, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 2,-26, 2,-13, 2,1, 3,-39, 4,16, 5,-55, 6,-76, 6,37 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > }; > ~~ > ushort huff[19][256]; > ~~~~~~~~~~~~~~~~~~~~~ > int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > short last[3] = { 16,16,16 }, mul[3], buf[3][3][386]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > static const ushort pt[] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,0, 1280,1344, 2320,3616, 3328,8000, 4095,16383, 65535,16383 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > for (i=2; i < 12; i+=2) > ~~~~~~~~~~~~~~~~~~~~~~~ > for (c=pt[i-2]; c <= pt[i]; c++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > curve[c] = (float) > ~~~~~~~~~~~~~~~~~~ > (c-pt[i-2]) / (pt[i]-pt[i-2]) * (pt[i+1]-pt[i-1]) + pt[i-1] + 0.5; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (s=i=0; i < sizeof src; i+=2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(256 >> src[i]) > ~~~~~~~~~~~~~~~~~~~ > ((ushort *)huff)[s++] = src[i] << 8 | (uchar) src[i+1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > s = kodak_cbpp == 243 ? 2 : 3; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(256) huff[18][c] = (8-s) << 8 | c >> s << s | 1 << (s-1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > getbits(-1); > ~~~~~~~~~~~~ > for (i=0; i < sizeof(buf)/sizeof(short); i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ((short *)buf)[i] = 2048; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < height; row+=4) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 mul[c] = getbits(6); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 { > ~~~~~~~ > val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > s = val > 65564 ? 10:12; > ~~~~~~~~~~~~~~~~~~~~~~~~ > x = ~(-1 << (s-1)); > ~~~~~~~~~~~~~~~~~~~ > val <<= 12-s; > ~~~~~~~~~~~~~ > for (i=0; i < sizeof(buf[0])/sizeof(short); i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ((short *)buf[c])[i] = (((short *)buf[c])[i] * val + x) >> s; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > last[c] = mul[c]; > ~~~~~~~~~~~~~~~~~ > for (r=0; r <= !c; r++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (tree=1, col=width/2; col > 0; ) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((tree = radc_token(tree))) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > col -= 2; > ~~~~~~~~~ > if (tree == 8) > ~~~~~~~~~~~~~~ > FORYX buf[c][y][x] = (uchar) radc_token(18) * mul[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else > ~~~~ > FORYX buf[c][y][x] = radc_token(tree+10) * 16 + PREDICTOR; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else > ~~~~~~ > do { > ~~~~ > nreps = (col > 2) ? radc_token(9) + 1 : 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (rep=0; rep < 8 && rep < nreps && col > 0; rep++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > col -= 2; > ~~~~~~~~~ > FORYX buf[c][y][x] = PREDICTOR; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (rep & 1) { > ~~~~~~~~~~~~~~ > step = radc_token(10) << 4; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORYX buf[c][y][x] += step; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } while (nreps == 9); > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (y=0; y < 2; y++) > ~~~~~~~~~~~~~~~~~~~~~ > for (x=0; x < width/2; x++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > val = (buf[c][y+1][x] << 4) / mul[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (val < 0) val = 0; > ~~~~~~~~~~~~~~~~~~~~~ > if (c) RAW(row+y*2+c-1,x*2+2-c) = val; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else RAW(row+r*2+y,x*2+y) = val; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > for (y=row; y < row+4; y++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (x=0; x < width; x++) > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((x+y) & 1) { > ~~~~~~~~~~~~~~~~ > r = x ? x-1 : x+1; > ~~~~~~~~~~~~~~~~~~ > s = x+1 < width ? x+1 : x-1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > val = (RAW(y,x)-2048)*2 + (RAW(y,r)+RAW(y,s))/2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (val < 0) val = 0; > ~~~~~~~~~~~~~~~~~~~~~ > RAW(y,x) = val; > ~~~~~~~~~~~~~~~ > } > ~ > } > ~ > for (i=0; i < height*width; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > raw_image[i] = curve[raw_image[i]]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > maximum = 0x3fff; > ~~~~~~~~~~~~~~~~~ > } > ~ > > > #undef FORYX > ~~~~~~~~~~~~ > #undef PREDICTOR > ~~~~~~~~~~~~~~~~ > > > #ifdef NO_JPEG > ~~~~~~~~~~~~~~ > void CLASS kodak_jpeg_load_raw() {} > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > void CLASS lossy_dng_load_raw() {} > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #else > ~~~~~ > > > METHODDEF(boolean) > ~~~~~~~~~~~~~~~~~~ > fill_input_buffer (j_decompress_ptr cinfo) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > /*RT static uchar jpeg_buffer[4096]; */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > size_t nbytes; > ~~~~~~~~~~~~~~ > > > nbytes = fread (jpeg_buffer, 1, 4096, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > swab ((char*)jpeg_buffer, (char*)jpeg_buffer, nbytes); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cinfo->src->next_input_byte = jpeg_buffer; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cinfo->src->bytes_in_buffer = nbytes; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return TRUE; > ~~~~~~~~~~~~ > } > ~ > > > void CLASS kodak_jpeg_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > struct jpeg_decompress_struct cinfo; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > struct jpeg_error_mgr jerr; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > JSAMPARRAY buf; > ~~~~~~~~~~~~~~~ > JSAMPLE (*pixel)[3]; > ~~~~~~~~~~~~~~~~~~~~ > int row, col; > ~~~~~~~~~~~~~ > > > cinfo.err = jpeg_std_error (&jerr); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jpeg_create_decompress (&cinfo); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jpeg_stdio_src (&cinfo, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cinfo.src->fill_input_buffer = fill_input_buffer; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jpeg_read_header (&cinfo, TRUE); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jpeg_start_decompress (&cinfo); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((cinfo.output_width != width ) || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (cinfo.output_height*2 != height ) || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (cinfo.output_components != 3 )) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fprintf (stderr,_("%s: incorrect JPEG dimensions\n"), ifname); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jpeg_destroy_decompress (&cinfo); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > longjmp (failure, 3); > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > buf = (*cinfo.mem->alloc_sarray) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > while (cinfo.output_scanline < cinfo.output_height) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row = cinfo.output_scanline * 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jpeg_read_scanlines (&cinfo, buf, 1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pixel = (JSAMPLE (*)[3]) buf[0]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row+0,col+0) = pixel[col+0][1] << 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row+1,col+1) = pixel[col+1][1] << 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row+0,col+1) = pixel[col][0] + pixel[col+1][0]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row+1,col+0) = pixel[col][2] + pixel[col+1][2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > jpeg_finish_decompress (&cinfo); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jpeg_destroy_decompress (&cinfo); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > maximum = 0xff << 1; > ~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS gamma_curve (double pwr, double ts, int mode, int imax); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > void CLASS lossy_dng_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > struct jpeg_decompress_struct cinfo; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > struct jpeg_error_mgr jerr; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > JSAMPARRAY buf; > ~~~~~~~~~~~~~~~ > JSAMPLE (*pixel)[3]; > ~~~~~~~~~~~~~~~~~~~~ > unsigned sorder=order, ntags, opcode, deg, i, j, c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unsigned save=data_offset-4, trow=0, tcol=0, row, col; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort cur[3][256]; > ~~~~~~~~~~~~~~~~~~~ > double coeff[9], tot; > ~~~~~~~~~~~~~~~~~~~~~ > > > if (meta_offset) { > ~~~~~~~~~~~~~~~~~~ > fseek (ifp, meta_offset, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > order = 0x4d4d; > ~~~~~~~~~~~~~~~ > ntags = get4(); > ~~~~~~~~~~~~~~~ > while (ntags--) { > ~~~~~~~~~~~~~~~~~ > opcode = get4(); get4(); get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (opcode != 8) > ~~~~~~~~~~~~~~~~ > { fseek (ifp, get4(), SEEK_CUR); continue; } > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 20, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((c = get4()) > 2) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 12, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((deg = get4()) > 8) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i <= deg && i < 9; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > coeff[i] = getreal(12); > ~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 256; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (tot=j=0; j <= deg; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tot += coeff[j] * pow(i/255.0, j); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cur[c][i] = tot*0xffff; > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > order = sorder; > ~~~~~~~~~~~~~~~ > } else { > ~~~~~~~~ > gamma_curve (1/2.4, 12.92, 1, 255); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 memcpy (cur[c], curve, sizeof cur[0]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > cinfo.err = jpeg_std_error (&jerr); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jpeg_create_decompress (&cinfo); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (trow < raw_height) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, save+=4, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tile_length < INT_MAX) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, get4(), SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jpeg_stdio_src (&cinfo, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jpeg_read_header (&cinfo, TRUE); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jpeg_start_decompress (&cinfo); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > buf = (*cinfo.mem->alloc_sarray) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ((j_common_ptr) &cinfo, JPOOL_IMAGE, cinfo.output_width*3, 1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (cinfo.output_scanline < cinfo.output_height && > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (row = trow + cinfo.output_scanline) < height) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jpeg_read_scanlines (&cinfo, buf, 1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pixel = (JSAMPLE (*)[3]) buf[0]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < cinfo.output_width && tcol+col < width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 image[row*width+tcol+col][c] = cur[c][pixel[col][c]]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > jpeg_abort_decompress (&cinfo); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((tcol += tile_width) >= raw_width) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > trow += tile_length + (tcol = 0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > jpeg_destroy_decompress (&cinfo); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > maximum = 0xffff; > ~~~~~~~~~~~~~~~~~ > } > ~ > #endif > ~~~~~~ > > > void CLASS kodak_dc120_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const int mul[4] = { 162, 192, 187, 92 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > static const int add[4] = { 0, 636, 424, 212 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > uchar pixel[848]; > ~~~~~~~~~~~~~~~~~ > int row, shift, col; > ~~~~~~~~~~~~~~~~~~~~ > > > for (row=0; row < height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (fread (pixel, 1, 848, ifp) < 848) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > shift = row * mul[row & 3] + add[row & 3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = (ushort) pixel[(col + shift) % 848]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > maximum = 0xff; > ~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS eight_bit_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar *pixel; > ~~~~~~~~~~~~~ > unsigned row, col; > ~~~~~~~~~~~~~~~~~~ > > > pixel = (uchar *) calloc (raw_width, sizeof *pixel); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (pixel, "eight_bit_load_raw()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (fread (pixel, 1, raw_width, ifp) < raw_width) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = curve[pixel[col]]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > free (pixel); > ~~~~~~~~~~~~~ > maximum = curve[0xff]; > ~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS kodak_c330_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar *pixel; > ~~~~~~~~~~~~~ > int row, col, y, cb, cr, rgb[3], c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > pixel = (uchar *) calloc (raw_width, 2*sizeof *pixel); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (pixel, "kodak_c330_load_raw()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (fread (pixel, raw_width, 2, ifp) < 2) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (load_flags && (row & 31) == 31) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, raw_width*32, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > y = pixel[col*2]; > ~~~~~~~~~~~~~~~~~~ > cb = pixel[(col*2 & -4) | 1] - 128; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cr = pixel[(col*2 & -4) | 3] - 128; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > rgb[1] = y - ((cb + cr + 2) >> 2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > rgb[2] = rgb[1] + cb; > ~~~~~~~~~~~~~~~~~~~~~ > rgb[0] = rgb[1] + cr; > ~~~~~~~~~~~~~~~~~~~~~ > FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > free (pixel); > ~~~~~~~~~~~~~ > maximum = curve[0xff]; > ~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS kodak_c603_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar *pixel; > ~~~~~~~~~~~~~ > int row, col, y, cb, cr, rgb[3], c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > pixel = (uchar *) calloc (raw_width, 3*sizeof *pixel); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (pixel, "kodak_c603_load_raw()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (~row & 1) > ~~~~~~~~~~~~~ > if (fread (pixel, raw_width, 3, ifp) < 3) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > y = pixel[width*2*(row & 1) + col]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cb = pixel[width + (col & -2)] - 128; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cr = pixel[width + (col & -2)+1] - 128; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > rgb[1] = y - ((cb + cr + 2) >> 2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > rgb[2] = rgb[1] + cb; > ~~~~~~~~~~~~~~~~~~~~~ > rgb[0] = rgb[1] + cr; > ~~~~~~~~~~~~~~~~~~~~~ > FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > free (pixel); > ~~~~~~~~~~~~~ > maximum = curve[0xff]; > ~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS kodak_262_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const uchar kodak_tree[2][26] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { { 0,1,5,1,1,2,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0,3,1,1,1,1,1,2,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9 } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort *huff[2]; > ~~~~~~~~~~~~~~~~ > uchar *pixel; > ~~~~~~~~~~~~~ > int *strip, ns, c, row, col, chess, pi=0, pi1, pi2, pred, val; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > FORC(2) huff[c] = make_decoder (kodak_tree[c]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ns = (raw_height+63) >> 5; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > pixel = (uchar *) malloc (raw_width*32 + ns*4); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (pixel, "kodak_262_load_raw()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > strip = (int *) (pixel + raw_width*32); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > order = 0x4d4d; > ~~~~~~~~~~~~~~~ > FORC(ns) strip[c] = get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((row & 31) == 0) { > ~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, strip[row >> 5], SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > getbits(-1); > ~~~~~~~~~~~~ > pi = 0; > ~~~~~~~ > } > ~ > for (col=0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > chess = (row + col) & 1; > ~~~~~~~~~~~~~~~~~~~~~~~~ > pi1 = chess ? pi-2 : pi-raw_width-1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pi2 = chess ? pi-2*raw_width : pi-raw_width+1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col <= chess) pi1 = -1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (pi1 < 0) pi1 = pi2; > ~~~~~~~~~~~~~~~~~~~~~~~ > if (pi2 < 0) pi2 = pi1; > ~~~~~~~~~~~~~~~~~~~~~~~ > if (pi1 < 0 && col > 1) pi1 = pi2 = pi-2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pixel[pi] = val = pred + ljpeg_diff (huff[chess]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (val >> 8) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~ > val = curve[pixel[pi++]]; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = val; > ~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > free (pixel); > ~~~~~~~~~~~~~ > FORC(2) free (huff[c]); > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > int CLASS kodak_65000_decode (short *out, int bsize) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar c, blen[768]; > ~~~~~~~~~~~~~~~~~~~ > ushort raw[6]; > ~~~~~~~~~~~~~~ > INT64 bitbuf=0; > ~~~~~~~~~~~~~~~ > int save, bits=0, i, j, len, diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > save = ftell(ifp); > ~~~~~~~~~~~~~~~~~~ > bsize = (bsize + 3) & -4; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < bsize; i+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > c = fgetc(ifp); > ~~~~~~~~~~~~~~~ > if ((blen[i ] = c & 15) > 12 || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (blen[i+1] = c >> 4) > 12 ) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, save, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < bsize; i+=8) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > read_shorts (raw, 6); > ~~~~~~~~~~~~~~~~~~~~~ > out[i ] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > out[i+1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 6; j++) > ~~~~~~~~~~~~~~~~~~~~~ > out[i+2+j] = raw[j] & 0xfff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > return 1; > ~~~~~~~~~ > } > ~ > } > ~ > if ((bsize & 7) == 4) { > ~~~~~~~~~~~~~~~~~~~~~~~ > bitbuf = fgetc(ifp) << 8; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > bitbuf += fgetc(ifp); > ~~~~~~~~~~~~~~~~~~~~~ > bits = 16; > ~~~~~~~~~~ > } > ~ > for (i=0; i < bsize; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > len = blen[i]; > ~~~~~~~~~~~~~~ > if (bits < len) { > ~~~~~~~~~~~~~~~~~ > for (j=0; j < 32; j+=8) > ~~~~~~~~~~~~~~~~~~~~~~~ > bitbuf += (INT64) fgetc(ifp) << (bits+(j^8)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > bits += 32; > ~~~~~~~~~~~ > } > ~ > diff = bitbuf & (0xffff >> (16-len)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > bitbuf >>= len; > ~~~~~~~~~~~~~~~ > bits -= len; > ~~~~~~~~~~~~ > if ((diff & (1 << (len-1))) == 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff -= (1 << len) - 1; > ~~~~~~~~~~~~~~~~~~~~~~~ > out[i] = diff; > ~~~~~~~~~~~~~~ > } > ~ > return 0; > ~~~~~~~~~ > } > ~ > > > void CLASS kodak_65000_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > short buf[256]; > ~~~~~~~~~~~~~~~ > int row, col, len, pred[2], ret, i; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > for (row=0; row < height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col+=256) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pred[0] = pred[1] = 0; > ~~~~~~~~~~~~~~~~~~~~~~ > len = MIN (256, width-col); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ret = kodak_65000_decode (buf, len); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < len; i++) > ~~~~~~~~~~~~~~~~~~~~~~~ > if ((RAW(row,col+i) = curve[ret ? buf[i] : > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (pred[i & 1] += buf[i])]) >> 12) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS kodak_ycbcr_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > short buf[384], *bp; > ~~~~~~~~~~~~~~~~~~~~ > int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort *ip; > ~~~~~~~~~~~ > > > if (!image) return; > ~~~~~~~~~~~~~~~~~~~ > for (row=0; row < height; row+=2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col+=128) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > len = MIN (128, width-col); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > kodak_65000_decode (buf, len*3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > y[0][1] = y[1][1] = cb = cr = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (bp=buf, i=0; i < len; i+=2, bp+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cb += bp[4]; > ~~~~~~~~~~~~ > cr += bp[5]; > ~~~~~~~~~~~~ > rgb[1] = -((cb + cr + 2) >> 2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > rgb[2] = rgb[1] + cb; > ~~~~~~~~~~~~~~~~~~~~~ > rgb[0] = rgb[1] + cr; > ~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 2; j++) > ~~~~~~~~~~~~~~~~~~~~~ > for (k=0; k < 2; k++) { > ~~~~~~~~~~~~~~~~~~~~~~~ > if ((y[j][k] = y[j][k^1] + *bp++) >> 10) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ip = image[(row+j)*width + col+i+k]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > } > ~ > > > void CLASS kodak_rgb_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > short buf[768], *bp; > ~~~~~~~~~~~~~~~~~~~~ > int row, col, len, c, i, rgb[3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort *ip=image[0]; > ~~~~~~~~~~~~~~~~~~~~ > > > for (row=0; row < height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col+=256) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > len = MIN (256, width-col); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > kodak_65000_decode (buf, len*3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memset (rgb, 0, sizeof rgb); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (bp=buf, i=0; i < len; i++, ip+=4) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 if ((ip[c] = rgb[c] += *bp++) >> 12) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS kodak_thumb_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int row, col; > ~~~~~~~~~~~~~ > colors = thumb_misc >> 5; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > read_shorts (image[row*width+col], colors); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > maximum = (1 << (thumb_misc & 31)) - 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS sony_decrypt_t::operator()(unsigned *data, int len, int start, int key) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > /*RT static unsigned pad[128], p;*/ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (start) { > ~~~~~~~~~~~~ > for (p=0; p < 4; p++) > ~~~~~~~~~~~~~~~~~~~~~ > pad[p] = key = key * 48828125 + 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (p=4; p < 127; p++) > ~~~~~~~~~~~~~~~~~~~~~~~ > pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (p=0; p < 127; p++) > ~~~~~~~~~~~~~~~~~~~~~~~ > pad[p] = htonl(pad[p]); > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > while (len-- && p++) > ~~~~~~~~~~~~~~~~~~~~ > *data++ ^= pad[(p-1) & 127] = pad[p & 127] ^ pad[(p+64) & 127]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS sony_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar head[40]; > ~~~~~~~~~~~~~~~ > ushort *pixel; > ~~~~~~~~~~~~~~ > unsigned i, key, row, col; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > fseek (ifp, 200896, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > order = 0x4d4d; > ~~~~~~~~~~~~~~~ > key = get4(); > ~~~~~~~~~~~~~ > fseek (ifp, 164600, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (head, 1, 40, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > sony_decrypt ((unsigned *) head, 10, 1, key); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=26; i-- > 22; ) > ~~~~~~~~~~~~~~~~~~~~~~ > key = key << 8 | head[i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, data_offset, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pixel = raw_image + row*raw_width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (fread (pixel, 2, raw_width, ifp) < raw_width) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sony_decrypt ((unsigned *) pixel, raw_width/2, !row, key); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((pixel[col] = ntohs(pixel[col])) >> 14) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > maximum = 0x3ff0; > ~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS sony_arw_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > ushort huff[32770]; > ~~~~~~~~~~~~~~~~~~~ > static const ushort tab[18] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0xf11,0xf10,0xe0f,0xd0e,0xc0d,0xb0c,0xa0b,0x90a,0x809, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x708,0x607,0x506,0x405,0x304,0x303,0x300,0x202,0x201 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int i, c, n, col, row, sum=0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > huff[0] = 15; > ~~~~~~~~~~~~~ > for (n=i=0; i < 18; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(32768 >> (tab[i] >> 8)) huff[++n] = tab[i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > getbits(-1); > ~~~~~~~~~~~~ > for (col = raw_width; col--; ) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height+1; row+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (row == raw_height) row = 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((sum += ljpeg_diff(huff)) >> 12) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (row < height) RAW(row,col) = sum; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS sony_arw2_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar *data, *dp; > ~~~~~~~~~~~~~~~~~ > ushort pix[16]; > ~~~~~~~~~~~~~~~ > int row, col, val, max, min, imax, imin, sh, bit, i; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > data = (uchar *) malloc (raw_width+1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (data, "sony_arw2_load_raw()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (data, 1, raw_width, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (dp=data, col=0; col < raw_width-30; dp+=16) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > max = 0x7ff & (val = sget4(dp)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > min = 0x7ff & val >> 11; > ~~~~~~~~~~~~~~~~~~~~~~~~ > imax = 0x0f & val >> 22; > ~~~~~~~~~~~~~~~~~~~~~~~~ > imin = 0x0f & val >> 26; > ~~~~~~~~~~~~~~~~~~~~~~~~ > for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (bit=30, i=0; i < 16; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (i == imax) pix[i] = max; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else if (i == imin) pix[i] = min; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else { > ~~~~~~ > pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (pix[i] > 0x7ff) pix[i] = 0x7ff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > bit += 7; > ~~~~~~~~~ > } > ~ > for (i=0; i < 16; i++, col+=2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = curve[pix[i] << 1]; // >> 2; RT: disabled shifting to avoid precision loss > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > col -= col & 1 ? 1:31; > ~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > free (data); > ~~~~~~~~~~~~ > maximum = curve[0x7ff << 1]; // RT: fix maximum. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > maximum = 16300; // RT: conservative white level tested on various ARW2 cameras. This constant was set in 2013-12-17, may need re-evaluation in the future. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS samsung_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int row, col, c, i, dir, op[4], len[4]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > order = 0x4949; > ~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, strip_offset+row*4, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, data_offset+get4(), SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ph1_bits(-1); > ~~~~~~~~~~~~~ > FORC4 len[c] = row < 2 ? 7:4; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width; col+=16) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > dir = ph1_bits(1); > ~~~~~~~~~~~~~~~~~~ > FORC4 op[c] = ph1_bits(2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 switch (op[c]) { > ~~~~~~~~~~~~~~~~~~~~~~ > case 3: len[c] = ph1_bits(4); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 2: len[c]--; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > case 1: len[c]++; > ~~~~~~~~~~~~~~~~~ > } > ~ > for (c=0; c < 16; c+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~ > i = len[((c & 1) << 1) | (c >> 3)]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col+c) = ((signed) ph1_bits(i) << (32-i) >> (32-i)) + > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (dir ? RAW(row+(~c | -2),col+c) : col ? RAW(row,col+(c | -2)) : 128); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (c == 14) c = -1; > ~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > for (row=0; row < raw_height-1; row+=2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width-1; col+=2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > SWAP (RAW(row,col+1), RAW(row+1,col)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS samsung2_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const ushort tab[14] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0x304,0x307,0x206,0x205,0x403,0x600,0x709, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x80a,0x90b,0xa0c,0xa0d,0x501,0x408,0x402 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort huff[1026], vpred[2][2] = {{0,0},{0,0}}, hpred[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int i, c, n, row, col, diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > huff[0] = 10; > ~~~~~~~~~~~~~ > for (n=i=0; i < 14; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > FORC(1024 >> (tab[i] >> 8)) huff[++n] = tab[i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > getbits(-1); > ~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < raw_width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff = ljpeg_diff (huff); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col < 2) hpred[col] = vpred[row & 1][col] += diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else hpred[col & 1] += diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = hpred[col & 1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (hpred[col & 1] >> tiff_bps) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS samsung3_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int opt, init, mag, pmode, row, tab, col, pred, diff, i, c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort lent[3][2], len[4], *prow[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > order = 0x4949; > ~~~~~~~~~~~~~~~ > fseek (ifp, 9, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > opt = fgetc(ifp); > ~~~~~~~~~~~~~~~~~ > init = (get2(),get2()); > ~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, (data_offset-ftell(ifp)) & 15, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ph1_bits(-1); > ~~~~~~~~~~~~~ > mag = 0; pmode = 7; > ~~~~~~~~~~~~~~~~~~~ > FORC(6) ((ushort *)lent)[c] = row < 2 ? 7:4; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > prow[ row & 1] = &RAW(row-1,1-((row & 1) << 1)); // green > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > prow[~row & 1] = &RAW(row-2,0); // red and blue > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (tab=0; tab+15 < raw_width; tab+=16) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (~opt & 4 && !(tab & 63)) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = ph1_bits(2); > ~~~~~~~~~~~~~~~~ > mag = i < 3 ? mag-'2'+"204"[i] : ph1_bits(12); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (opt & 2) > ~~~~~~~~~~~~ > pmode = 7 - 4*ph1_bits(1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > else if (!ph1_bits(1)) > ~~~~~~~~~~~~~~~~~~~~~~ > pmode = ph1_bits(3); > ~~~~~~~~~~~~~~~~~~~~ > if (opt & 1 || !ph1_bits(1)) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 len[c] = ph1_bits(2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 { > ~~~~~~~ > i = ((row & 1) << 1 | (c & 1)) % 3; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > len[c] = len[c] < 3 ? lent[i][0]-'1'+"120"[len[c]] : ph1_bits(4); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > lent[i][0] = lent[i][1]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > lent[i][1] = len[c]; > ~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > FORC(16) { > ~~~~~~~~~~ > col = tab + (((c & 7) << 1)^(c >> 3)^(row & 1)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pred = (pmode == 7 || row < 2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ? (tab ? RAW(row,tab-2+(col & 1)) : init) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > : (prow[col & 1][col-'4'+"0224468"[pmode]] + > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > prow[col & 1][col-'4'+"0244668"[pmode]] + 1) >> 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff = ph1_bits (i = len[c >> 2]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (diff >> (i-1)) diff -= 1 << i; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff = diff * (mag*2+1) + mag; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = pred + diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > } > ~ > > > #define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > /* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > void CLASS smal_decode_segment (unsigned seg[2][2], int holes) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > uchar hist[3][13] = { > ~~~~~~~~~~~~~~~~~~~~~ > { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 3, 3, 0, 0, 63, 47, 31, 15, 0 } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int low, high=0xff, carry=0, nbits=8; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int pix, s, count, bin, next, i, sym[3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > uchar diff, pred[]={0,0}; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort data=0, range=0; > ~~~~~~~~~~~~~~~~~~~~~~~ > > > fseek (ifp, seg[0][1]+1, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > getbits(-1); > ~~~~~~~~~~~~ > if (seg[1][0] > raw_width*raw_height) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > seg[1][0] = raw_width*raw_height; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (pix=seg[0][0]; pix < seg[1][0]; pix++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (s=0; s < 3; s++) { > ~~~~~~~~~~~~~~~~~~~~~~~ > data = data << nbits | getbits(nbits); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (carry < 0) > ~~~~~~~~~~~~~~ > carry = (nbits += carry+1) < 1 ? nbits-1 : 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (--nbits >= 0) > ~~~~~~~~~~~~~~~~~~~~ > if ((data >> nbits & 0xff) == 0xff) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (nbits > 0) > ~~~~~~~~~~~~~~ > data = ((data & ((1 << (nbits-1)) - 1)) << 1) | > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ((data + (((data & (1 << (nbits-1)))) << 1)) & (-1 << nbits)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (nbits >= 0) { > ~~~~~~~~~~~~~~~~~ > data += getbits(1); > ~~~~~~~~~~~~~~~~~~~ > carry = nbits - 8; > ~~~~~~~~~~~~~~~~~~ > } > ~ > count = ((((data-range+1) & 0xffff) << 2) - 1) / (high >> 4); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (bin=0; hist[s][bin+5] > count; bin++); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > low = hist[s][bin+5] * (high >> 4) >> 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (bin) high = hist[s][bin+4] * (high >> 4) >> 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > high -= low; > ~~~~~~~~~~~~ > for (nbits=0; high << nbits < 128; nbits++); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > range = (range+low) << nbits; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > high <<= nbits; > ~~~~~~~~~~~~~~~ > next = hist[s][1]; > ~~~~~~~~~~~~~~~~~~ > if (++hist[s][2] > hist[s][3]) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > next = (next+1) & hist[s][0]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > hist[s][3] = (hist[s][next+4] - hist[s][next+5]) >> 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > hist[s][2] = 1; > ~~~~~~~~~~~~~~~ > } > ~ > if (hist[s][hist[s][1]+4] - hist[s][hist[s][1]+5] > 1) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (bin < hist[s][1]) > ~~~~~~~~~~~~~~~~~~~~~ > for (i=bin; i < hist[s][1]; i++) hist[s][i+5]--; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else if (next <= bin) > ~~~~~~~~~~~~~~~~~~~~~ > for (i=hist[s][1]; i < bin; i++) hist[s][i+5]++; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > hist[s][1] = next; > ~~~~~~~~~~~~~~~~~~ > sym[s] = bin; > ~~~~~~~~~~~~~ > } > ~ > diff = sym[2] << 5 | sym[1] << 2 | (sym[0] & 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (sym[0] & 4) > ~~~~~~~~~~~~~~~ > diff = diff ? -diff : 0x80; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ftell(ifp) + 12 >= seg[1][1]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff = 0; > ~~~~~~~~~ > if(pix>=raw_width*raw_height) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > derror(); > ~~~~~~~~~ > else > ~~~~ > raw_image[pix] = pred[pix & 1] += diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!(pix & 1) && HOLE(pix / raw_width)) pix += 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > maximum = 0xff; > ~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS smal_v6_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned seg[2][2]; > ~~~~~~~~~~~~~~~~~~~ > > > fseek (ifp, 16, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > seg[0][0] = 0; > ~~~~~~~~~~~~~~ > seg[0][1] = get2(); > ~~~~~~~~~~~~~~~~~~~ > seg[1][0] = raw_width * raw_height; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > seg[1][1] = INT_MAX; > ~~~~~~~~~~~~~~~~~~~~ > smal_decode_segment (seg, 0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > int CLASS median4 (int *p) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int min, max, sum, i; > ~~~~~~~~~~~~~~~~~~~~~ > > > min = max = sum = p[0]; > ~~~~~~~~~~~~~~~~~~~~~~~ > for (i=1; i < 4; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~ > sum += p[i]; > ~~~~~~~~~~~~ > if (min > p[i]) min = p[i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (max < p[i]) max = p[i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > return (sum - min - max) >> 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS fill_holes (int holes) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int row, col, val[4]; > ~~~~~~~~~~~~~~~~~~~~~ > > > for (row=2; row < height-2; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!HOLE(row)) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=1; col < width-1; col+=4) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > val[0] = RAW(row-1,col-1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > val[1] = RAW(row-1,col+1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > val[2] = RAW(row+1,col-1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > val[3] = RAW(row+1,col+1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = median4(val); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (col=2; col < width-2; col+=4) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (HOLE(row-2) || HOLE(row+2)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = (RAW(row,col-2) + RAW(row,col+2)) >> 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else { > ~~~~~~ > val[0] = RAW(row,col-2); > ~~~~~~~~~~~~~~~~~~~~~~~~ > val[1] = RAW(row,col+2); > ~~~~~~~~~~~~~~~~~~~~~~~~ > val[2] = RAW(row-2,col); > ~~~~~~~~~~~~~~~~~~~~~~~~ > val[3] = RAW(row+2,col); > ~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = median4(val); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > > > void CLASS smal_v9_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned seg[256][2], offset, nseg, holes, i; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > fseek (ifp, 67, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > offset = get4(); > ~~~~~~~~~~~~~~~~ > nseg = (uchar) fgetc(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, offset, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < nseg*2; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > ((unsigned *)seg)[i] = get4() + data_offset*(i & 1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 78, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > holes = fgetc(ifp); > ~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 88, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > seg[nseg][0] = raw_height * raw_width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > seg[nseg][1] = get4() + data_offset; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < nseg; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > smal_decode_segment (seg+i, holes); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (holes) fill_holes (holes); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS redcine_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > #ifndef NO_JASPER > ~~~~~~~~~~~~~~~~~ > int c, row, col; > ~~~~~~~~~~~~~~~~ > jas_stream_t *in; > ~~~~~~~~~~~~~~~~~ > jas_image_t *jimg; > ~~~~~~~~~~~~~~~~~~ > jas_matrix_t *jmat; > ~~~~~~~~~~~~~~~~~~~ > jas_seqent_t *data; > ~~~~~~~~~~~~~~~~~~~ > ushort *img, *pix; > ~~~~~~~~~~~~~~~~~~ > > > jas_init(); > ~~~~~~~~~~~ > in = jas_stream_fopen (ifname, "rb"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jas_stream_seek (in, data_offset+20, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jimg = jas_image_decode (in, -1, 0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!jimg) longjmp (failure, 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > jmat = jas_matrix_create (height/2, width/2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (jmat, "redcine_load_raw()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > img = (ushort *) calloc ((height+2), (width+2)*2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (img, "redcine_load_raw()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 { > ~~~~~~~ > jas_image_readcmpt (jimg, c, 0, 0, width/2, height/2, jmat); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > data = jas_matrix_getref (jmat, 0, 0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row = c >> 1; row < height; row+=2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col = c & 1; col < width; col+=2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > img[(row+1)*(width+2)+col+1] = data[(row/2)*(width/2)+col/2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (col=1; col <= width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > img[col] = img[2*(width+2)+col]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > img[(height+1)*(width+2)+col] = img[(height-1)*(width+2)+col]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (row=0; row < height+2; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > img[row*(width+2)] = img[row*(width+2)+2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > img[(row+1)*(width+2)-1] = img[(row+1)*(width+2)-3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (row=1; row <= height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix = img + row*(width+2) + (col = 1 + (FC(row,1) & 1)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for ( ; col <= width; col+=2, pix+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > c = (((pix[0] - 0x800) << 3) + > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[-(width+2)] + pix[width+2] + pix[-1] + pix[1]) >> 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[0] = LIM(c,0,4095); > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > for (row=0; row < height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > RAW(row,col) = curve[img[(row+1)*(width+2)+col+1]]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > free (img); > ~~~~~~~~~~~ > jas_matrix_destroy (jmat); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > jas_image_destroy (jimg); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > jas_stream_close (in); > ~~~~~~~~~~~~~~~~~~~~~~ > #endif > ~~~~~~ > } > ~ > > > /* RESTRICTED code starts here */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > void CLASS foveon_decoder (unsigned size, unsigned code) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > /*RT static unsigned huff[1024];*/ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > struct decode *cur; > ~~~~~~~~~~~~~~~~~~~ > int i, len; > ~~~~~~~~~~~ > > > if (!code) { > ~~~~~~~~~~~~ > for (i=0; i < size; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > huff[i] = get4(); > ~~~~~~~~~~~~~~~~~ > memset (first_decode, 0, sizeof first_decode); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > free_decode = first_decode; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > cur = free_decode++; > ~~~~~~~~~~~~~~~~~~~~ > if (free_decode > first_decode+2048) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fprintf (stderr,_("%s: decoder table overflow\n"), ifname); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > longjmp (failure, 2); > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (code) > ~~~~~~~~~ > for (i=0; i < size; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (huff[i] == code) { > ~~~~~~~~~~~~~~~~~~~~~~ > cur->leaf = i; > ~~~~~~~~~~~~~~ > return; > ~~~~~~~ > } > ~ > if ((len = code >> 27) > 26) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > code = (len+1) << 27 | (code & 0x3ffffff) << 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > cur->branch[0] = free_decode; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > foveon_decoder (size, code); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cur->branch[1] = free_decode; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > foveon_decoder (size, code+1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS foveon_thumb() > ~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned bwide, row, col, bitbuf=0, bit=1, c, i; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > char *buf; > ~~~~~~~~~~ > struct decode *dindex; > ~~~~~~~~~~~~~~~~~~~~~~ > short pred[3]; > ~~~~~~~~~~~~~~ > > > bwide = get4(); > ~~~~~~~~~~~~~~~ > fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (bwide > 0) { > ~~~~~~~~~~~~~~~~ > if (bwide < thumb_width*3) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > buf = (char *) malloc (bwide); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (buf, "foveon_thumb()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < thumb_height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (buf, 1, bwide, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fwrite (buf, 3, thumb_width, ofp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > free (buf); > ~~~~~~~~~~~ > return; > ~~~~~~~ > } > ~ > foveon_decoder (256, 0); > ~~~~~~~~~~~~~~~~~~~~~~~~ > > > for (row=0; row < thumb_height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memset (pred, 0, sizeof pred); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!bit) get4(); > ~~~~~~~~~~~~~~~~~ > for (bit=col=0; col < thumb_width; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 { > ~~~~~~~ > for (dindex=first_decode; dindex->branch[0]; ) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((bit = (bit-1) & 31) == 31) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 4; i++) > ~~~~~~~~~~~~~~~~~~~~~ > bitbuf = (bitbuf << 8) + fgetc(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > dindex = dindex->branch[bitbuf >> bit & 1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > pred[c] += dindex->leaf; > ~~~~~~~~~~~~~~~~~~~~~~~~ > fputc (pred[c], ofp); > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > > > void CLASS foveon_sd_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > struct decode *dindex; > ~~~~~~~~~~~~~~~~~~~~~~ > short diff[1024]; > ~~~~~~~~~~~~~~~~~ > unsigned bitbuf=0; > ~~~~~~~~~~~~~~~~~~ > int pred[3], row, col, bit=-1, c, i; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > read_shorts ((ushort *) diff, 1024); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!load_flags) foveon_decoder (1024, 0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > for (row=0; row < height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memset (pred, 0, sizeof pred); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!bit && !load_flags && atoi(model+2) < 14) get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=bit=0; col < width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (load_flags) { > ~~~~~~~~~~~~~~~~~ > bitbuf = get4(); > ~~~~~~~~~~~~~~~~ > FORC3 pred[2-c] += diff[bitbuf >> c*10 & 0x3ff]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > else FORC3 { > ~~~~~~~~~~~~ > for (dindex=first_decode; dindex->branch[0]; ) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((bit = (bit-1) & 31) == 31) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 4; i++) > ~~~~~~~~~~~~~~~~~~~~~ > bitbuf = (bitbuf << 8) + fgetc(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > dindex = dindex->branch[bitbuf >> bit & 1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > pred[c] += diff[dindex->leaf]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (pred[c] >> 16 && ~pred[c] >> 16) derror(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > FORC3 image[row*width+col][c] = pred[c] < 0 ? 0 : pred[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > > > void CLASS foveon_huff (ushort *huff) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int i, j, clen, code; > ~~~~~~~~~~~~~~~~~~~~~ > > > huff[0] = 8; > ~~~~~~~~~~~~ > for (i=0; i < 13; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~ > clen = getc(ifp); > ~~~~~~~~~~~~~~~~~ > code = getc(ifp); > ~~~~~~~~~~~~~~~~~ > for (j=0; j < 256 >> clen; ) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > huff[code+ ++j] = clen << 8 | i; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > get2(); > ~~~~~~~ > } > ~ > > > void CLASS foveon_dp_load_raw() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned c, roff[4], row, col, diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort huff[512], vpred[2][2], hpred[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > fseek (ifp, 8, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > foveon_huff (huff); > ~~~~~~~~~~~~~~~~~~~ > roff[0] = 48; > ~~~~~~~~~~~~~ > FORC3 roff[c+1] = -(-(roff[c] + get4()) & -16); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 { > ~~~~~~~ > fseek (ifp, data_offset+roff[c], SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > getbits(-1); > ~~~~~~~~~~~~ > vpred[0][0] = vpred[0][1] = vpred[1][0] = vpred[1][1] = 512; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff = ljpeg_diff(huff); > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (col < 2) hpred[col] = vpred[row & 1][col] += diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else hpred[col & 1] += diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > image[row*width+col][c] = hpred[col & 1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > } > ~ > > > void CLASS foveon_load_camf() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned type, wide, high, i, j, row, col, diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort huff[258], vpred[2][2] = {{512,512},{512,512}}, hpred[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > fseek (ifp, meta_offset, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > type = get4(); get4(); get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > wide = get4(); > ~~~~~~~~~~~~~~ > high = get4(); > ~~~~~~~~~~~~~~ > if (type == 2) { > ~~~~~~~~~~~~~~~~ > fread (meta_data, 1, meta_length, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < meta_length; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > high = (high * 1597 + 51749) % 244944; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > wide = high * (INT64) 301593171 >> 24; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > meta_data[i] ^= ((((high << 8) - wide) >> 1) + wide) >> 17; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } else if (type == 4) { > ~~~~~~~~~~~~~~~~~~~~~~~ > free (meta_data); > ~~~~~~~~~~~~~~~~~ > meta_data = (char *) malloc (meta_length = wide*high*3/2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (meta_data, "foveon_load_camf()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > foveon_huff (huff); > ~~~~~~~~~~~~~~~~~~~ > get4(); > ~~~~~~~ > getbits(-1); > ~~~~~~~~~~~~ > for (j=row=0; row < high; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < wide; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > diff = ljpeg_diff(huff); > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (col < 2) hpred[col] = vpred[row & 1][col] += diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else hpred[col & 1] += diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col & 1) { > ~~~~~~~~~~~~~~ > meta_data[j++] = hpred[0] >> 4; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > meta_data[j++] = hpred[0] << 4 | hpred[1] >> 8; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > meta_data[j++] = hpred[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > } else > ~~~~~~ > fprintf (stderr,_("%s has unknown CAMF type %d.\n"), ifname, type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > const char * CLASS foveon_camf_param (const char *block, const char *param) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned idx, num; > ~~~~~~~~~~~~~~~~~~ > char *pos, *cp, *dp; > ~~~~~~~~~~~~~~~~~~~~ > > > for (idx=0; idx < meta_length; idx += sget4(pos+8)) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pos = meta_data + idx; > ~~~~~~~~~~~~~~~~~~~~~~ > if (strncmp (pos, "CMb", 3)) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (pos[3] != 'P') continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (strcmp (block, pos+sget4(pos+12))) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cp = pos + sget4(pos+16); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > num = sget4(cp); > ~~~~~~~~~~~~~~~~ > dp = pos + sget4(cp+4); > ~~~~~~~~~~~~~~~~~~~~~~~ > while (num--) { > ~~~~~~~~~~~~~~~ > cp += 8; > ~~~~~~~~ > if (!strcmp (param, dp+sget4(cp))) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return dp+sget4(cp+4); > ~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > return 0; > ~~~~~~~~~ > } > ~ > > > void * CLASS foveon_camf_matrix (unsigned dim[3], const char *name) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned i, idx, type, ndim, size, *mat; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > char *pos, *cp, *dp; > ~~~~~~~~~~~~~~~~~~~~ > double dsize; > ~~~~~~~~~~~~~ > > > for (idx=0; idx < meta_length; idx += sget4(pos+8)) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pos = meta_data + idx; > ~~~~~~~~~~~~~~~~~~~~~~ > if (strncmp (pos, "CMb", 3)) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (pos[3] != 'M') continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (strcmp (name, pos+sget4(pos+12))) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > dim[0] = dim[1] = dim[2] = 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cp = pos + sget4(pos+16); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > type = sget4(cp); > ~~~~~~~~~~~~~~~~~ > if ((ndim = sget4(cp+4)) > 3) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > dp = pos + sget4(cp+8); > ~~~~~~~~~~~~~~~~~~~~~~~ > for (i=ndim; i--; ) { > ~~~~~~~~~~~~~~~~~~~~~ > cp += 12; > ~~~~~~~~~ > dim[i] = sget4(cp); > ~~~~~~~~~~~~~~~~~~~ > } > ~ > if ((dsize = (double) dim[0]*dim[1]*dim[2]) > meta_length/4) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > mat = (unsigned *) malloc ((size = dsize) * 4); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (mat, "foveon_camf_matrix()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < size; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (type && type != 6) > ~~~~~~~~~~~~~~~~~~~~~~ > mat[i] = sget4(dp + i*4); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > else > ~~~~ > mat[i] = sget4(dp + i*2) & 0xffff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return mat; > ~~~~~~~~~~~ > } > ~ > fprintf (stderr,_("%s: \"%s\" matrix not found!\n"), ifname, name); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return 0; > ~~~~~~~~~ > } > ~ > > > int CLASS foveon_fixed (void *ptr, int size, const char *name) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > void *dp; > ~~~~~~~~~ > unsigned dim[3]; > ~~~~~~~~~~~~~~~~ > > > if (!name) return 0; > ~~~~~~~~~~~~~~~~~~~~ > dp = foveon_camf_matrix (dim, name); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!dp) return 0; > ~~~~~~~~~~~~~~~~~~ > memcpy (ptr, dp, size*4); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > free (dp); > ~~~~~~~~~~ > return 1; > ~~~~~~~~~ > } > ~ > > > float CLASS foveon_avg (short *pix, int range[2], float cfilt) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int i; > ~~~~~~ > float val, min=FLT_MAX, max=-FLT_MAX, sum=0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > for (i=range[0]; i <= range[1]; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sum += val = pix[i*4] + (pix[i*4]-pix[(i-1)*4]) * cfilt; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (min > val) min = val; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if (max < val) max = val; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (range[1] - range[0] == 1) return sum/2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return (sum - min - max) / (range[1] - range[0] - 1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > short * CLASS foveon_make_curve (double max, double mul, double filt) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > short *curve; > ~~~~~~~~~~~~~ > unsigned i, size; > ~~~~~~~~~~~~~~~~~ > double x; > ~~~~~~~~~ > > > if (!filt) filt = 0.8; > ~~~~~~~~~~~~~~~~~~~~~~ > size = 4*M_PI*max / filt; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if (size == UINT_MAX) size--; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > curve = (short *) calloc (size+1, sizeof *curve); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (curve, "foveon_make_curve()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > curve[0] = size; > ~~~~~~~~~~~~~~~~ > for (i=0; i < size; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > x = i*filt/max/4; > ~~~~~~~~~~~~~~~~~ > curve[i+1] = (cos(x)+1)/2 * tanh(i*filt/mul) * mul + 0.5; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > return curve; > ~~~~~~~~~~~~~ > } > ~ > > > void CLASS foveon_make_curves > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (short **curvep, float dq[3], float div[3], float filt) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > double mul[3], max=0; > ~~~~~~~~~~~~~~~~~~~~~ > int c; > ~~~~~~ > > > FORC3 mul[c] = dq[c]/div[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 if (max < mul[c]) max = mul[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 curvep[c] = foveon_make_curve (max, mul[c], filt); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > int CLASS foveon_apply_curve (short *curve, int i) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > if (abs(i) >= curve[0]) return 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return i < 0 ? -curve[1-i] : curve[1+i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > #define image ((short (*)[4]) image) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > void CLASS foveon_interpolate() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > short *pix, prev[3], *curve[8], (*shrink)[3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float cfilt=0, ddft[3][3][2], ppm[3][3][3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float cam_xyz[3][3], correct[3][3], last[3][3], trans[3][3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float chroma_dq[3], color_dq[3], diag[3][3], div[3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float (*black)[3], (*sgain)[3], (*sgrow)[3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float fsum[3], val, frow, num; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int row, col, c, i, j, diff, sgx, irow, sum, min, max, limit; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int dscr[2][2], dstb[4], (*smrow[7])[3], total[4], ipix[3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int work[3][3], smlast, smred, smred_p=0, dev[3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int satlev[3], keep[4], active[4]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unsigned dim[3], *badpix; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > double dsum=0, trsum[3]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > char str[128]; > ~~~~~~~~~~~~~~ > const char* cp; > ~~~~~~~~~~~~~~~ > > > if (verbose) > ~~~~~~~~~~~~ > fprintf (stderr,_("Foveon interpolation...\n")); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > foveon_load_camf(); > ~~~~~~~~~~~~~~~~~~~ > foveon_fixed (dscr, 4, "DarkShieldColRange"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > foveon_fixed (ppm[0][0], 27, "PostPolyMatrix"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > foveon_fixed (satlev, 3, "SaturationLevel"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > foveon_fixed (keep, 4, "KeepImageArea"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > foveon_fixed (active, 4, "ActiveImageArea"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > foveon_fixed (chroma_dq, 3, "ChromaDQ"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > foveon_fixed (color_dq, 3, > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > foveon_camf_param ("IncludeBlocks", "ColorDQ") ? > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > "ColorDQ" : "ColorDQCamRGB"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (foveon_camf_param ("IncludeBlocks", "ColumnFilter")) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > foveon_fixed (&cfilt, 1, "ColumnFilter"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > memset (ddft, 0, sizeof ddft); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!foveon_camf_param ("IncludeBlocks", "DarkDrift") > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > || !foveon_fixed (ddft[1][0], 12, "DarkDrift")) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 2; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~ > foveon_fixed (dstb, 4, i ? "DarkShieldBottom":"DarkShieldTop"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row = dstb[1]; row <= dstb[3]; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col = dstb[0]; col <= dstb[2]; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 ddft[i+1][c][1] += (short) image[row*width+col][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 ddft[i+1][c][1] /= (dstb[3]-dstb[1]+1) * (dstb[2]-dstb[0]+1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2))) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { fprintf (stderr,_("%s: Invalid white balance \"%s\"\n"), ifname, model2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return; } > ~~~~~~~~~ > foveon_fixed (cam_xyz, 9, cp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > foveon_fixed (correct, 9, > ~~~~~~~~~~~~~~~~~~~~~~~~~ > foveon_camf_param ("WhiteBalanceCorrections", model2)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memset (last, 0, sizeof last); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 3; i++) > ~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 3; j++) > ~~~~~~~~~~~~~~~~~~~~~ > FORC3 last[i][j] += correct[i][c] * cam_xyz[c][j]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > #define LAST(x,y) last[(i+x)%3][(c+y)%3] > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 3; i++) > ~~~~~~~~~~~~~~~~~~~~~ > FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > #undef LAST > ~~~~~~~~~~~ > FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sprintf (str, "%sRGBNeutral", model2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (foveon_camf_param ("IncludeBlocks", str)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > foveon_fixed (div, 3, str); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > num = 0; > ~~~~~~~~ > FORC3 if (num < div[c]) num = div[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 div[c] /= num; > ~~~~~~~~~~~~~~~~~~~~ > > > memset (trans, 0, sizeof trans); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 3; i++) > ~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 3; j++) > ~~~~~~~~~~~~~~~~~~~~~ > FORC3 trans[i][j] += rgb_cam[i][c] * last[c][j] * div[j]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 trsum[c] = trans[c][0] + trans[c][1] + trans[c][2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > dsum = (6*trsum[0] + 11*trsum[1] + 3*trsum[2]) / 20; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 3; i++) > ~~~~~~~~~~~~~~~~~~~~~ > FORC3 last[i][c] = trans[i][c] * dsum / trsum[i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memset (trans, 0, sizeof trans); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 3; i++) > ~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 3; j++) > ~~~~~~~~~~~~~~~~~~~~~ > FORC3 trans[i][j] += (i==c ? 32 : -1) * last[c][j] / 30; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > foveon_make_curves (curve, color_dq, div, cfilt); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 chroma_dq[c] /= 3; > ~~~~~~~~~~~~~~~~~~~~~~~~ > foveon_make_curves (curve+3, chroma_dq, div, cfilt); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 dsum += chroma_dq[c] / div[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > curve[6] = foveon_make_curve (dsum, dsum, cfilt); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > curve[7] = foveon_make_curve (dsum*2, dsum*2, cfilt); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > sgain = (float (*)[3]) foveon_camf_matrix (dim, "SpatialGain"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!sgain) return; > ~~~~~~~~~~~~~~~~~~~ > sgrow = (float (*)[3]) calloc (dim[1], sizeof *sgrow); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sgx = (width + dim[1]-2) / (dim[1]-1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > black = (float (*)[3]) calloc (height, sizeof *black); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 6; i++) > ~~~~~~~~~~~~~~~~~~~~~ > ((float *)ddft[0])[i] = ((float *)ddft[1])[i] + > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 black[row][c] = > ~~~~~~~~~~~~~~~~~~~~~ > ( foveon_avg (image[row*width]+c, dscr[0], cfilt) + > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > - ddft[0][c][0] ) / 4 - ddft[0][c][1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > memcpy (black, black+8, sizeof *black*8); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memcpy (black+height-11, black+height-22, 11*sizeof *black); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memcpy (last, black, sizeof last); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > for (row=1; row < height-1; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 if (last[1][c] > last[0][c]) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (last[1][c] > last[2][c]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > black[row][c] = (last[0][c] > last[2][c]) ? last[0][c]:last[2][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else > ~~~~~~ > if (last[1][c] < last[2][c]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > black[row][c] = (last[0][c] < last[2][c]) ? last[0][c]:last[2][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memmove (last, last+1, 2*sizeof last[0]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memcpy (last[2], black[row+1], sizeof last[2]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > FORC3 black[row][c] = (last[0][c] + last[1][c])/2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 black[0][c] = (black[1][c] + black[3][c])/2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > val = 1 - exp(-1/24.0); > ~~~~~~~~~~~~~~~~~~~~~~~ > memcpy (fsum, black, sizeof fsum); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=1; row < height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 fsum[c] += black[row][c] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (black[row][c] - black[row-1][c])*val + black[row-1][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memcpy (last[0], black[height-1], sizeof last[0]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 fsum[c] /= height; > ~~~~~~~~~~~~~~~~~~~~~~~~ > for (row = height; row--; ) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 last[0][c] = black[row][c] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (black[row][c] - fsum[c] - last[0][c])*val + last[0][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > memset (total, 0, sizeof total); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=2; row < height; row+=4) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=2; col < width; col+=4) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 total[c] += (short) image[row*width+col][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > total[3]++; > ~~~~~~~~~~~ > } > ~ > for (row=0; row < height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 black[row][c] += fsum[c]/2 + total[c]/(total[3]*100.0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > for (row=0; row < height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 6; i++) > ~~~~~~~~~~~~~~~~~~~~~ > ((float *)ddft[0])[i] = ((float *)ddft[1])[i] + > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix = image[row*width]; > ~~~~~~~~~~~~~~~~~~~~~~~ > memcpy (prev, pix, sizeof prev); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > frow = row / (height-1.0) * (dim[2]-1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((irow = frow) == dim[2]-1) irow--; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > frow -= irow; > ~~~~~~~~~~~~~ > for (i=0; i < dim[1]; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 sgrow[i][c] = sgain[ irow *dim[1]+i][c] * (1-frow) + > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sgain[(irow+1)*dim[1]+i][c] * frow; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 { > ~~~~~~~ > diff = pix[c] - prev[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > prev[c] = pix[c]; > ~~~~~~~~~~~~~~~~~ > ipix[c] = pix[c] + floor ((diff + (diff*diff >> 14)) * cfilt > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > - ddft[0][c][1] - ddft[0][c][0] * ((float) col/width - 0.5) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > - black[row][c] ); > ~~~~~~~~~~~~~~~~~~ > } > ~ > FORC3 { > ~~~~~~~ > work[0][c] = ipix[c] * ipix[c] >> 14; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > work[2][c] = ipix[c] * work[0][c] >> 14; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > FORC3 { > ~~~~~~~ > for (val=i=0; i < 3; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for ( j=0; j < 3; j++) > ~~~~~~~~~~~~~~~~~~~~~~~ > val += ppm[c][i][j] * work[i][j]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ipix[c] = floor ((ipix[c] + floor(val)) * > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ( sgrow[col/sgx ][c] * (sgx - col%sgx) + > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sgrow[col/sgx+1][c] * (col%sgx) ) / sgx / div[c]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ipix[c] > 32000) ipix[c] = 32000; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[c] = ipix[c]; > ~~~~~~~~~~~~~~~~~ > } > ~ > pix += 4; > ~~~~~~~~~ > } > ~ > } > ~ > free (black); > ~~~~~~~~~~~~~ > free (sgrow); > ~~~~~~~~~~~~~ > free (sgain); > ~~~~~~~~~~~~~ > > > if ((badpix = (unsigned *) foveon_camf_matrix (dim, "BadPixels"))) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < dim[0]; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > col = (badpix[i] >> 8 & 0xfff) - keep[0]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > row = (badpix[i] >> 20 ) - keep[1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((unsigned)(row-1) > height-3 || (unsigned)(col-1) > width-3) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > continue; > ~~~~~~~~~ > memset (fsum, 0, sizeof fsum); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (sum=j=0; j < 8; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if (badpix[i] & (1 << j)) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 fsum[c] += (short) > ~~~~~~~~~~~~~~~~~~~~~~~~ > image[(row+hood[j*2])*width+col+hood[j*2+1]][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sum++; > ~~~~~~ > } > ~ > if (sum) FORC3 image[row*width+col][c] = fsum[c]/sum; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > free (badpix); > ~~~~~~~~~~~~~~ > } > ~ > > > /* Array for 5x5 Gaussian averaging of red values */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > smrow[6] = (int (*)[3]) calloc (width*5, sizeof **smrow); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (smrow[6], "foveon_interpolate()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 5; i++) > ~~~~~~~~~~~~~~~~~~~~~ > smrow[i] = smrow[6] + i*width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > /* Sharpen the reds against these Gaussian averages */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (smlast=-1, row=2; row < height-2; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (smlast < row+2) { > ~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 6; i++) > ~~~~~~~~~~~~~~~~~~~~~ > smrow[(i+5) % 6] = smrow[i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix = image[++smlast*width+2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=2; col < width-2; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > smrow[4][col][0] = > ~~~~~~~~~~~~~~~~~~ > (pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix += 4; > ~~~~~~~~~ > } > ~ > } > ~ > pix = image[row*width+2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=2; col < width-2; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > smred = ( 6 * smrow[2][col][0] > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > + 4 * (smrow[1][col][0] + smrow[3][col][0]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > + smrow[0][col][0] + smrow[4][col][0] + 8 ) >> 4; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (col == 2) > ~~~~~~~~~~~~~ > smred_p = smred; > ~~~~~~~~~~~~~~~~ > i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (i > 32000) i = 32000; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > pix[0] = i; > ~~~~~~~~~~~ > smred_p = smred; > ~~~~~~~~~~~~~~~~ > pix += 4; > ~~~~~~~~~ > } > ~ > } > ~ > > > /* Adjust the brighter pixels for better linearity */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > min = 0xffff; > ~~~~~~~~~~~~~ > FORC3 { > ~~~~~~~ > i = satlev[c] / div[c]; > ~~~~~~~~~~~~~~~~~~~~~~~ > if (min > i) min = i; > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > limit = min * 9 >> 4; > ~~~~~~~~~~~~~~~~~~~~~ > for (pix=image[0]; pix < image[height*width]; pix+=4) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > continue; > ~~~~~~~~~ > min = max = pix[0]; > ~~~~~~~~~~~~~~~~~~~ > for (c=1; c < 3; c++) { > ~~~~~~~~~~~~~~~~~~~~~~~ > if (min > pix[c]) min = pix[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (max < pix[c]) max = pix[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (min >= limit*2) { > ~~~~~~~~~~~~~~~~~~~~~ > pix[0] = pix[1] = pix[2] = max; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else { > ~~~~~~~~ > i = 0x4000 - ((min - limit) << 14) / limit; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = 0x4000 - (i*i >> 14); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > i = i*i >> 14; > ~~~~~~~~~~~~~~ > FORC3 pix[c] += (max - pix[c]) * i >> 14; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > /* > ~~ > Because photons that miss one detector often hit another, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > the sum R+G+B is much less noisy than the individual colors. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > So smooth the hues without smoothing the total. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > for (smlast=-1, row=2; row < height-2; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (smlast < row+2) { > ~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 6; i++) > ~~~~~~~~~~~~~~~~~~~~~ > smrow[(i+5) % 6] = smrow[i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix = image[++smlast*width+2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=2; col < width-2; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 smrow[4][col][c] = (pix[c-4]+2*pix[c]+pix[c+4]+2) >> 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix += 4; > ~~~~~~~~~ > } > ~ > } > ~ > pix = image[row*width+2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=2; col < width-2; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 dev[c] = -foveon_apply_curve (curve[7], pix[c] - > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ((smrow[1][col][c] + 2*smrow[2][col][c] + smrow[3][col][c]) >> 2)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sum = (dev[0] + dev[1] + dev[2]) >> 3; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 pix[c] += dev[c] - sum; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix += 4; > ~~~~~~~~~ > } > ~ > } > ~ > for (smlast=-1, row=2; row < height-2; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (smlast < row+2) { > ~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 6; i++) > ~~~~~~~~~~~~~~~~~~~~~ > smrow[(i+5) % 6] = smrow[i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix = image[++smlast*width+2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=2; col < width-2; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 smrow[4][col][c] = > ~~~~~~~~~~~~~~~~~~~~~~~~ > (pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8]+2) >> 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix += 4; > ~~~~~~~~~ > } > ~ > } > ~ > pix = image[row*width+2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=2; col < width-2; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (total[3]=375, sum=60, c=0; c < 3; c++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (total[c]=i=0; i < 5; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > total[c] += smrow[i][col][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > total[3] += total[c]; > ~~~~~~~~~~~~~~~~~~~~~ > sum += pix[c]; > ~~~~~~~~~~~~~~ > } > ~ > if (sum < 0) sum = 0; > ~~~~~~~~~~~~~~~~~~~~~ > j = total[3] > 375 ? (sum << 16) / total[3] : sum * 174; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 pix[c] += foveon_apply_curve (curve[6], > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ((j*total[c] + 0x8000) >> 16) - pix[c]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > pix += 4; > ~~~~~~~~~ > } > ~ > } > ~ > > > /* Transform the image to a different colorspace */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (pix=image[0]; pix < image[height*width]; pix+=4) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sum = (pix[0]+pix[1]+pix[1]+pix[2]) >> 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]-sum); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 { > ~~~~~~~ > for (dsum=i=0; i < 3; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > dsum += trans[c][i] * pix[i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (dsum < 0) dsum = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (dsum > 24000) dsum = 24000; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ipix[c] = dsum + 0.5; > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > FORC3 pix[c] = ipix[c]; > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > /* Smooth the image bottom-to-top and save at 1/4 scale */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > shrink = (short (*)[3]) calloc ((height/4), (width/4)*sizeof *shrink); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (shrink, "foveon_interpolate()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row = height/4; row--; ) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width/4; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ipix[0] = ipix[1] = ipix[2] = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 4; i++) > ~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 4; j++) > ~~~~~~~~~~~~~~~~~~~~~ > FORC3 ipix[c] += image[(row*4+i)*width+col*4+j][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 > ~~~~~ > if (row+2 > height/4) > ~~~~~~~~~~~~~~~~~~~~~ > shrink[row*(width/4)+col][c] = ipix[c] >> 4; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else > ~~~~ > shrink[row*(width/4)+col][c] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (shrink[(row+1)*(width/4)+col][c]*1840 + ipix[c]*141 + 2048) >> 12; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > /* From the 1/4-scale image, smooth right-to-left */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < (height & ~3); row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ipix[0] = ipix[1] = ipix[2] = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((row & 3) == 0) > ~~~~~~~~~~~~~~~~~~~ > for (col = width & ~3 ; col--; ) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 smrow[0][col][c] = ipix[c] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (shrink[(row/4)*(width/4)+col/4][c]*1485 + ipix[c]*6707 + 4096) >> 13; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > /* Then smooth left-to-right */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ipix[0] = ipix[1] = ipix[2] = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < (width & ~3); col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 smrow[1][col][c] = ipix[c] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (smrow[0][col][c]*1485 + ipix[c]*6707 + 4096) >> 13; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > /* Smooth top-to-bottom */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (row == 0) > ~~~~~~~~~~~~~ > memcpy (smrow[2], smrow[1], sizeof **smrow * width); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else > ~~~~ > for (col=0; col < (width & ~3); col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 smrow[2][col][c] = > ~~~~~~~~~~~~~~~~~~~~~~~~ > (smrow[2][col][c]*6707 + smrow[1][col][c]*1485 + 4096) >> 13; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > /* Adjust the chroma toward the smooth values */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < (width & ~3); col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=j=30, c=0; c < 3; c++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i += smrow[2][col][c]; > ~~~~~~~~~~~~~~~~~~~~~~ > j += image[row*width+col][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > j = (j << 16) / i; > ~~~~~~~~~~~~~~~~~~ > for (sum=c=0; c < 3; c++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ipix[c] = foveon_apply_curve (curve[c+3], > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ((smrow[2][col][c] * j + 0x8000) >> 16) - image[row*width+col][c]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sum += ipix[c]; > ~~~~~~~~~~~~~~~ > } > ~ > sum >>= 3; > ~~~~~~~~~~ > FORC3 { > ~~~~~~~ > i = image[row*width+col][c] + ipix[c] - sum; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (i < 0) i = 0; > ~~~~~~~~~~~~~~~~~ > image[row*width+col][c] = i; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > free (shrink); > ~~~~~~~~~~~~~~ > free (smrow[6]); > ~~~~~~~~~~~~~~~~ > for (i=0; i < 8; i++) > ~~~~~~~~~~~~~~~~~~~~~ > free (curve[i]); > ~~~~~~~~~~~~~~~~ > > > /* Trim off the black border */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > active[1] -= keep[1]; > ~~~~~~~~~~~~~~~~~~~~~ > active[3] -= 2; > ~~~~~~~~~~~~~~~ > i = active[2] - active[0]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < active[3]-active[1]; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memcpy (image[row*i], image[(row+active[1])*width+active[0]], > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i * sizeof *image); > ~~~~~~~~~~~~~~~~~~~ > width = i; > ~~~~~~~~~~ > height = row; > ~~~~~~~~~~~~~ > } > ~ > #undef image > ~~~~~~~~~~~~ > > > /* RESTRICTED code ends here */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > void CLASS crop_masked_pixels() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int row, col; > ~~~~~~~~~~~~~ > unsigned r, c, m, mblack[8], zero, val; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > if (load_raw == &CLASS phase_one_load_raw || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > load_raw == &CLASS phase_one_load_raw_c) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > phase_one_correct(); > ~~~~~~~~~~~~~~~~~~~~ > if (load_raw == &CLASS hasselblad_load_raw) // RT > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > hasselblad_correct(); // RT > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (fuji_width) { > ~~~~~~~~~~~~~~~~~ > for (row=0; row < raw_height-top_margin*2; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < fuji_width << !fuji_layout; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (fuji_layout) { > ~~~~~~~~~~~~~~~~~~ > r = fuji_width - 1 - col + (row >> 1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > c = col + ((row+1) >> 1); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > } else { > ~~~~~~~~ > r = fuji_width - 1 + row - (col >> 1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > c = row + ((col+1) >> 1); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (r < height && c < width) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > BAYER(r,c) = RAW(row+top_margin,col+left_margin); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } else { > ~~~~~~~~ > > > #pragma omp parallel for > ~~~~~~~~~~~~~~~~~~~~~~~~ > for (int row=0; row < height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (int col=0; col < width; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > BAYER2(row,col) = RAW(row+top_margin,col+left_margin); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > if (mask[0][3] > 0) goto mask_set; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (load_raw == &CLASS canon_load_raw || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > load_raw == &CLASS lossless_jpeg_load_raw) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > mask[0][1] = mask[1][1] += 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > mask[0][3] -= 2; > ~~~~~~~~~~~~~~~~ > goto sides; > ~~~~~~~~~~~ > } > ~ > if (load_raw == &CLASS canon_600_load_raw || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > load_raw == &CLASS sony_load_raw || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (load_raw == &CLASS eight_bit_load_raw && strncmp(model,"DC2",3)) || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > load_raw == &CLASS kodak_262_load_raw || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (load_raw == &CLASS packed_load_raw && (load_flags & 32))) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sides: > ~~~~~~ > mask[0][0] = mask[1][0] = top_margin; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > mask[0][2] = mask[1][2] = top_margin+height; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > mask[0][3] += left_margin; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > mask[1][1] += left_margin+width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > mask[1][3] += raw_width; > ~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (load_raw == &CLASS nokia_load_raw) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > mask[0][2] = top_margin; > ~~~~~~~~~~~~~~~~~~~~~~~~ > mask[0][3] = width; > ~~~~~~~~~~~~~~~~~~~ > } > ~ > mask_set: > ~~~~~~~~~ > memset (mblack, 0, sizeof mblack); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (zero=m=0; m < 8; m++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=MAX(mask[m][0],0); row < MIN(mask[m][2],raw_height); row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=MAX(mask[m][1],0); col < MIN(mask[m][3],raw_width); col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > c = FC(row-top_margin,col-left_margin); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > mblack[c] += val = RAW(row,col); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > mblack[4+c]++; > ~~~~~~~~~~~~~~ > zero += !val; > ~~~~~~~~~~~~~ > } > ~ > if (load_raw == &CLASS canon_600_load_raw && width < raw_width) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > black = (mblack[0]+mblack[1]+mblack[2]+mblack[3]) / > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (mblack[4]+mblack[5]+mblack[6]+mblack[7]) - 4; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > canon_600_correct(); > ~~~~~~~~~~~~~~~~~~~~ > } else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7]) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 cblack[c] = mblack[c] / mblack[4+c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cblack[4] = cblack[5] = cblack[6] = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > //void CLASS remove_zeroes() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > //{ > ~~~ > // unsigned row, col, tot, n, r, c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // > ~~ > // for (row=0; row < height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (col=0; col < width; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (BAYER(row,col) == 0) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // tot = n = 0; > ~~~~~~~~~~~~~~~ > // for (r = row-2; r <= row+2; r++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (c = col-2; c <= col+2; c++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (r < height && c < width && > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // FC(r,c) == FC(row,col) && BAYER(r,c)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // tot += (n++,BAYER(r,c)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (n) BAYER(row,col) = tot/n; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~~ > //} > ~~~ > > > /* > ~~ > Seach from the current directory up to the root looking for > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > a ".badpixels" file, and fix those pixels now. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > //void CLASS bad_pixels (const char *cfname) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > //{ > ~~~ > // FILE *fp=0; > ~~~~~~~~~~~~~~~ > // char *fname, *cp, line[128]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // int len, time, row, col, r, c, rad, tot, n, fixed=0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // > ~~ > // if (!filters) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (cfname) > ~~~~~~~~~~~~~~~ > // fp = fopen (cfname, "r"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // else { > ~~~~~~~~~~ > // for (len=32 ; ; len *= 2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // fname = (char *) malloc (len); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (!fname) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (getcwd (fname, len-16)) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // free (fname); > ~~~~~~~~~~~~~~~~~~~~~ > // if (errno != ERANGE) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~ > //#if defined(WIN32) || defined(DJGPP) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (fname[1] == ':') > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > // memmove (fname, fname+2, len-2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (cp=fname; *cp; cp++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (*cp == '\\') *cp = '/'; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > //#endif > ~~~~~~~~ > // cp = fname + strlen(fname); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (cp[-1] == '/') cp--; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // while (*fname == '/') { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // strcpy (cp, "/.badpixels"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if ((fp = fopen (fname, "r"))) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (cp == fname) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // while (*--cp != '/'); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~ > // free (fname); > ~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~ > // if (!fp) return; > ~~~~~~~~~~~~~~~~~~~~ > // while (fgets (line, 128, fp)) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // cp = strchr (line, '#'); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (cp) *cp = 0; > ~~~~~~~~~~~~~~~~~~~~~~ > // if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if ((unsigned) col >= width || (unsigned) row >= height) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (time > timestamp) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (tot=n=0, rad=1; rad < 3 && n==0; rad++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (r = row-rad; r <= row+rad; r++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (c = col-rad; c <= col+rad; c++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if ((unsigned) r < height && (unsigned) c < width && > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // (r != row || c != col) && fcol(r,c) == fcol(row,col)) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // tot += BAYER2(r,c); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > // n++; > ~~~~~~~~~~~ > // } > ~~~~~~ > // BAYER2(row,col) = tot/n; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (verbose) { > ~~~~~~~~~~~~~~~~~~~~ > // if (!fixed++) > ~~~~~~~~~~~~~~~~~~~~~ > // fprintf (stderr,_("Fixed dead pixels at:")); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // fprintf (stderr, " %d,%d", col, row); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~ > // } > ~~~~~ > // if (fixed) fputc ('\n', stderr); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // fclose (fp); > ~~~~~~~~~~~~~~~~ > //} > ~~~ > > > //void CLASS subtract (const char *fname) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > //{ > ~~~ > // FILE *fp; > ~~~~~~~~~~~~~ > // int dim[3]={0,0,0}, comment=0, number=0, error=0, nd=0, c, row, col; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // ushort *pixel; > ~~~~~~~~~~~~~~~~~~ > // > ~~ > // if (!(fp = fopen (fname, "rb"))) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // perror (fname); return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~ > // if (fgetc(fp) != 'P' || fgetc(fp) != '5') error = 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // while (!error && nd < 3 && (c = fgetc(fp)) != EOF) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (c == '#') comment = 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (c == '\n') comment = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (comment) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (isdigit(c)) number = 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (number) { > ~~~~~~~~~~~~~~~~~~~ > // if (isdigit(c)) dim[nd] = dim[nd]*10 + c -'0'; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // else if (isspace(c)) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // number = 0; nd++; > ~~~~~~~~~~~~~~~~~~~~~ > // } else error = 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~ > // } > ~~~~~ > // if (error || nd < 3) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > // fprintf (stderr,_("%s is not a valid PGM file!\n"), fname); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // fclose (fp); return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } else if (dim[0] != width || dim[1] != height || dim[2] != 65535) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // fprintf (stderr,_("%s has the wrong dimensions!\n"), fname); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // fclose (fp); return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~ > // pixel = (ushort *) calloc (width, sizeof *pixel); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // merror (pixel, "subtract()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (row=0; row < height; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // fread (pixel, 2, width, fp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (col=0; col < width; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // BAYER(row,col) = MAX (BAYER(row,col) - ntohs(pixel[col]), 0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~ > // free (pixel); > ~~~~~~~~~~~~~~~~~ > // fclose (fp); > ~~~~~~~~~~~~~~~~ > // memset (cblack, 0, sizeof cblack); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // black = 0; > ~~~~~~~~~~~~~~ > //} > ~~~ > > > void CLASS gamma_curve (double pwr, double ts, int mode, int imax) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int i; > ~~~~~~ > double g[6], bnd[2]={0,0}, r; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > g[0] = pwr; > ~~~~~~~~~~~ > g[1] = ts; > ~~~~~~~~~~ > g[2] = g[3] = g[4] = 0; > ~~~~~~~~~~~~~~~~~~~~~~~ > bnd[g[1] >= 1] = 1; > ~~~~~~~~~~~~~~~~~~~ > if (g[1] && (g[1]-1)*(g[0]-1) <= 0) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 48; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~ > g[2] = (bnd[0] + bnd[1])/2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (g[0]) bnd[(pow(g[2]/g[1],-g[0]) - 1)/g[0] - 1/g[2] > -1] = g[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else bnd[g[2]/exp(1-1/g[2]) < g[1]] = g[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > g[3] = g[2] / g[1]; > ~~~~~~~~~~~~~~~~~~~ > if (g[0]) g[4] = g[2] * (1/g[0] - 1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (g[0]) g[5] = 1 / (g[1]*SQR(g[3])/2 - g[4]*(1 - g[3]) + > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (1 - pow(g[3],1+g[0]))*(1 + g[4])/(1 + g[0])) - 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else g[5] = 1 / (g[1]*SQR(g[3])/2 + 1 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > - g[2] - g[3] - g[2]*g[3]*(log(g[3]) - 1)) - 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!mode--) { > ~~~~~~~~~~~~~~ > memcpy (gamm, g, sizeof gamm); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return; > ~~~~~~~ > } > ~ > for (i=0; i < 0x10000; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > curve[i] = 0xffff; > ~~~~~~~~~~~~~~~~~~ > if ((r = (double) i / imax) < 1) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > curve[i] = 0x10000 * ( mode > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ? (r < g[3] ? r*g[1] : (g[0] ? pow( r,g[0])*(1+g[4])-g[4] : log(r)*g[2]+1)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > : (r < g[2] ? r/g[1] : (g[0] ? pow((r+g[4])/(1+g[4]),1/g[0]) : exp((r-1)/g[2])))); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > double work[3][6], num; > ~~~~~~~~~~~~~~~~~~~~~~~ > int i, j, k; > ~~~~~~~~~~~~ > > > for (i=0; i < 3; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 6; j++) > ~~~~~~~~~~~~~~~~~~~~~ > work[i][j] = j == i+3; > ~~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 3; j++) > ~~~~~~~~~~~~~~~~~~~~~ > for (k=0; k < size; k++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > work[i][j] += in[k][i] * in[k][j]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > for (i=0; i < 3; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~ > num = work[i][i]; > ~~~~~~~~~~~~~~~~~ > for (j=0; j < 6; j++) > ~~~~~~~~~~~~~~~~~~~~~ > work[i][j] /= num; > ~~~~~~~~~~~~~~~~~~ > for (k=0; k < 3; k++) { > ~~~~~~~~~~~~~~~~~~~~~~~ > if (k==i) continue; > ~~~~~~~~~~~~~~~~~~~ > num = work[k][i]; > ~~~~~~~~~~~~~~~~~ > for (j=0; j < 6; j++) > ~~~~~~~~~~~~~~~~~~~~~ > work[k][j] -= work[i][j] * num; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > for (i=0; i < size; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 3; j++) > ~~~~~~~~~~~~~~~~~~~~~ > for (out[i][j]=k=0; k < 3; k++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > out[i][j] += work[j][k+3] * in[i][k]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS cam_xyz_coeff (float rgb_cam[3][4], double cam_xyz[4][3]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > double cam_rgb[4][3], inverse[4][3], num; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int i, j, k; > ~~~~~~~~~~~~ > > > for (i=0; i < colors; i++) /* Multiply out XYZ colorspace */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 3; j++) > ~~~~~~~~~~~~~~~~~~~~~ > for (cam_rgb[i][j] = k=0; k < 3; k++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > for (i=0; i < colors; i++) { /* Normalize cam_rgb so that */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (num=j=0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > num += cam_rgb[i][j]; > ~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 3; j++) > ~~~~~~~~~~~~~~~~~~~~~ > cam_rgb[i][j] /= num; > ~~~~~~~~~~~~~~~~~~~~~ > pre_mul[i] = 1 / num; > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > pseudoinverse (cam_rgb, inverse, colors); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 3; i++) > ~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < colors; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > rgb_cam[i][j] = inverse[j][i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > #ifdef COLORCHECK > ~~~~~~~~~~~~~~~~~ > void CLASS colorcheck() > ~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > #define NSQ 24 > ~~~~~~~~~~~~~~ > // Coordinates of the GretagMacbeth ColorChecker squares > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // width, height, 1st_column, 1st_row > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int cut[NSQ][4]; // you must set these > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // ColorChecker Chart under 6500-kelvin illumination > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > static const double gmb_xyY[NSQ][3] = { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.400, 0.350, 10.1 }, // Dark Skin > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.377, 0.345, 35.8 }, // Light Skin > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.247, 0.251, 19.3 }, // Blue Sky > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.337, 0.422, 13.3 }, // Foliage > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.265, 0.240, 24.3 }, // Blue Flower > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.261, 0.343, 43.1 }, // Bluish Green > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.506, 0.407, 30.1 }, // Orange > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.211, 0.175, 12.0 }, // Purplish Blue > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.453, 0.306, 19.8 }, // Moderate Red > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.285, 0.202, 6.6 }, // Purple > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.380, 0.489, 44.3 }, // Yellow Green > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.473, 0.438, 43.1 }, // Orange Yellow > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.187, 0.129, 6.1 }, // Blue > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.305, 0.478, 23.4 }, // Green > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.539, 0.313, 12.0 }, // Red > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.448, 0.470, 59.1 }, // Yellow > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.364, 0.233, 19.8 }, // Magenta > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.196, 0.252, 19.8 }, // Cyan > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.310, 0.316, 90.0 }, // White > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.310, 0.316, 59.1 }, // Neutral 8 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.310, 0.316, 36.2 }, // Neutral 6.5 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.310, 0.316, 19.8 }, // Neutral 5 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.310, 0.316, 9.0 }, // Neutral 3.5 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0.310, 0.316, 3.1 } }; // Black > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > double gmb_cam[NSQ][4], gmb_xyz[NSQ][3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > double inverse[NSQ][3], cam_xyz[4][3], balance[4], num; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int c, i, j, k, sq, row, col, pass, count[4]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > memset (gmb_cam, 0, sizeof gmb_cam); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (sq=0; sq < NSQ; sq++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORCC count[c] = 0; > ~~~~~~~~~~~~~~~~~~~ > for (row=cut[sq][3]; row < cut[sq][3]+cut[sq][1]; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > c = FC(row,col); > ~~~~~~~~~~~~~~~~ > if (c >= colors) c -= 2; > ~~~~~~~~~~~~~~~~~~~~~~~~ > gmb_cam[sq][c] += BAYER2(row,col); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > BAYER2(row,col) = black + (BAYER2(row,col)-black)/2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > count[c]++; > ~~~~~~~~~~~ > } > ~ > FORCC gmb_cam[sq][c] = gmb_cam[sq][c]/count[c] - black; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > gmb_xyz[sq][0] = gmb_xyY[sq][2] * gmb_xyY[sq][0] / gmb_xyY[sq][1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > gmb_xyz[sq][1] = gmb_xyY[sq][2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > gmb_xyz[sq][2] = gmb_xyY[sq][2] * > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > pseudoinverse (gmb_xyz, inverse, NSQ); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (pass=0; pass < 2; pass++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (raw_color = i=0; i < colors; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 3; j++) > ~~~~~~~~~~~~~~~~~~~~~ > for (cam_xyz[i][j] = k=0; k < NSQ; k++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cam_xyz_coeff (rgb_cam, cam_xyz); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORCC balance[c] = pre_mul[c] * gmb_cam[20][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (sq=0; sq < NSQ; sq++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORCC gmb_cam[sq][c] *= balance[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (verbose) { > ~~~~~~~~~~~~~~ > printf (" { \"%s %s\", %d,\n\t{", make, model, black); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORCC for (j=0; j < 3; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > printf ("%c%d", (c | j) ? ',':' ', (int) (cam_xyz[c][j] * num + 0.5)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > puts (" } },"); > ~~~~~~~~~~~~~~~ > } > ~ > #undef NSQ > ~~~~~~~~~~ > } > ~ > #endif > ~~~~~~ > > > //void CLASS hat_transform (float *temp, float *base, int st, int size, int sc) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > //{ > ~~~ > // int i; > ~~~~~~~~~~ > // for (i=0; i < sc; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > // temp[i] = 2*base[st*i] + base[st*(sc-i)] + base[st*(i+sc)]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (; i+sc < size; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(i+sc)]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (; i < size; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~ > // temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(2*size-2-(i+sc))]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > //} > ~~~ > > > //void CLASS wavelet_denoise() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > //{ > ~~~ > // float *fimg=0, *temp, thold, mul[2], avg, diff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast, blk[2]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // ushort *window[4]; > ~~~~~~~~~~~~~~~~~~~~~~ > // static const float noise[] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // { 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // > ~~ > // if (verbose) fprintf (stderr,_("Wavelet denoising...\n")); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // > ~~ > // while (maximum << scale < 0x10000) scale++; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // maximum <<= --scale; > ~~~~~~~~~~~~~~~~~~~~~~~~ > // black <<= scale; > ~~~~~~~~~~~~~~~~~~~~ > // FORC4 cblack[c] <<= scale; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if ((size = iheight*iwidth) < 0x15550000) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // fimg = (float *) malloc ((size*3 + iheight + iwidth) * sizeof *fimg); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // merror (fimg, "wavelet_denoise()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // temp = fimg + size*3; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > // if ((nc = colors) == 3 && filters) nc++; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // FORC(nc) { /* denoise R,G1,B,G3 individually */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (i=0; i < size; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // fimg[i] = 256 * sqrt(image[i][c] << scale); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (hpass=lev=0; lev < 5; lev++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // lpass = size*((lev & 1)+1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (row=0; row < iheight; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // hat_transform (temp, fimg+hpass+row*iwidth, 1, iwidth, 1 << lev); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (col=0; col < iwidth; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // fimg[lpass + row*iwidth + col] = temp[col] * 0.25; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~~ > // for (col=0; col < iwidth; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // hat_transform (temp, fimg+lpass+col, iwidth, iheight, 1 << lev); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (row=0; row < iheight; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // fimg[lpass + row*iwidth + col] = temp[row] * 0.25; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~~ > // thold = threshold * noise[lev]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (i=0; i < size; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // fimg[hpass+i] -= fimg[lpass+i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (fimg[hpass+i] < -thold) fimg[hpass+i] += thold; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // else if (fimg[hpass+i] > thold) fimg[hpass+i] -= thold; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // else fimg[hpass+i] = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (hpass) fimg[i] += fimg[hpass+i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~~ > // hpass = lpass; > ~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~ > // for (i=0; i < size; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // image[i][c] = CLIP(SQR(fimg[i]+fimg[lpass+i])/0x10000); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~ > // if (filters && colors == 3) { /* pull G1 and G3 closer together */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (row=0; row < 2; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // mul[row] = 0.125 * pre_mul[FC(row+1,0) | 1] / pre_mul[FC(row,0) | 1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // blk[row] = cblack[FC(row,0) | 1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~ > // for (i=0; i < 4; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // window[i] = (ushort *) fimg + width*i; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (wlast=-1, row=1; row < height-1; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // while (wlast < row+1) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (wlast++, i=0; i < 4; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // window[(i+3) & 3] = window[i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (col = FC(wlast,1) & 1; col < width; col+=2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // window[2][col] = BAYER(wlast,col); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~~ > // thold = threshold/512; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (col = (FC(row,0) & 1)+1; col < width-1; col+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // avg = ( window[0][col-1] + window[0][col+1] + > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // window[2][col-1] + window[2][col+1] - blk[~row & 1]*4 ) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // * mul[row & 1] + (window[1][col] + blk[row & 1]) * 0.5; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // avg = avg < 0 ? 0 : sqrt(avg); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // diff = sqrt(BAYER(row,col)) - avg; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (diff < -thold) diff += thold; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // else if (diff > thold) diff -= thold; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // else diff = 0; > ~~~~~~~~~~~~~~~~~ > // BAYER(row,col) = CLIP(SQR(avg+diff) + 0.5); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~~ > // } > ~~~~~~~ > // } > ~~~~~ > // free (fimg); > ~~~~~~~~~~~~~~~~ > //} > ~~~ > > > void CLASS scale_colors() > ~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int val, dark, sat; > ~~~~~~~~~~~~~~~~~~~ > double dsum[8], dmin, dmax; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float scale_mul[4], fr, fc; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ushort *img=0, *pix; > ~~~~~~~~~~~~~~~~~~~~ > > > if (user_mul[0]) > ~~~~~~~~~~~~~~~~ > memcpy (pre_mul, user_mul, sizeof pre_mul); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memset (dsum, 0, sizeof dsum); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > bottom = MIN (greybox[1]+greybox[3], height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > right = MIN (greybox[0]+greybox[2], width); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=greybox[1]; row < bottom; row += 8) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=greybox[0]; col < right; col += 8) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memset (sum, 0, sizeof sum); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (y=row; y < row+8 && y < bottom; y++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (x=col; x < col+8 && x < right; x++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 { > ~~~~~~~ > if (filters) { > ~~~~~~~~~~~~~~ > c = fcol(y,x); > ~~~~~~~~~~~~~~ > val = BAYER2(y,x); > ~~~~~~~~~~~~~~~~~~ > } else > ~~~~~~ > val = image[y*width+x][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (val > maximum-25) goto skip_block; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((val -= cblack[c]) < 0) val = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sum[c] += val; > ~~~~~~~~~~~~~~ > sum[c+4]++; > ~~~~~~~~~~~ > if (filters) break; > ~~~~~~~~~~~~~~~~~~~ > } > ~ > FORC(8) dsum[c] += sum[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > skip_block: ; > ~~~~~~~~~~~~~ > } > ~ > FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (use_camera_wb && cam_mul[0] != -1) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memset (sum, 0, sizeof sum); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < 8; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < 8; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > c = FC(row,col); > ~~~~~~~~~~~~~~~~ > if ((val = white[row][col] - cblack[c]) > 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sum[c] += val; > ~~~~~~~~~~~~~~ > sum[c+4]++; > ~~~~~~~~~~~ > } > ~ > if (sum[0] && sum[1] && sum[2] && sum[3]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 pre_mul[c] = (float) sum[c+4] / sum[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else if (cam_mul[0] && cam_mul[2]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > memcpy (pre_mul, cam_mul, sizeof pre_mul); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else > ~~~~ > fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (pre_mul[1] == 0) pre_mul[1] = 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > dark = black; > ~~~~~~~~~~~~~ > sat = maximum; > ~~~~~~~~~~~~~~ > // if (threshold) wavelet_denoise(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > maximum -= black; > ~~~~~~~~~~~~~~~~~ > for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (dmin > pre_mul[c]) > ~~~~~~~~~~~~~~~~~~~~~~ > dmin = pre_mul[c]; > ~~~~~~~~~~~~~~~~~~ > if (dmax < pre_mul[c]) > ~~~~~~~~~~~~~~~~~~~~~~ > dmax = pre_mul[c]; > ~~~~~~~~~~~~~~~~~~ > } > ~ > if (!highlight) dmax = dmin; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (verbose) { > ~~~~~~~~~~~~~~ > fprintf (stderr, > ~~~~~~~~~~~~~~~~ > _("Scaling with darkness %d, saturation %d, and\nmultipliers"), dark, sat); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 fprintf (stderr, " %f", pre_mul[c]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fputc ('\n', stderr); > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (filters > 1000 && (cblack[4]+1)/2 == 1 && (cblack[5]+1)/2 == 1) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 cblack[FC(c/2,c%2)] += > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cblack[6 + c/2 % cblack[4] * cblack[5] + c%2 % cblack[5]]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cblack[4] = cblack[5] = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > size = iheight*iwidth; > ~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < size*4; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!(val = ((ushort *)image)[i])) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (cblack[4] && cblack[5]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > val -= cblack[6 + i/4 / iwidth % cblack[4] * cblack[5] + > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i/4 % iwidth % cblack[5]]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > val -= cblack[i & 3]; > ~~~~~~~~~~~~~~~~~~~~~ > val *= scale_mul[i & 3]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > ((ushort *)image)[i] = CLIP(val); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if ((aber[0] != 1 || aber[2] != 1) && colors == 3) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (verbose) > ~~~~~~~~~~~~ > fprintf (stderr,_("Correcting chromatic aberration...\n")); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (c=0; c < 4; c+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (aber[c] == 1) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > img = (ushort *) malloc (size * sizeof *img); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (img, "scale_colors()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < size; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~ > img[i] = image[i][c]; > ~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < iheight; row++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ur = fr = (row - iheight*0.5) * aber[c] + iheight*0.5; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ur > iheight-2) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fr -= ur; > ~~~~~~~~~ > for (col=0; col < iwidth; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > uc = fc = (col - iwidth*0.5) * aber[c] + iwidth*0.5; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (uc > iwidth-2) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fc -= uc; > ~~~~~~~~~ > pix = img + ur*iwidth + uc; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > image[row*iwidth+col][c] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > (pix[ 0]*(1-fc) + pix[ 1]*fc) * (1-fr) + > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (pix[iwidth]*(1-fc) + pix[iwidth+1]*fc) * fr; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > free(img); > ~~~~~~~~~~ > } > ~ > } > ~ > } > ~ > > > void CLASS pre_interpolate() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > ushort (*img)[4]; > ~~~~~~~~~~~~~~~~~ > int row, col, c; > ~~~~~~~~~~~~~~~~ > > > if (shrink) { > ~~~~~~~~~~~~~ > if (half_size) { > ~~~~~~~~~~~~~~~~ > height = iheight; > ~~~~~~~~~~~~~~~~~ > width = iwidth; > ~~~~~~~~~~~~~~~~ > if (filters == 9) { > ~~~~~~~~~~~~~~~~~~~ > for (row=0; row < 3; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=1; col < 4; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!(image[row*width+col][0] | image[row*width+col][2])) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > goto break2; break2: > ~~~~~~~~~~~~~~~~~~~~~ > for ( ; row < height; row+=3) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=(col-1)%3+1; col < width-1; col+=3) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > img = image + row*width+col; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (c=0; c < 3; c+=2) > ~~~~~~~~~~~~~~~~~~~~~~ > img[0][c] = (img[-1][c] + img[1][c]) >> 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > } else { > ~~~~~~~~ > img = (ushort (*)[4]) calloc (height, width*sizeof *img); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > merror (img, "pre_interpolate()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (row=0; row < height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col=0; col < width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > c = fcol(row,col); > ~~~~~~~~~~~~~~~~~~ > img[row*width+col][c] = image[(row >> 1)*iwidth+(col >> 1)][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > free (image); > ~~~~~~~~~~~~~ > image = img; > ~~~~~~~~~~~~ > shrink = 0; > ~~~~~~~~~~~ > } > ~ > } > ~ > if (filters > 1000 && colors == 3) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > mix_green = four_color_rgb ^ half_size; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (four_color_rgb | half_size) colors++; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else { > ~~~~~~ > for (row = FC(1,0) >> 1; row < height; row+=2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (col = FC(row,1) & 1; col < width; col+=2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > image[row*width+col][1] = image[row*width+col][3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > filters &= ~((filters & 0x55555555) << 1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > if (half_size) filters = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > //void CLASS border_interpolate (int border) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > //{ > ~~~ > // unsigned row, col, y, x, f, c, sum[8]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // > ~~ > // for (row=0; row < height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (col=0; col < width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (col==border && row >= border && row < height-border) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // col = width-border; > ~~~~~~~~~~~~~~~~~~~~~~ > // memset (sum, 0, sizeof sum); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (y=row-1; y != row+2; y++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (x=col-1; x != col+2; x++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (y < height && x < width) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // f = fcol(y,x); > ~~~~~~~~~~~~~~~~~~~~~ > // sum[f] += image[y*width+x][f]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // sum[f+4]++; > ~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~ > // f = fcol(row,col); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > // FORCC if (c != f && sum[c+4]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // image[row*width+col][c] = sum[c] / sum[c+4]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~ > //} > ~~~ > > > /* RT: delete interpolation functions */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > > > //void CLASS cielab (ushort rgb[3], short lab[3]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > //{ > ~~~ > // int c, i, j, k; > ~~~~~~~~~~~~~~~~~~~ > // float r, xyz[3]; > ~~~~~~~~~~~~~~~~~~~~ > // static float cbrt[0x10000], xyz_cam[3][4]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // > ~~ > // if (!rgb) { > ~~~~~~~~~~~~~~~ > // for (i=0; i < 0x10000; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // r = i / 65535.0; > ~~~~~~~~~~~~~~~~~~~~~~~~ > // cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~ > // for (i=0; i < 3; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (j=0; j < colors; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (xyz_cam[i][j] = k=0; k < 3; k++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // return; > ~~~~~~~~~~~~~ > // } > ~~~~~ > // xyz[0] = xyz[1] = xyz[2] = 0.5; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // FORCC { > ~~~~~~~~~~~ > // xyz[0] += xyz_cam[0][c] * rgb[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // xyz[1] += xyz_cam[1][c] * rgb[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // xyz[2] += xyz_cam[2][c] * rgb[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~ > // xyz[0] = cbrt[CLIP((int) xyz[0])]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // xyz[1] = cbrt[CLIP((int) xyz[1])]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // xyz[2] = cbrt[CLIP((int) xyz[2])]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // lab[0] = 64 * (116 * xyz[1] - 16); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // lab[1] = 64 * 500 * (xyz[0] - xyz[1]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // lab[2] = 64 * 200 * (xyz[1] - xyz[2]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > //} > ~~~ > // > ~~ > //#define TS 512 /* Tile Size */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > //#define fcol(row,col) xtrans[(row+6) % 6][(col+6) % 6] > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // > ~~ > ///* > ~~~~ > // Frank Markesteijn's algorithm for Fuji X-Trans sensors > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // */ > ~~~~~ > //void CLASS xtrans_interpolate (int passes) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > //{ > ~~~ > // int c, d, f, g, h, i, v, ng, row, col, top, left, mrow, mcol; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // int val, ndir, pass, hm[8], avg[4], color[3][8]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // static const short orth[12] = { 1,0,0,1,-1,0,0,-1,1,0,0,1 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // patt[2][16] = { { 0,1,0,-1,2,0,-1,0,1,1,1,-1,0,0,0,0 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // { 0,1,0,-2,1,0,-2,0,1,1,-2,-2,1,-1,-1,1 } }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // dir[4] = { 1,TS,TS+1,TS-1 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // short allhex[3][3][2][8], *hex; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // ushort min, max, sgrow, sgcol; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // short (*lab) [TS][3], (*lix)[3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // float (*drv)[TS][TS], diff[6], tr; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // char (*homo)[TS][TS], *buffer; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // > ~~ > // if (verbose) > ~~~~~~~~~~~~~~~~ > // fprintf (stderr,_("%d-pass X-Trans interpolation...\n"), passes); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // > ~~ > // cielab (0,0); > ~~~~~~~~~~~~~~~~~ > // ndir = 4 << (passes > 1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // buffer = (char *) malloc (TS*TS*(ndir*11+6)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // merror (buffer, "xtrans_interpolate()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // rgb = (ushort(*)[TS][TS][3]) buffer; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // lab = (short (*) [TS][3])(buffer + TS*TS*(ndir*6)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // drv = (float (*)[TS][TS]) (buffer + TS*TS*(ndir*6+6)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // homo = (char (*)[TS][TS]) (buffer + TS*TS*(ndir*10+6)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // > ~~ > ///* Map a green hexagon around each non-green pixel and vice versa: */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (row=0; row < 3; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (col=0; col < 3; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (ng=d=0; d < 10; d+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // g = fcol(row,col) == 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (fcol(row+orth[d],col+orth[d+2]) == 1) ng=0; else ng++; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (ng == 4) { sgrow = row; sgcol = col; } > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (ng == g+1) FORC(8) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // v = orth[d ]*patt[g][c*2] + orth[d+1]*patt[g][c*2+1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // h = orth[d+2]*patt[g][c*2] + orth[d+3]*patt[g][c*2+1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // allhex[row][col][0][c^(g*2 & d)] = h + v*width; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // allhex[row][col][1][c^(g*2 & d)] = h + v*TS; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~ > // } > ~~~~~~~~~ > // > ~~ > ///* Set green1 and green3 to the minimum and maximum allowed values: */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (row=2; row < height-2; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (min=~(max=0), col=2; col < width-2; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (fcol(row,col) == 1 && (min=~(max=0))) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // pix = image + row*width + col; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // hex = allhex[row % 3][col % 3][0]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (!max) FORC(6) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // val = pix[hex[c]][1]; > ~~~~~~~~~~~~~~~~~~~~~~~~ > // if (min > val) min = val; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (max < val) max = val; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~~ > // pix[0][1] = min; > ~~~~~~~~~~~~~~~~~~~~~~~~ > // pix[0][3] = max; > ~~~~~~~~~~~~~~~~~~~~~~~~ > // switch ((row-sgrow) % 3) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // case 1: if (row < height-3) { row++; col--; } break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // case 2: if ((min=~(max=0)) && (col+=2) < width-3 && row > 2) row--; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~~ > // } > ~~~~~~~ > // > ~~ > // for (top=3; top < height-19; top += TS-16) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (left=3; left < width-19; left += TS-16) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // mrow = MIN (top+TS, height-3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // mcol = MIN (left+TS, width-3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (row=top; row < mrow; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (col=left; col < mcol; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // memcpy (rgb[0][row-top][col-left], image[row*width+col], 6); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // FORC3 memcpy (rgb[c+1], rgb[0], sizeof *rgb); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // > ~~ > ///* Interpolate green horizontally, vertically, and along both diagonals: */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (row=top; row < mrow; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (col=left; col < mcol; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if ((f = fcol(row,col)) == 1) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // pix = image + row*width + col; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // hex = allhex[row % 3][col % 3][0]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // color[1][0] = 174 * (pix[ hex[1]][1] + pix[ hex[0]][1]) - > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // 46 * (pix[2*hex[1]][1] + pix[2*hex[0]][1]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // color[1][1] = 223 * pix[ hex[3]][1] + pix[ hex[2]][1] * 33 + > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // 92 * (pix[ 0 ][f] - pix[ -hex[2]][f]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // FORC(2) color[1][2+c] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // 164 * pix[hex[4+c]][1] + 92 * pix[-2*hex[4+c]][1] + 33 * > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // (2*pix[0][f] - pix[3*hex[4+c]][f] - pix[-3*hex[4+c]][f]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // FORC4 rgb[c^!((row-sgrow) % 3)][row-top][col-left][1] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // LIM(color[1][c] >> 8,pix[0][1],pix[0][3]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~ > // > ~~ > // for (pass=0; pass < passes; pass++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (pass == 1) > ~~~~~~~~~~~~~~~~~ > // memcpy (rgb+=4, buffer, 4*sizeof *rgb); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // > ~~ > ///* Recalculate green from interpolated values of closer pixels: */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (pass) { > ~~~~~~~~~~~~~~ > // for (row=top+2; row < mrow-2; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (col=left+2; col < mcol-2; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if ((f = fcol(row,col)) == 1) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // pix = image + row*width + col; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // hex = allhex[row % 3][col % 3][1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (d=3; d < 6; d++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // rix = &rgb[(d-2)^!((row-sgrow) % 3)][row-top][col-left]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // val = rix[-2*hex[d]][1] + 2*rix[hex[d]][1] > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // - rix[-2*hex[d]][f] - 2*rix[hex[d]][f] + 3*rix[0][f]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // rix[0][1] = LIM(val/3,pix[0][1],pix[0][3]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~~~ > // } > ~~~~~~~~ > // } > ~~~~ > // > ~~ > ///* Interpolate red and blue values for solitary green pixels: */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (row=(top-sgrow+4)/3*3+sgrow; row < mrow-2; row+=3) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (col=(left-sgcol+4)/3*3+sgcol; col < mcol-2; col+=3) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // rix = &rgb[0][row-top][col-left]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // h = fcol(row,col+1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // memset (diff, 0, sizeof diff); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (i=1, d=0; d < 6; d++, i^=TS^1, h^=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (c=0; c < 2; c++, h^=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // g = 2*rix[0][1] - rix[i<<c][1] - rix[-i<<c][1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // color[h][d] = g + rix[i<<c][h] + rix[-i<<c][h]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (d > 1) > ~~~~~~~~~~~~~~ > // diff[d] += SQR (rix[i<<c][1] - rix[-i<<c][1] > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // - rix[i<<c][h] + rix[-i<<c][h]) + SQR(g); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~~~ > // if (d > 1 && (d & 1)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (diff[d-1] < diff[d]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // FORC(2) color[c*2][d] = color[c*2][d-1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (d < 2 || (d & 1)) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // FORC(2) rix[0][c*2] = CLIP(color[c*2][d]/2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // rix += TS*TS; > ~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~~~ > // } > ~~~~~~~~ > // } > ~~~~~~ > // > ~~ > ///* Interpolate red for blue pixels and vice versa: */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (row=top+3; row < mrow-3; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (col=left+3; col < mcol-3; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if ((f = 2-fcol(row,col)) == 1) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // rix = &rgb[0][row-top][col-left]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // c = (row-sgrow) % 3 ? TS:1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // h = 3 * (c ^ TS ^ 1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (d=0; d < 4; d++, rix += TS*TS) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // i = d > 1 || ((d ^ c) & 1) || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // ((ABS(rix[0][1]-rix[c][1])+ABS(rix[0][1]-rix[-c][1])) < > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // 2*(ABS(rix[0][1]-rix[h][1])+ABS(rix[0][1]-rix[-h][1]))) ? c:h; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // rix[0][f] = CLIP((rix[i][f] + rix[-i][f] + > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // 2*rix[0][1] - rix[i][1] - rix[-i][1])/2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~ > // } > ~~~~~~ > // > ~~ > ///* Fill in red and blue for 2x2 blocks of green: */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (row=top+2; row < mrow-2; row++) if ((row-sgrow) % 3) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (col=left+2; col < mcol-2; col++) if ((col-sgcol) % 3) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // rix = &rgb[0][row-top][col-left]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // hex = allhex[row % 3][col % 3][1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (d=0; d < ndir; d+=2, rix += TS*TS) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (hex[d] + hex[d+1]) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // g = 3*rix[0][1] - 2*rix[hex[d]][1] - rix[hex[d+1]][1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (c=0; c < 4; c+=2) rix[0][c] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // CLIP((g + 2*rix[hex[d]][c] + rix[hex[d+1]][c])/3); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } else { > ~~~~~~~~~~~~~~~~~ > // g = 2*rix[0][1] - rix[hex[d]][1] - rix[hex[d+1]][1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (c=0; c < 4; c+=2) rix[0][c] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // CLIP((g + rix[hex[d]][c] + rix[hex[d+1]][c])/2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~~~ > // } > ~~~~~~ > // } > ~~~~~~~~~ > // rgb = (ushort(*)[TS][TS][3]) buffer; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // mrow -= top; > ~~~~~~~~~~~~~~~~~~~~ > // mcol -= left; > ~~~~~~~~~~~~~~~~~~~~~ > // > ~~ > ///* Convert to CIELab and differentiate in all directions: */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (d=0; d < ndir; d++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (row=2; row < mrow-2; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (col=2; col < mcol-2; col++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // cielab (rgb[d][row][col], lab[row][col]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (f=dir[d & 3],row=3; row < mrow-3; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (col=3; col < mcol-3; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // lix = &lab[row][col]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // g = 2*lix[0][0] - lix[f][0] - lix[-f][0]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // drv[d][row][col] = SQR(g) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // + SQR((2*lix[0][1] - lix[f][1] - lix[-f][1] + g*500/232)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // + SQR((2*lix[0][2] - lix[f][2] - lix[-f][2] - g*500/580)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~ > // } > ~~~~~~~~~ > // > ~~ > ///* Build homogeneity maps from the derivatives: */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // memset(homo, 0, ndir*TS*TS); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (row=4; row < mrow-4; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (col=4; col < mcol-4; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (tr=FLT_MAX, d=0; d < ndir; d++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (tr > drv[d][row][col]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // tr = drv[d][row][col]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > // tr *= 8; > ~~~~~~~~~~~~~ > // for (d=0; d < ndir; d++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (v=-1; v <= 1; v++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (h=-1; h <= 1; h++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (drv[d][row+v][col+h] <= tr) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // homo[d][row][col]++; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~ > // > ~~ > ///* Average the most homogenous pixels for the final result: */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (height-top < TS+4) mrow = height-top+2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (width-left < TS+4) mcol = width-left+2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (row = MIN(top,8); row < mrow-8; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (col = MIN(left,8); col < mcol-8; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (d=0; d < ndir; d++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (hm[d]=0, v=-2; v <= 2; v++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (h=-2; h <= 2; h++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // hm[d] += homo[d][row+v][col+h]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (d=0; d < ndir-4; d++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (hm[d] < hm[d+4]) hm[d ] = 0; else > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (hm[d] > hm[d+4]) hm[d+4] = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (max=hm[0],d=1; d < ndir; d++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (max < hm[d]) max = hm[d]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // max -= max >> 3; > ~~~~~~~~~~~~~~~~~~~~~ > // memset (avg, 0, sizeof avg); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (d=0; d < ndir; d++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (hm[d] >= max) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > // FORC3 avg[c] += rgb[d][row][col][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // avg[3]++; > ~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~ > // FORC3 image[(row+top)*width+col+left][c] = avg[c]/avg[3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~ > // } > ~~~~~~~ > // free(buffer); > ~~~~~~~~~~~~~~~~~ > // border_interpolate(8); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > //} > ~~~ > //#undef fcol > ~~~~~~~~~~~~~ > // > ~~ > // > ~~ > //#undef TS > ~~~~~~~~~~~ > > > //void CLASS median_filter() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > //{ > ~~~ > // ushort (*pix)[4]; > ~~~~~~~~~~~~~~~~~~~~~ > // int pass, c, i, j, k, med[9]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // static const uchar opt[] = /* Optimal 9-element median search */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // { 1,2, 4,5, 7,8, 0,1, 3,4, 6,7, 1,2, 4,5, 7,8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // 0,3, 5,8, 4,7, 3,6, 1,4, 2,5, 4,7, 4,2, 6,4, 4,2 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // > ~~ > // for (pass=1; pass <= med_passes; pass++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (verbose) > ~~~~~~~~~~~~~~~~~~ > // fprintf (stderr,_("Median filter pass %d...\n"), pass); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (c=0; c < 3; c+=2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (pix = image; pix < image+width*height; pix++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // pix[0][3] = pix[0][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (pix = image+width; pix < image+width*(height-1); pix++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if ((pix-image+1) % width < 2) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (k=0, i = -width; i <= width; i += width) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (j = i-1; j <= i+1; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // med[k++] = pix[j][3] - pix[j][1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (i=0; i < sizeof opt; i+=2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (med[opt[i]] > med[opt[i+1]]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // SWAP (med[opt[i]] , med[opt[i+1]]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // pix[0][c] = CLIP(med[4] + pix[0][1]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~~ > // } > ~~~~~~~ > // } > ~~~~~ > //} > ~~~ > // > ~~ > //void CLASS blend_highlights() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > //{ > ~~~ > // int clip=INT_MAX, row, col, c, i, j; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // static const float trans[2][4][4] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // { { { 1,1,1 }, { 1.7320508,-1.7320508,0 }, { -1,-1,2 } }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // static const float itrans[2][4][4] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // { { { 1,0.8660254,-0.5 }, { 1,-0.8660254,-0.5 }, { 1,0,1 } }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // float cam[2][4], lab[2][4], sum[2], chratio; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // > ~~ > // if ((unsigned) (colors-3) > 1) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (verbose) fprintf (stderr,_("Blending highlights...\n")); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // FORCC if (clip > (i = 65535*pre_mul[c])) clip = i; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (row=0; row < height; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (col=0; col < width; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // FORCC if (image[row*width+col][c] > clip) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (c == colors) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // FORCC { > ~~~~~~~~~~~~~~~ > // cam[0][c] = image[row*width+col][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // cam[1][c] = MIN(cam[0][c],clip); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~~ > // for (i=0; i < 2; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // FORCC for (lab[i][c]=j=0; j < colors; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // lab[i][c] += trans[colors-3][c][j] * cam[i][j]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (sum[i]=0,c=1; c < colors; c++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // sum[i] += SQR(lab[i][c]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~~ > // chratio = sqrt(sum[1]/sum[0]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (c=1; c < colors; c++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // lab[0][c] *= chratio; > ~~~~~~~~~~~~~~~~~~~~~~~~ > // FORCC for (cam[0][c]=j=0; j < colors; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // cam[0][c] += itrans[colors-3][c][j] * lab[0][j]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // FORCC image[row*width+col][c] = cam[0][c] / colors; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~ > //} > ~~~ > // > ~~ > //#define SCALE (4 >> shrink) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > //void CLASS recover_highlights() > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > //{ > ~~~ > // float *map, sum, wgt, grow; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // int hsat[4], count, spread, change, val, i; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // unsigned high, wide, mrow, mcol, row, col, kc, c, d, y, x; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // ushort *pixel; > ~~~~~~~~~~~~~~~~~~ > // static const signed char dir[8][2] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // { {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // > ~~ > // if (verbose) fprintf (stderr,_("Rebuilding highlights...\n")); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // > ~~ > // grow = pow (2, 4-highlight); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // FORCC hsat[c] = 32000 * pre_mul[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (kc=0, c=1; c < colors; c++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (pre_mul[kc] < pre_mul[c]) kc = c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // high = height / SCALE; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > // wide = width / SCALE; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > // map = (float *) calloc (high, wide*sizeof *map); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // merror (map, "recover_highlights()"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // FORCC if (c != kc) { > ~~~~~~~~~~~~~~~~~~~~~~~~ > // memset (map, 0, high*wide*sizeof *map); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (mrow=0; mrow < high; mrow++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (mcol=0; mcol < wide; mcol++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // sum = wgt = count = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // pixel = image[row*width+col]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (pixel[c] / hsat[c] == 1 && pixel[kc] > 24000) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // sum += pixel[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > // wgt += pixel[kc]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > // count++; > ~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~ > // } > ~~~~~~ > // if (count == SCALE*SCALE) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // map[mrow*wide+mcol] = sum / wgt; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~~ > // for (spread = 32/grow; spread--; ) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (mrow=0; mrow < high; mrow++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (mcol=0; mcol < wide; mcol++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (map[mrow*wide+mcol]) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // sum = count = 0; > ~~~~~~~~~~~~~~~~~~~~~ > // for (d=0; d < 8; d++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // y = mrow + dir[d][0]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // x = mcol + dir[d][1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (y < high && x < wide && map[y*wide+x] > 0) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // sum += (1 + (d & 1)) * map[y*wide+x]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // count += 1 + (d & 1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~ > // } > ~~~~~~ > // if (count > 3) > ~~~~~~~~~~~~~~~~~~~ > // map[mrow*wide+mcol] = - (sum+grow) / (count+grow); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~ > // for (change=i=0; i < high*wide; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (map[i] < 0) { > ~~~~~~~~~~~~~~~~~~~~ > // map[i] = -map[i]; > ~~~~~~~~~~~~~~~~~~~~~~ > // change = 1; > ~~~~~~~~~~~~~~~~ > // } > ~~~~ > // if (!change) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~ > // for (i=0; i < high*wide; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (map[i] == 0) map[i] = 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (mrow=0; mrow < high; mrow++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (mcol=0; mcol < wide; mcol++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // pixel = image[row*width+col]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (pixel[c] / hsat[c] > 1) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // val = pixel[kc] * map[mrow*wide+mcol]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // if (pixel[c] < val) pixel[c] = CLIP(val); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > // } > ~~~~~~~~ > // } > ~~~~~~ > // } > ~~~~~~~~~ > // } > ~~~~~ > // free (map); > ~~~~~~~~~~~~~~~ > //} > ~~~ > //#undef SCALE > ~~~~~~~~~~~~~~ > > > void CLASS tiff_get (unsigned base, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unsigned *tag, unsigned *type, unsigned *len, unsigned *save) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > *tag = get2(); > ~~~~~~~~~~~~~~~ > *type = get2(); > ~~~~~~~~~~~~~~~ > *len = get4(); > ~~~~~~~~~~~~~~~ > *save = ftell(ifp) + 4; > ~~~~~~~~~~~~~~~~~~~~~~~ > if (*len * ("11124811248484"[*type < 14 ? *type:0]-'0') > 4) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, get4()+base, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned entries, tag, type, len, save; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > entries = get2(); > ~~~~~~~~~~~~~~~~~ > while (entries--) { > ~~~~~~~~~~~~~~~~~~~ > tiff_get (base, &tag, &type, &len, &save); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == toff) thumb_offset = get4()+base; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == tlen) thumb_length = get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, save, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > /*RT int CLASS parse_tiff_ifd (int base);*/ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > void CLASS parse_makernote (int base, int uptag) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const uchar xlat[2][256] = { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unsigned offset=0, entries, tag, type, len, save, c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0}; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > uchar buf97[324], ci, cj, ck; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > short morder, sorder=order; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > char buf[10]; > ~~~~~~~~~~~~~ > /* > ~~ > The MakerNote might have its own TIFF header (possibly with > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > its own byte-order!), or it might just be a table. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > if (!strcmp(make,"Nokia")) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (buf, 1, 10, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (!strncmp (buf,"KDK" ,3) || /* these aren't TIFF tables */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > !strncmp (buf,"VER" ,3) || > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > !strncmp (buf,"IIII",4) || > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > !strncmp (buf,"MMMM",4)) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!strncmp (buf,"KC" ,2) || /* Konica KD-400Z, KD-510Z */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > !strncmp (buf,"MLY" ,3)) { /* Minolta DiMAGE G series */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > order = 0x4d4d; > ~~~~~~~~~~~~~~~ > while ((i=ftell(ifp)) < data_offset && i < 16384) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > wb[0] = wb[2]; wb[2] = wb[1]; wb[1] = wb[3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > wb[3] = get2(); > ~~~~~~~~~~~~~~~ > if (wb[1] == 256 && wb[3] == 256 && > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 cam_mul[c] = wb[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > goto quit; > ~~~~~~~~~~ > } > ~ > if (!strcmp (buf,"Nikon")) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > base = ftell(ifp); > ~~~~~~~~~~~~~~~~~~ > order = get2(); > ~~~~~~~~~~~~~~~ > if (get2() != 42) goto quit; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > offset = get4(); > ~~~~~~~~~~~~~~~~ > fseek (ifp, offset-8, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else if (!strcmp (buf,"OLYMPUS") || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > !strcmp (buf,"PENTAX ")) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > base = ftell(ifp)-10; > ~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, -2, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > order = get2(); > ~~~~~~~~~~~~~~~ > if (buf[0] == 'O') get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else if (!strncmp (buf,"SONY",4) || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > !strcmp (buf,"Panasonic")) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > goto nf; > ~~~~~~~~ > } else if (!strncmp (buf,"FUJIFILM",8)) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > base = ftell(ifp)-10; > ~~~~~~~~~~~~~~~~~~~~~ > nf: order = 0x4949; > ~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 2, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else if (!strcmp (buf,"OLYMP") || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > !strcmp (buf,"LEICA") || > ~~~~~~~~~~~~~~~~~~~~~~~~ > !strcmp (buf,"Ricoh") || > ~~~~~~~~~~~~~~~~~~~~~~~~ > !strcmp (buf,"EPSON")) > ~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, -2, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > else if (!strcmp (buf,"AOC") || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > !strcmp (buf,"QVC")) > ~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, -4, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > else { > ~~~~~~ > fseek (ifp, -10, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!strncmp(make,"SAMSUNG",7)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > base = ftell(ifp); > ~~~~~~~~~~~~~~~~~~ > } > ~ > entries = get2(); > ~~~~~~~~~~~~~~~~~ > if (entries > 1000) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > morder = order; > ~~~~~~~~~~~~~~~ > while (entries--) { > ~~~~~~~~~~~~~~~~~~~ > order = morder; > ~~~~~~~~~~~~~~~ > tiff_get (base, &tag, &type, &len, &save); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tag |= uptag << 16; > ~~~~~~~~~~~~~~~~~~~ > if (tag == 2 && strstr(make,"NIKON") && !iso_speed) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > iso_speed = (get2(),get2()); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((tag == 0x25 || tag == 0x28) && strstr(make,"NIKON") && !iso_speed) { // Nikon ISOInfo Tags/ISO & ISO2 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > uchar iso[1]; > ~~~~~~~~~~~~~ > fread (iso, 1, 1, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~ > iso_speed = 100 * pow(2,(float)iso[0]/12.0-5); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (tag == 4 && len > 26 && len < 35) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((i=(get4(),get2())) != 0x7fff && !iso_speed) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > iso_speed = 50 * pow (2, i/32.0 - 4); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((i=(get2(),get2())) != 0x7fff && !aperture) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > aperture = pow (2, i/64.0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((i=get2()) != 0xffff && !shutter) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > shutter = pow (2, (short) i/-32.0); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > wbi = (get2(),get2()); > ~~~~~~~~~~~~~~~~~~~~~~ > shot_order = (get2(),get2()); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if ((tag == 4 || tag == 0x114) && !strncmp(make,"KONICA",6)) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, tag == 4 ? 140:160, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > switch (get2()) { > ~~~~~~~~~~~~~~~~~ > case 72: flip = 0; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 76: flip = 6; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 82: flip = 5; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > if (tag == 7 && type == 2 && len > 20) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fgets (model2, 64, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 8 && type == 4) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > shot_order = get4(); > ~~~~~~~~~~~~~~~~~~~~ > if (tag == 9 && !strcmp(make,"Canon")) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (artist, 64, 1, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0xc && len == 4) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 cam_mul[(c << 1 | c >> 1) & 3] = getreal(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0xd && type == 7 && get2() == 0xaaaa) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (c=i=2; (ushort) c != 0xbbbb && i < len; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > c = c << 8 | fgetc(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~ > while ((i+=4) < len-5) > ~~~~~~~~~~~~~~~~~~~~~~ > if (get4() == 257 && (i=len) && (c = (get4(),fgetc(ifp))) < 3) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > flip = "065"[c]-'0'; > ~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (tag == 0x10 && type == 4) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unique_id = get4(); > ~~~~~~~~~~~~~~~~~~~ > if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, get4()+base, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > parse_tiff_ifd (base); > ~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (tag == 0x14 && type == 7) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (len == 2560) { > ~~~~~~~~~~~~~~~~~~ > fseek (ifp, 1248, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > goto get2_256; > ~~~~~~~~~~~~~~ > } > ~ > fread (buf, 1, 10, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (!strncmp(buf,"NRW ",4)) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, strcmp(buf+4,"0100") ? 46:1546, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cam_mul[0] = get4() << 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > cam_mul[1] = get4() + get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cam_mul[2] = get4() << 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > //if (tag == 0x15 && type == 2 && is_raw) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0x15 && type == 2 && is_raw && strstr(model, "Hasselblad ") != model) // RT: don't overwrite already parsed Hasselblad model > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (model, 64, 1, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (strstr(make,"PENTAX")) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0x1b) tag = 0x1018; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0x1c) tag = 0x1017; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (tag == 0x19 && !strcmp(make,"Hasselblad") && len == 0x300000) { // RT > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > parse_hasselblad_gain(); // RT > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } // RT > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0x1d) > ~~~~~~~~~~~~~~~~ > while ((c = fgetc(ifp)) && c != EOF) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > serial = serial*10 + (isdigit(c) ? c - '0' : c % 10); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0x29 && type == 1) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 8 + c*32, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (tag == 0x3d && type == 3 && len == 4) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 cblack[c ^ c >> 1] = get2() >> (14-tiff_bps); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0x81 && type == 4) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > data_offset = get4(); > ~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, data_offset + 41, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > raw_height = get2() * 2; > ~~~~~~~~~~~~~~~~~~~~~~~~ > raw_width = get2(); > ~~~~~~~~~~~~~~~~~~~~ > filters = 0x61616161; > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if ((tag == 0x81 && type == 7) || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (tag == 0x100 && type == 7) || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (tag == 0x280 && type == 1)) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > thumb_offset = ftell(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > thumb_length = len; > ~~~~~~~~~~~~~~~~~~~ > } > ~ > if (tag == 0x88 && type == 4 && (thumb_offset = get4())) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > thumb_offset += base; > ~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0x89 && type == 4) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > thumb_length = get4(); > ~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0x8c || tag == 0x96) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > meta_offset = ftell(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0x97) { > ~~~~~~~~~~~~~~~~~~ > for (i=0; i < 4; i++) > ~~~~~~~~~~~~~~~~~~~~~ > ver97 = ver97 * 10 + fgetc(ifp)-'0'; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > switch (ver97) { > ~~~~~~~~~~~~~~~~ > case 100: > ~~~~~~~~~ > fseek (ifp, 68, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 102: > ~~~~~~~~~ > fseek (ifp, 6, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 cam_mul[c ^ (c >> 1)] = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 103: > ~~~~~~~~~ > fseek (ifp, 16, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 cam_mul[c] = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (ver97 >= 200) { > ~~~~~~~~~~~~~~~~~~~ > if (ver97 != 205) fseek (ifp, 280, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (buf97, 324, 1, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > if (tag == 0xa1 && type == 7) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > order = 0x4949; > ~~~~~~~~~~~~~~~ > fseek (ifp, 140, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 cam_mul[c] = get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (tag == 0xa4 && type == 3) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, wbi*48, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 cam_mul[c] = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (tag == 0xa7 && (unsigned) (ver97-200) < 17) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ci = xlat[0][serial & 0xff]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ck = 0x60; > ~~~~~~~~~~ > for (i=0; i < 324; i++) > ~~~~~~~~~~~~~~~~~~~~~~~ > buf97[i] ^= (cj += ci * ck++); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = "66666>666;6A;:;55"[ver97-200] - '0'; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sget2 (buf97 + (i & -2) + c*2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (tag == 0x200 && len == 3) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > shot_order = (get4(),get4()); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0x200 && len == 4) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 cblack[c ^ c >> 1] = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0x201 && len == 4) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 cam_mul[c ^ (c >> 1)] = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0x220 && type == 7) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > meta_offset = ftell(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0x401 && type == 4 && len == 4) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 cblack[c ^ c >> 1] = get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0xe01) { /* Nikon Capture Note */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > order = 0x4949; > ~~~~~~~~~~~~~~~ > fseek (ifp, 22, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (offset=22; offset+22 < len; offset += 22+i) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tag = get4(); > ~~~~~~~~~~~~~ > fseek (ifp, 14, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = get4()-4; > ~~~~~~~~~~~~~ > if (tag == 0x76a43207) flip = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else fseek (ifp, i, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > if (tag == 0xe80 && len == 256 && type == 7) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 48, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > cam_mul[0] = get2() * 508 * 1.078 / 0x10000; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cam_mul[2] = get2() * 382 * 1.173 / 0x10000; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (tag == 0xf00 && type == 7) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (len == 614) > ~~~~~~~~~~~~~~~ > fseek (ifp, 176, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else if (len == 734 || len == 1502) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 148, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else goto next; > ~~~~~~~~~~~~~~~ > goto get2_256; > ~~~~~~~~~~~~~~ > } > ~ > if ((tag == 0x1011 && len == 9) || tag == 0x20400200) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 3; i++) > ~~~~~~~~~~~~~~~~~~~~~ > FORC3 cmatrix[i][c] = ((short) get2()) / 256.0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((tag == 0x1012 || tag == 0x20400600) && len == 4) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 cblack[c ^ c >> 1] = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0x1017 || tag == 0x20400100) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cam_mul[0] = get2() / 256.0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0x1018 || tag == 0x20400100) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cam_mul[2] = get2() / 256.0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0x2011 && len == 2) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > get2_256: > ~~~~~~~~~ > order = 0x4d4d; > ~~~~~~~~~~~~~~~ > cam_mul[0] = get2() / 256.0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cam_mul[2] = get2() / 256.0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if ((tag | 0x70) == 0x2070 && (type == 4 || type == 13)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, get4()+base, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0x2020 && !strncmp(buf,"OLYMP",5)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > parse_thumb_note (base, 257, 258); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0x2040) > ~~~~~~~~~~~~~~~~~~ > parse_makernote (base, 0x2040); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0xb028) { > ~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, get4()+base, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > parse_thumb_note (base, 136, 137); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (tag == 0x4001 && len > 500) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, i, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 cam_mul[c ^ (c >> 1)] = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i+=18; i <= len; i+=10) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > get2(); > ~~~~~~~ > FORC4 sraw_mul[c ^ (c >> 1)] = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (sraw_mul[1] == 1170) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > if (tag == 0x4021 && get4() && get4()) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 cam_mul[c] = 1024; > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0xa021) > ~~~~~~~~~~~~~~~~~~ > FORC4 cam_mul[c ^ (c >> 1)] = get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0xa028) > ~~~~~~~~~~~~~~~~~~ > FORC4 cam_mul[c ^ (c >> 1)] -= get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 0xb001) > ~~~~~~~~~~~~~~~~~~ > unique_id = get2(); > ~~~~~~~~~~~~~~~~~~~ > next: > ~~~~~ > fseek (ifp, save, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > quit: > ~~~~~ > order = sorder; > ~~~~~~~~~~~~~~~ > } > ~ > > > /* > ~~ > Since the TIFF DateTime string has no timezone information, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > assume that the camera's clock was set to Universal Time. > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > */ > ~~ > void CLASS get_timestamp (int reversed) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > struct tm t; > ~~~~~~~~~~~~ > char str[20]; > ~~~~~~~~~~~~~ > int i; > ~~~~~~ > > > str[19] = 0; > ~~~~~~~~~~~~ > if (reversed) > ~~~~~~~~~~~~~ > for (i=19; i--; ) str[i] = fgetc(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > else > ~~~~ > fread (str, 19, 1, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~ > memset (&t, 0, sizeof t); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > if (sscanf (str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return; > ~~~~~~~ > t.tm_year -= 1900; > ~~~~~~~~~~~~~~~~~~ > t.tm_mon -= 1; > ~~~~~~~~~~~~~~ > t.tm_isdst = -1; > ~~~~~~~~~~~~~~~~ > if (mktime(&t) > 0) > ~~~~~~~~~~~~~~~~~~~ > timestamp = mktime(&t); > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS parse_exif (int base) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned kodak, entries, tag, type, len, save, c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > double expo; > ~~~~~~~~~~~~ > > > kodak = !strncmp(make,"EASTMAN",7) && tiff_nifds < 3; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > entries = get2(); > ~~~~~~~~~~~~~~~~~ > while (entries--) { > ~~~~~~~~~~~~~~~~~~~ > tiff_get (base, &tag, &type, &len, &save); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > switch (tag) { > ~~~~~~~~~~~~~~ > case 33434: tiff_ifd[tiff_nifds-1].shutter = shutter = getreal(type); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 33437: aperture = getreal(type); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 34855: iso_speed = get2(); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 34866: if((!iso_speed) || iso_speed == 65535) iso_speed = get4();break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 36867: > ~~~~~~~~~~~ > case 36868: get_timestamp(0); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 37377: if ((expo = -getreal(type)) < 128) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[tiff_nifds-1].shutter = > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > shutter = pow (2, expo); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 37378: aperture = pow (2, getreal(type)/2); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 37386: focal_len = getreal(type); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 37500: parse_makernote (base, 0); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 40962: if (kodak) raw_width = get4(); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 40963: if (kodak) raw_height = get4(); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 41730: > ~~~~~~~~~~~ > if (get4() == 0x20002) > ~~~~~~~~~~~~~~~~~~~~~~ > for (exif_cfa=c=0; c < 8; c+=2) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > exif_cfa |= fgetc(ifp) * 0x01010101 << c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > fseek (ifp, save, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS parse_gps (int base) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned entries, tag, type, len, save, c; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > entries = get2(); > ~~~~~~~~~~~~~~~~~ > while (entries--) { > ~~~~~~~~~~~~~~~~~~~ > tiff_get (base, &tag, &type, &len, &save); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > switch (tag) { > ~~~~~~~~~~~~~~ > case 1: case 3: case 5: > ~~~~~~~~~~~~~~~~~~~~~~~ > gpsdata[29+tag/2] = getc(ifp); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 2: case 4: case 7: > ~~~~~~~~~~~~~~~~~~~~~~~ > FORC(6) gpsdata[tag/3*6+c] = get4(); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 6: > ~~~~~~~ > FORC(2) gpsdata[18+c] = get4(); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 18: case 29: > ~~~~~~~~~~~~~~~~~ > fgets ((char *) (gpsdata+14+tag/3), MIN(len,12), ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > fseek (ifp, save, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > void CLASS romm_coeff (float romm_cam[3][3]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { { 2.034193, -0.727420, -0.306766 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -0.228811, 1.231729, -0.002922 }, > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { -0.008565, -0.153273, 1.161839 } }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int i, j, k; > ~~~~~~~~~~~~ > > > for (i=0; i < 3; i++) > ~~~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 3; j++) > ~~~~~~~~~~~~~~~~~~~~~ > for (cmatrix[i][j] = k=0; k < 3; k++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS parse_mos (int offset) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > char data[40]; > ~~~~~~~~~~~~~~ > int skip, from, i, c, neut[4], planes=0, frot=0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > static const char *mod[] = > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22", > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65", > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7", > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > "AFi-II 7","Aptus-II 7","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5", > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > "","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float romm_cam[3][3]; > ~~~~~~~~~~~~~~~~~~~~~ > > > fseek (ifp, offset, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (1) { > ~~~~~~~~~~~ > if (get4() != 0x504b5453) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > get4(); > ~~~~~~~ > fread (data, 1, 40, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > skip = get4(); > ~~~~~~~~~~~~~~ > from = ftell(ifp); > ~~~~~~~~~~~~~~~~~~ > if (!strcmp(data,"JPEG_preview_data")) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > thumb_offset = from; > ~~~~~~~~~~~~~~~~~~~~ > thumb_length = skip; > ~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (!strcmp(data,"icc_camera_profile")) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > profile_offset = from; > ~~~~~~~~~~~~~~~~~~~~~~ > profile_length = skip; > ~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (!strcmp(data,"ShootObj_back_type")) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fscanf (ifp, "%d", &i); > ~~~~~~~~~~~~~~~~~~~~~~~ > if ((unsigned) i < sizeof mod / sizeof (*mod)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > strcpy (model, mod[i]); > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (!strcmp(data,"icc_camera_to_tone_matrix")) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 9; i++) > ~~~~~~~~~~~~~~~~~~~~~ > ((float *)romm_cam)[i] = int_to_float(get4()); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > romm_coeff (romm_cam); > ~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (!strcmp(data,"CaptProf_color_matrix")) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 9; i++) > ~~~~~~~~~~~~~~~~~~~~~ > fscanf (ifp, "%f", (float *)romm_cam + i); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > romm_coeff (romm_cam); > ~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (!strcmp(data,"CaptProf_number_of_planes")) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fscanf (ifp, "%d", &planes); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!strcmp(data,"CaptProf_raw_data_rotation")) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fscanf (ifp, "%d", &flip); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!strcmp(data,"CaptProf_mosaic_pattern")) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 { > ~~~~~~~ > fscanf (ifp, "%d", &i); > ~~~~~~~~~~~~~~~~~~~~~~~ > if (i == 1) frot = c ^ (c >> 1); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (!strcmp(data,"ImgProf_rotation_angle")) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fscanf (ifp, "%d", &i); > ~~~~~~~~~~~~~~~~~~~~~~~ > flip = i - flip; > ~~~~~~~~~~~~~~~~ > } > ~ > if (!strcmp(data,"NeutObj_neutrals") && !cam_mul[0]) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 fscanf (ifp, "%d", neut+c); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 cam_mul[c] = (float) neut[0] / neut[c+1]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (!strcmp(data,"Rows_data")) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > load_flags = get4(); > ~~~~~~~~~~~~~~~~~~~~ > parse_mos (from); > ~~~~~~~~~~~~~~~~~ > fseek (ifp, skip+from, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (planes) > ~~~~~~~~~~~ > filters = (planes == 1) * 0x01010101 * > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (uchar) "\x94\x61\x16\x49"[(flip/90 + frot) & 3]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS linear_table (unsigned len) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > int i; > ~~~~~~ > if (len > 0x1000) len = 0x1000; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > read_shorts (curve, len); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=len; i < 0x1000; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > curve[i] = curve[i-1]; > ~~~~~~~~~~~~~~~~~~~~~~ > maximum = curve[0xfff]; > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > > > void CLASS parse_kodak_ifd (int base) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned entries, tag, type, len, save; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int i, c, wbi=-2, wbtemp=6500; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > float mul[3]={1,1,1}, num; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > static const int wbtag[] = { 64037,64040,64039,64041,-1,-1,64042 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > entries = get2(); > ~~~~~~~~~~~~~~~~~ > if (entries > 1024) return; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (entries--) { > ~~~~~~~~~~~~~~~~~~~ > tiff_get (base, &tag, &type, &len, &save); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 1020) wbi = getint(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 1021 && len == 72) { /* WB set in software */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 40, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 cam_mul[c] = 2048.0 / get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > wbi = -2; > ~~~~~~~~~ > } > ~ > if (tag == 2118) wbtemp = getint(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 2120 + wbi && wbi >= 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 cam_mul[c] = 2048.0 / getreal(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 2130 + wbi) > ~~~~~~~~~~~~~~~~~~~~~~ > FORC3 mul[c] = getreal(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 2140 + wbi && wbi >= 0) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 { > ~~~~~~~ > for (num=i=0; i < 4; i++) > ~~~~~~~~~~~~~~~~~~~~~~~~~ > num += getreal(type) * pow (wbtemp/100.0, i); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cam_mul[c] = 2048 / (num * mul[c]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (tag == 2317) linear_table (len); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 6020) iso_speed = getint(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 64013) wbi = fgetc(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((unsigned) wbi < 7 && tag == wbtag[wbi]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 cam_mul[c] = get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 64019) width = getint(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tag == 64020) height = (getint(type)+1) & -2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, save, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > } > ~ > > > /*RT void CLASS parse_minolta (int base); */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > /*RT int CLASS parse_tiff (int base);*/ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > int CLASS parse_tiff_ifd (int base) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > { > ~ > unsigned entries, tag, type, len, plen=16, save; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int ifd, use_cm=0, cfa, i, j, c, ima_len=0,cm_D65=0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > char software[64], *cbuf, *cp; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > double cc[2][4][4]; > ~~~~~~~~~~~~~~~~~~~ > double cm[2][4][3] = {NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN,NAN}; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > double cam_xyz[4][3], num; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unsigned sony_curve[] = { 0,0,0,0,0,4095 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > unsigned *buf, sony_offset=0, sony_length=0, sony_key=0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > struct jhead jh; > ~~~~~~~~~~~~~~~~ > /*RT*/ IMFILE *sfp; > ~~~~~~~~~~~~~~~~~~~~ > > > if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > return 1; > ~~~~~~~~~ > ifd = tiff_nifds++; > ~~~~~~~~~~~~~~~~~~~ > for (j=0; j < 4; j++) > ~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 4; i++) > ~~~~~~~~~~~~~~~~~~~~~ > { > ~ > cc[0][j][i] = i == j; > ~~~~~~~~~~~~~~~~~~~~~ > cc[1][j][i] = i == j; > ~~~~~~~~~~~~~~~~~~~~~ > } > ~ > entries = get2(); > ~~~~~~~~~~~~~~~~~ > if (entries > 512) return 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > while (entries--) { > ~~~~~~~~~~~~~~~~~~~ > tiff_get (base, &tag, &type, &len, &save); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > switch (tag) { > ~~~~~~~~~~~~~~ > case 5: width = get2(); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 6: height = get2(); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 7: width += get2(); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 9: if ((i = get2())) filters = i; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 17: case 18: > ~~~~~~~~~~~~~~~~~ > if (type == 3 && len == 1) > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > cam_mul[(tag-17)*2] = get2() / 256.0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 23: > ~~~~~~~~ > if (type == 3) iso_speed = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 28: case 29: case 30: > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > cblack[tag-28] = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~ > cblack[3] = cblack[1]; > ~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 36: case 37: case 38: > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > cam_mul[tag-36] = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 39: > ~~~~~~~~ > if (len < 50 || cam_mul[0]) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 12, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 cam_mul[c] = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 46: > ~~~~~~~~ > if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > thumb_offset = ftell(ifp) - 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > thumb_length = len; > ~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 61440: /* Fuji HS10 table */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, get4()+base, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > parse_tiff_ifd (base); > ~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 2: case 256: case 61441: /* ImageWidth */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].width = getint(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 3: case 257: case 61442: /* ImageHeight */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].height = getint(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 258: /* BitsPerSample */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 61443: > ~~~~~~~~~~~ > tiff_ifd[ifd].samples = len & 7; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].bps = getint(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (tiff_bps < tiff_ifd[ifd].bps) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_bps = tiff_ifd[ifd].bps; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 61446: > ~~~~~~~~~~~ > raw_height = 0; > ~~~~~~~~~~~~~~~ > if (tiff_ifd[ifd].bps > 12) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > load_raw = &CLASS packed_load_raw; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > load_flags = get4() ? 24:80; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 259: /* Compression */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].comp = getint(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 262: /* PhotometricInterpretation */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].phint = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 270: /* ImageDescription */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (desc, 512, 1, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 271: /* Make */ > ~~~~~~~~~~~~~~~~~~~~~~~ > fgets (make, 64, ifp); > ~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 272: /* Model */ > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (strstr(model, "Hasselblad ") != model) // RT: if Hasselblad, only parse the first model name (otherwise it can change from say Hasselblad CFV-50 to Hasselblad CW (ie the camera body model, not the back model which we are interested in) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fgets (model, 64, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 280: /* Panasonic RW2 offset */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (type != 4) break; > ~~~~~~~~~~~~~~~~~~~~~ > load_raw = &CLASS panasonic_load_raw; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > load_flags = 0x2008; > ~~~~~~~~~~~~~~~~~~~~ > case 273: /* StripOffset */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 513: /* JpegIFOffset */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 61447: > ~~~~~~~~~~~ > tiff_ifd[ifd].offset = get4()+base; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (ljpeg_start (&jh, 1)) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].comp = 6; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].width = jh.wide; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].height = jh.high; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].bps = jh.bits; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].samples = jh.clrs; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!(jh.sraw || (jh.clrs & 1))) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].width *= jh.clrs; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((tiff_ifd[ifd].width > 4*tiff_ifd[ifd].height) & ~jh.clrs) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].width /= 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].height *= 2; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > i = order; > ~~~~~~~~~~ > parse_tiff (tiff_ifd[ifd].offset + 12); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > order = i; > ~~~~~~~~~~ > } > ~ > } > ~ > break; > ~~~~~~ > case 274: /* Orientation */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].flip = "50132467"[get2() & 7]-'0'; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 277: /* SamplesPerPixel */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].samples = getint(type) & 7; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 279: /* StripByteCounts */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 514: > ~~~~~~~~~ > case 61448: > ~~~~~~~~~~~ > tiff_ifd[ifd].bytes = get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 61454: > ~~~~~~~~~~~ > FORC3 cam_mul[(4-c) % 3] = getint(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 305: case 11: /* Software */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fgets (software, 64, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!strncmp(software,"Adobe",5) || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > !strncmp(software,"dcraw",5) || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > !strncmp(software,"UFRaw",5) || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > !strncmp(software,"Bibble",6) || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > !strncmp(software,"Nikon Scan",10) || > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > !strcmp (software,"Digital Photo Professional")) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > is_raw = 0; > ~~~~~~~~~~~ > break; > ~~~~~~ > case 306: /* DateTime */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > get_timestamp(0); > ~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 315: /* Artist */ > ~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (artist, 64, 1, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 317: /* Predictor */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].predictor = getint(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 322: /* TileWidth */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].tile_width = getint(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 323: /* TileLength */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].tile_length = getint(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 324: /* TileOffsets */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (len == 1) > ~~~~~~~~~~~~~ > tiff_ifd[ifd].tile_width = tiff_ifd[ifd].tile_length = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (len == 4) { > ~~~~~~~~~~~~~~~ > load_raw = &CLASS sinar_4shot_load_raw; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > is_raw = 5; > ~~~~~~~~~~~ > } > ~ > break; > ~~~~~~ > case 325: /* TileByteCounts */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].bytes = len > 1 ? ftell(ifp) : get4(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 330: /* SubIFDs */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > load_raw = &CLASS sony_arw_load_raw; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > data_offset = get4()+base; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > ifd++; break; > ~~~~~~~~~~~~~~ > } > ~ > while (len--) { > ~~~~~~~~~~~~~~~ > i = ftell(ifp); > ~~~~~~~~~~~~~~~ > fseek (ifp, get4()+base, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (parse_tiff_ifd (base)) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, i+4, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > break; > ~~~~~~ > case 339: > ~~~~~~~~~ > tiff_ifd[ifd].sample_format = getint(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 400: > ~~~~~~~~~ > strcpy (make, "Sarnoff"); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > maximum = 0xfff; > ~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 28688: > ~~~~~~~~~~~ > FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (i=0; i < 5; i++) > ~~~~~~~~~~~~~~~~~~~~~ > for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > curve[j] = curve[j-1] + (1 << i); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 29184: sony_offset = get4(); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 29185: sony_length = get4(); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 29217: sony_key = get4(); break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 29264: > ~~~~~~~~~~~ > parse_minolta (ftell(ifp)); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > raw_width = 0; > ~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 29443: > ~~~~~~~~~~~ > FORC4 cam_mul[c ^ (c < 2)] = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 29459: > ~~~~~~~~~~~ > FORC4 cam_mul[c] = get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = (cam_mul[1] == 1024 && cam_mul[2] == 1024) << 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > SWAP (cam_mul[i],cam_mul[i+1]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 33405: /* Model2 */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > fgets (model2, 64, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 33421: /* CFARepeatPatternDim */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (get2() == 6 && get2() == 6) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > filters = 9; > ~~~~~~~~~~~~ > break; > ~~~~~~ > case 33422: /* CFAPattern */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (filters == 9) { > ~~~~~~~~~~~~~~~~~~~ > FORC(36) ((char *)xtrans)[c] = fgetc(ifp) & 3; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > } > ~ > case 64777: /* Kodak P-series */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if ((plen=len) > 16) plen = 16; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (cfa_pat, 1, plen, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (colors=cfa=i=0; i < plen && colors < 4; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > colors += !(cfa & (1 << cfa_pat[i])); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cfa |= 1 << cfa_pat[i]; > ~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3); /* CMY */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4); /* GMCY */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > goto guess_cfa_pc; > ~~~~~~~~~~~~~~~~~~ > case 33424: > ~~~~~~~~~~~ > case 65024: > ~~~~~~~~~~~ > fseek (ifp, get4()+base, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > parse_kodak_ifd (base); > ~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 33434: /* ExposureTime */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > tiff_ifd[ifd].shutter = shutter = getreal(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 33437: /* FNumber */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > aperture = getreal(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 34306: /* Leaf white balance */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 cam_mul[c ^ 1] = 4096.0 / get2(); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 34307: /* Leaf CatchLight color matrix */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (software, 1, 7, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (strncmp(software,"MATRIX",6)) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > colors = 4; > ~~~~~~~~~~~ > for (raw_color = i=0; i < 3; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 fscanf (ifp, "%f", &rgb_cam[i][c^1]); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!use_camera_wb) continue; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > num = 0; > ~~~~~~~~ > FORC4 num += rgb_cam[i][c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 rgb_cam[i][c] /= num; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > break; > ~~~~~~ > case 34310: /* Leaf metadata */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > parse_mos (ftell(ifp)); > ~~~~~~~~~~~~~~~~~~~~~~~ > case 34303: > ~~~~~~~~~~~ > strcpy (make, "Leaf"); > ~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 34665: /* EXIF tag */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, get4()+base, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > parse_exif (base); > ~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 34853: /* GPSInfo tag */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, get4()+base, SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > parse_gps (base); > ~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 34675: /* InterColorProfile */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 50831: /* AsShotICCProfile */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > profile_offset = ftell(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > profile_length = len; > ~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 37122: /* CompressedBitsPerPixel */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > kodak_cbpp = get4(); > ~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 37386: /* FocalLength */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > focal_len = getreal(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 37393: /* ImageNumber */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > shot_order = getint(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 37400: /* old Kodak KDC tag */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (raw_color = i=0; i < 3; i++) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > getreal(type); > ~~~~~~~~~~~~~~ > FORC3 rgb_cam[i][c] = getreal(type); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > break; > ~~~~~~ > case 40976: > ~~~~~~~~~~~ > strip_offset = get4(); > ~~~~~~~~~~~~~~~~~~~~~~ > switch (tiff_ifd[ifd].comp) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 32770: load_raw = &CLASS samsung_load_raw; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 32772: load_raw = &CLASS samsung2_load_raw; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 32773: load_raw = &CLASS samsung3_load_raw; break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > break; > ~~~~~~ > case 46275: /* Imacon tags */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > strcpy (make, "Imacon"); > ~~~~~~~~~~~~~~~~~~~~~~~~ > data_offset = ftell(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~ > ima_len = len; > ~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 46279: > ~~~~~~~~~~~ > if (!ima_len) break; > ~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 38, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 46274: > ~~~~~~~~~~~ > fseek (ifp, 40, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > raw_width = get4(); > ~~~~~~~~~~~~~~~~~~~~ > raw_height = get4(); > ~~~~~~~~~~~~~~~~~~~~ > left_margin = get4() & 7; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > width = raw_width - left_margin - (get4() & 7); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > top_margin = get4() & 7; > ~~~~~~~~~~~~~~~~~~~~~~~~ > height = raw_height - top_margin - (get4() & 7); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (raw_width == 7262) { > ~~~~~~~~~~~~~~~~~~~~~~~~ > height = 5444; > ~~~~~~~~~~~~~~ > width = 7244; > ~~~~~~~~~~~~~~ > left_margin = 7; > ~~~~~~~~~~~~~~~~ > } > ~ > fseek (ifp, 52, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC3 cam_mul[c] = getreal(11); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fseek (ifp, 114, SEEK_CUR); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > flip = (get2() >> 7) * 90; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (width * height * 6 == ima_len) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (flip % 180 == 90) SWAP(width,height); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > raw_width = width; > ~~~~~~~~~~~~~~~~~~ > raw_height = height; > ~~~~~~~~~~~~~~~~~~~~ > left_margin = top_margin = filters = flip = 0; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > sprintf (model, "Ixpress %d-Mp", height*width/1000000); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > load_raw = &CLASS imacon_full_load_raw; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (filters) { > ~~~~~~~~~~~~~~ > if (left_margin & 1) filters = 0x61616161; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > load_raw = &CLASS unpacked_load_raw; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } > ~ > maximum = 0xffff; > ~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 50454: /* Sinar tag */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 50455: > ~~~~~~~~~~~ > if (!(cbuf = (char *) malloc(len))) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > fread (cbuf, 1, len, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n')) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!strncmp (++cp,"Neutral ",8)) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > free (cbuf); > ~~~~~~~~~~~~ > break; > ~~~~~~ > case 50458: > ~~~~~~~~~~~ > if (!make[0]) strcpy (make, "Hasselblad"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 50459: /* Hasselblad tag */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > i = order; > ~~~~~~~~~~ > j = ftell(ifp); > ~~~~~~~~~~~~~~~ > c = tiff_nifds; > ~~~~~~~~~~~~~~~ > order = get2(); > ~~~~~~~~~~~~~~~ > fseek (ifp, j+(get2(),get4()), SEEK_SET); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > parse_tiff_ifd (j); > ~~~~~~~~~~~~~~~~~~~ > maximum = 0xffff; > ~~~~~~~~~~~~~~~~~ > tiff_nifds = c; > ~~~~~~~~~~~~~~~ > order = i; > ~~~~~~~~~~ > break; > ~~~~~~ > case 50706: /* DNGVersion */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 dng_version = (dng_version << 8) + fgetc(ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (!make[0]) strcpy (make, "DNG"); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > is_raw = 1; > ~~~~~~~~~~~ > break; > ~~~~~~ > case 50708: /* UniqueCameraModel */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (model[0]) break; > ~~~~~~~~~~~~~~~~~~~~ > fgets (make, 64, ifp); > ~~~~~~~~~~~~~~~~~~~~~~ > if ((cp = strchr(make,' '))) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > strcpy(model,cp+1); > ~~~~~~~~~~~~~~~~~~~ > *cp = 0; > ~~~~~~~~ > } > ~ > break; > ~~~~~~ > case 50710: /* CFAPlaneColor */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (filters == 9) break; > ~~~~~~~~~~~~~~~~~~~~~~~~ > if (len > 4) len = 4; > ~~~~~~~~~~~~~~~~~~~~~ > colors = len; > ~~~~~~~~~~~~~ > fread (cfa_pc, 1, colors, ifp); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > guess_cfa_pc: > ~~~~~~~~~~~~~ > FORCC tab[cfa_pc[c]] = c; > ~~~~~~~~~~~~~~~~~~~~~~~~~ > cdesc[c] = 0; > ~~~~~~~~~~~~~ > for (i=16; i--; ) > ~~~~~~~~~~~~~~~~~ > filters = filters << 2 | tab[cfa_pat[i % plen]]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > filters -= !filters; > ~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 50711: /* CFALayout */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (get2() == 2) fuji_width = 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 291: > ~~~~~~~~~ > case 50712: /* LinearizationTable */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > linear_table (len); > ~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 50713: /* BlackLevelRepeatDim */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cblack[4] = get2(); > ~~~~~~~~~~~~~~~~~~~ > cblack[5] = get2(); > ~~~~~~~~~~~~~~~~~~~ > if (cblack[4] * cblack[5] > sizeof cblack / sizeof *cblack - 6) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > cblack[4] = cblack[5] = 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > break; > ~~~~~~ > case 61450: > ~~~~~~~~~~~ > cblack[4] = cblack[5] = MIN(sqrt(len),64); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > case 50714: /* BlackLevel */ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if(cblack[4] * cblack[5] == 0) { > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > int dblack[] = { 0,0,0,0 }; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ > black = getreal(type); > ~~~~~~~~~~~~~~~~~~~~~~ > if ((unsigned)(filters+1) < 1000) break; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > dblack[0] = dblack[1] = dblack[2] = dblack[3] = black; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > if (colors == 3) > ~~~~~~~~~~~~~~~~ > filters |= ((filters >> 2 & 0x22222222) | > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (filters << 2 & 0x88888888)) & filters << 1; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > FORC4 cblack[filters >> (c << 1) & 3] = dblack[c]; > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > } else { > ~~~~~~~~ > FORC (cblack[4] * cblack[5]) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6088:4: note: in expansion of macro 'FORC' > FORC (cblack[4] * cblack[5]) > ^ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6095:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (num=i=0; i < (len & 0xffff); i++) > ~~^~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6150:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (i=0; i < len && i < 32; i++) > ~~^~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::apply_tiff()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6243:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (i=0; i < tiff_nifds; i++) { > ~~^~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6256:28: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > (ns == os && shot_select == ties++))) { > ~~~~~~~~~~~~^~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6282:28: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if (tiff_ifd[raw].bytes*8 != raw_width*raw_height*tiff_bps) { > ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6336:4: warning: this 'else' clause does not guard... [-Wmisleading-indentation] > } else > ^~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6337:40: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'else' > load_raw = &CLASS nikon_load_raw; break; > ^~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6356:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (i=0; i < tiff_nifds; i++) > ~~^~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6358:68: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > tiff_ifd[i].width * tiff_ifd[i].height / (SQR(tiff_ifd[i].bps)+1) > > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ > thumb_width * thumb_height / (SQR(thumb_misc)+1) > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::parse_riff()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6831:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > while (ftell(ifp)+7 < end && !feof(ifp)) > ~~~~~~~~~~~~~^~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6834:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > while (ftell(ifp)+7 < end) { > ~~~~~~~~~~~~~^~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::parse_smal(int, int)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6886:14: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if (get4() != fsize) return; > ~~~~~~~^~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::parse_redcine()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:6959:27: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > while ((len = get4()) != EOF) { > ^ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::parse_foveon()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:7002:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if (get4() != (0x20434553 | (tag << 24))) return; > ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:7024:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > && thumb_length < len-28) { > ~~~~~~~~~~~~~^~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::adobe_coeff(const char*, const char*)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:8127:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (i=0; i < sizeof table / sizeof *table; i++) > ~~^~~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In member function 'void DCraw::identify()': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:8654:28: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (zero_fsize=i=0; i < sizeof table / sizeof *table; i++) > ~~^~~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:8655:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if (fsize == table[i].fsize) { > ~~~~~~^~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:8706:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (i=0; i < sizeof corp / sizeof *corp; i++) > ~~^~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:8769:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (i=0; i < sizeof canon / sizeof *canon; i++) > ~~^~~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:8786:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (i=0; i < sizeof unique / sizeof *unique; i++) > ~~^~~~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:8792:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (i=0; i < sizeof sonique / sizeof *sonique; i++) > ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:9240:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (i=0; i < sizeof pana / sizeof *pana; i++) > ~~^~~~~~~~~~~~~~~~~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:9538:12: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if (flip == UINT_MAX) flip = tiff_flip; > ^ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:9539:12: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > if (flip == UINT_MAX) flip = 0; > ^ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc: In function 'void decodeFPDeltaRow(Bytef*, Bytef*, size_t, size_t, int, int)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:9614:31: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (size_t byte = 0; byte < bytesps; ++byte) > ~~~~~^~~~~~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/dcraw.cc:9619:31: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] > for (size_t byte = 0; byte < bytesps; ++byte) > ~~~~~^~~~~~~~~ >[ 8%] Building CXX object rtengine/CMakeFiles/rtengine.dir/iccstore.cc.o >cd /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine && /usr/bin/c++ -DAUTO_GDK_FLUSH=0 -DBZIP_SUPPORT -DMYFILE_MMAP -DNDEBUG -DSTRICT_MUTEX=1 -DTRACE_MYRWMUTEX=0 -D_DNDEBUG -Drtengine_EXPORTS -I/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/glibmm-2.4 -I/usr/lib64/glibmm-2.4/include -I/usr/include/sigc++-2.0 -I/usr/lib64/sigc++-2.0/include -I/usr/include/libiptcdata -I/usr/include/gtkmm-3.0 -I/usr/lib64/gtkmm-3.0/include -I/usr/include/atkmm-1.6 -I/usr/include/atk-1.0 -I/usr/include/giomm-2.4 -I/usr/lib64/giomm-2.4/include -I/usr/include/pangomm-1.4 -I/usr/lib64/pangomm-1.4/include -I/usr/include/cairomm-1.0 -I/usr/lib64/cairomm-1.0/include -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/libdrm -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/gtk-3.0 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gio-unix-2.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -I/usr/include/gtk-3.0/unix-print -I/usr/include/gdkmm-3.0 -I/usr/lib64/gdkmm-3.0/include -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mcpu=power8 -mtune=power8 -std=gnu++11 -Werror=unused-label -fopenmp -Werror=unknown-pragmas -DNDEBUG -fPIC -o CMakeFiles/rtengine.dir/iccstore.cc.o -c /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/iccstore.cc >make[2]: *** [rtengine/CMakeFiles/rtengine.dir/build.make:162: rtengine/CMakeFiles/rtengine.dir/dcraw.cc.o] Error 1 >make[2]: *** Waiting for unfinished jobs.... >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.cc: In member function 'void rtengine::ColorGradientCurve::SetXYZ(const rtengine::Curve*, const double (*)[3], const double (*)[3], float, float)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/curves.cc:1429:27: warning: 'lr2' may be used uninitialized in this function [-Wmaybe-uninitialized] > Color::hsv2rgb(float(nextY), satur, lr2, r, g, b); > ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >In file included from /usr/include/glibmm-2.4/glibmm/containerhandle_shared.h:24:0, > from /usr/include/glibmm-2.4/glibmm/arrayhandle.h:23, > from /usr/include/glibmm-2.4/glibmm.h:93, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/iccstore.h:23, > from /builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/iccstore.cc:19: >/usr/include/glibmm-2.4/glibmm/variant.h:596:55: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > static V_CastTo cast_dynamic(const VariantBase& v) throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:643:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast) > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:899:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1082:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/usr/include/glibmm-2.4/glibmm/variant.h:1139:1: warning: dynamic exception specifications are deprecated in C++11; use 'noexcept' instead [-Wdeprecated] > throw(std::bad_cast); > ^~~~~ >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/iccstore.cc: In constructor 'rtengine::ProfileContent::ProfileContent(const Glib::ustring&)': >/builddir/build/BUILD/RawTherapee-5.0-gtk3/rtengine/iccstore.cc:843:11: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result] > fread (data, length, 1, f); > ~~~~~~^~~~~~~~~~~~~~~~~~~~ >make[2]: Leaving directory '/builddir/build/BUILD/RawTherapee-5.0-gtk3' >make[1]: *** [CMakeFiles/Makefile2:182: rtengine/CMakeFiles/rtengine.dir/all] Error 2 >make[1]: Leaving directory '/builddir/build/BUILD/RawTherapee-5.0-gtk3' >make: *** [Makefile:131: all] Error 2 >error: Bad exit status from /var/tmp/rpm-tmp.1h7iSc (%build) >RPM build errors: > Bad exit status from /var/tmp/rpm-tmp.1h7iSc (%build) >Child return code was: 1 >EXCEPTION: [Error()] >Traceback (most recent call last): > File "/usr/lib/python3.5/site-packages/mockbuild/trace_decorator.py", line 89, in trace > result = func(*args, **kw) > File "/usr/lib/python3.5/site-packages/mockbuild/util.py", line 578, in do > raise exception.Error("Command failed. See logs for output.\n # %s" % (command,), child.returncode) >mockbuild.exception.Error: Command failed. See logs for output. > # bash --login -c /usr/bin/rpmbuild -bb --target ppc64le --nodeps /builddir/build/SPECS/rawtherapee.spec
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 1424245
: 1254014 |
1254015
|
1254016