Add decoding through LibRaw
Decode raw files with LibRaw and fall back to dcraw if LibRaw is unable to read the file.
This commit is contained in:
parent
3f5c3988e5
commit
20d3311931
4
.github/workflows/macos.yml
vendored
4
.github/workflows/macos.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
||||
mkdir build
|
||||
date +%s > build/stamp
|
||||
brew uninstall --ignore-dependencies libtiff
|
||||
brew install libtiff gtk+3 gtkmm3 gtk-mac-integration adwaita-icon-theme libsigc++@2 little-cms2 libiptcdata fftw lensfun expat pkgconfig llvm shared-mime-info exiv2 | tee -a depslog
|
||||
brew install libtiff gtk+3 gtkmm3 gtk-mac-integration adwaita-icon-theme libsigc++@2 little-cms2 libiptcdata fftw lensfun expat pkgconfig llvm shared-mime-info exiv2 automake | tee -a depslog
|
||||
date -u
|
||||
echo "----====Pourage====----"
|
||||
cat depslog | grep Pouring
|
||||
@ -42,6 +42,7 @@ jobs:
|
||||
export REF=${GITHUB_REF##*/}
|
||||
export C_FLAGS=$(echo -e $C_FLAGS | tr -d '\n')
|
||||
cd build && date -u && date +%s > configstamp
|
||||
curl -L https://github.com/Homebrew/homebrew-core/raw/679923b4eb48a8dc7ecc1f05d06063cd79b3fc00/Formula/libomp.rb -o libomp.rb && brew install --formula libomp.rb
|
||||
cmake \
|
||||
-DCMAKE_BUILD_TYPE="Release" \
|
||||
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \
|
||||
@ -66,7 +67,6 @@ jobs:
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \
|
||||
-DOSX_CONTINUOUS=ON \
|
||||
..
|
||||
curl -L https://github.com/Homebrew/homebrew-core/raw/679923b4eb48a8dc7ecc1f05d06063cd79b3fc00/Formula/libomp.rb -o libomp.rb && brew install --formula libomp.rb
|
||||
zsh -c 'echo "Configured in $(printf "%0.2f" $(($[$(date +%s)-$(cat configstamp)]/$((60.))))) minutes"'
|
||||
- name: Compile RawTherapee
|
||||
run: |
|
||||
|
1
.github/workflows/windows.yml
vendored
1
.github/workflows/windows.yml
vendored
@ -43,6 +43,7 @@ jobs:
|
||||
cc:p
|
||||
pkgconf:p
|
||||
cmake:p
|
||||
autotools:p
|
||||
ninja:p
|
||||
gtkmm3:p
|
||||
lcms2:p
|
||||
|
@ -226,6 +226,7 @@ option(WITH_LTO "Build with link-time optimizations" OFF)
|
||||
option(WITH_SAN "Build with run-time sanitizer" OFF)
|
||||
option(WITH_PROF "Build with profiling instrumentation" OFF)
|
||||
option(WITH_SYSTEM_KLT "Build using system KLT library." OFF)
|
||||
option(WITH_SYSTEM_LIBRAW "Build using system LibRaw library." OFF)
|
||||
option(OPTION_OMP "Build with OpenMP support" ON)
|
||||
option(
|
||||
STRICT_MUTEX
|
||||
@ -522,6 +523,13 @@ foreach(l ${_exiv2_libs})
|
||||
set(EXIV2_LIBRARIES ${EXIV2_LIBRARIES} ${_el})
|
||||
endforeach()
|
||||
|
||||
if(NOT WITH_SYSTEM_LIBRAW)
|
||||
set(LIBRAW_LIBRARIES "${CMAKE_CURRENT_BINARY_DIR}/rtengine/libraw/lib/.libs/libraw_r.a")
|
||||
if(WIN32)
|
||||
set(LIBRAW_LIBRARIES ${LIBRAW_LIBRARIES} -lws2_32)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
add_definitions(-DWIN32)
|
||||
add_definitions(-D_WIN32)
|
||||
@ -551,6 +559,9 @@ find_package(ZLIB REQUIRED)
|
||||
if(WITH_SYSTEM_KLT)
|
||||
find_package(KLT REQUIRED)
|
||||
endif()
|
||||
if(WITH_SYSTEM_LIBRAW)
|
||||
pkg_check_modules(LIBRAW REQUIRED libraw_r>=0.21)
|
||||
endif()
|
||||
|
||||
# Check for libcanberra-gtk3 (sound events on Linux):
|
||||
if(UNIX AND (NOT APPLE))
|
||||
|
@ -45,6 +45,11 @@ endif()
|
||||
if(EXIV2_INCLUDE_DIRS)
|
||||
include_directories("${EXIV2_INCLUDE_DIRS}")
|
||||
endif()
|
||||
if(NOT WITH_SYSTEM_LIBRAW)
|
||||
include_directories("${CMAKE_SOURCE_DIR}/rtengine/libraw")
|
||||
else()
|
||||
include_directories("${LIBRAW_INCLUDE_DIRS}")
|
||||
endif()
|
||||
|
||||
link_directories(
|
||||
"${EXPAT_LIBRARY_DIRS}"
|
||||
@ -245,10 +250,16 @@ target_link_libraries(rtengine
|
||||
${RSVG_LIBRARIES}
|
||||
${KLT_LIBRARIES}
|
||||
${EXIV2_LIBRARIES}
|
||||
${LIBRAW_LIBRARIES}
|
||||
)
|
||||
|
||||
if(OpenMP_FOUND)
|
||||
target_link_libraries(rtengine ${OpenMP_CXX_LIBRARIES})
|
||||
endif()
|
||||
|
||||
# Configure LibRaw
|
||||
if(NOT WITH_SYSTEM_LIBRAW)
|
||||
include(LibRaw.cmake)
|
||||
endif()
|
||||
|
||||
install(FILES ${CAMCONSTSFILE} DESTINATION "${DATADIR}" PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
|
||||
|
124
rtengine/LibRaw.cmake
Normal file
124
rtengine/LibRaw.cmake
Normal file
@ -0,0 +1,124 @@
|
||||
# LibRaw has its own configuration script and uses make to build. Here we add
|
||||
# the LibRaw configuration commands so they run during the CMake configuration.
|
||||
# Also, add a target which always runs make.
|
||||
|
||||
set(LIBRAW_DIR "${CMAKE_CURRENT_BINARY_DIR}/libraw")
|
||||
set(LIBRAW_LIB_DIR "${LIBRAW_DIR}/lib")
|
||||
set(LIBRAW_PHANTOM_FILE "${LIBRAW_LIB_DIR}/phantom_file")
|
||||
if(DEFINED ENV{SHELL})
|
||||
set(SHELL "$ENV{SHELL}")
|
||||
else()
|
||||
set(SHELL "sh")
|
||||
endif()
|
||||
|
||||
add_custom_target(
|
||||
LibRaw ALL
|
||||
DEPENDS ${LIBRAW_PHANTOM_FILE} # Ensures target always executes.
|
||||
)
|
||||
|
||||
# Configuration flags.
|
||||
set(CONFIGURE_FLAGS "--disable-examples")
|
||||
set(LIBRAW_CXX_FLAGS "${CXX_FLAGS} -std=gnu++11 -Wno-error=unknown-pragmas")
|
||||
# Let the configure script handle OpenMP flags.
|
||||
string(REPLACE "${OpenMP_CXX_FLAGS}" "" LIBRAW_CXX_FLAGS "${LIBRAW_CXX_FLAGS}")
|
||||
if(OPTION_OMP)
|
||||
set(CONFIGURE_FLAGS "${CONFIGURE_FLAGS} --enable-openmp")
|
||||
else()
|
||||
set(CONFIGURE_FLAGS "${CONFIGURE_FLAGS} --disable-openmp")
|
||||
endif()
|
||||
set(CONFIGURE_FLAGS "${CONFIGURE_FLAGS} CC=\"${CMAKE_C_COMPILER}\"")
|
||||
set(CONFIGURE_FLAGS "${CONFIGURE_FLAGS} CXX=\"${CMAKE_CXX_COMPILER}\"")
|
||||
set(CONFIGURE_FLAGS "${CONFIGURE_FLAGS} CXXFLAGS=\"${LIBRAW_CXX_FLAGS}\"")
|
||||
|
||||
# Configuration commands.
|
||||
message(STATUS "Configuring LibRaw")
|
||||
execute_process(
|
||||
COMMAND cp -p -R "${CMAKE_CURRENT_SOURCE_DIR}/libraw" .
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
RESULT_VARIABLE PROCESS_RESULT
|
||||
COMMAND_ECHO STDOUT
|
||||
)
|
||||
if(PROCESS_RESULT AND NOT PROCESS_RESULT EQUAL 0)
|
||||
message(FATAL_ERROR "Could not copy LibRaw files into build directory")
|
||||
endif()
|
||||
execute_process(
|
||||
COMMAND "${SHELL}" -l -c "autoreconf -v --install"
|
||||
WORKING_DIRECTORY "${LIBRAW_DIR}"
|
||||
RESULT_VARIABLE PROCESS_RESULT
|
||||
COMMAND_ECHO STDOUT
|
||||
)
|
||||
if(PROCESS_RESULT AND NOT PROCESS_RESULT EQUAL 0)
|
||||
message(FATAL_ERROR "Could not generate LibRaw configuration script")
|
||||
endif()
|
||||
execute_process(
|
||||
COMMAND "${SHELL}" -l -c "./configure ${CONFIGURE_FLAGS}"
|
||||
WORKING_DIRECTORY "${LIBRAW_DIR}"
|
||||
RESULT_VARIABLE PROCESS_RESULT
|
||||
COMMAND_ECHO STDOUT
|
||||
)
|
||||
if(PROCESS_RESULT AND NOT PROCESS_RESULT EQUAL 0)
|
||||
execute_process(
|
||||
COMMAND cat config.log
|
||||
WORKING_DIRECTORY "${LIBRAW_DIR}"
|
||||
COMMAND_ECHO STDOUT
|
||||
)
|
||||
message(FATAL_ERROR "LibRaw configure failed")
|
||||
endif()
|
||||
|
||||
# Build flags.
|
||||
set(LIBRAW_MAKE_FLAGS "")
|
||||
if(CMAKE_GENERATOR MATCHES ".*Makefiles.*")
|
||||
set(LIBRAW_MAKE_COMMAND "$(MAKE)")
|
||||
else()
|
||||
# If not using Makefiles, set number of jobs equal to logical processors
|
||||
# count. Not necessary for make because of the jobserver.
|
||||
execute_process(
|
||||
COMMAND "${SHELL}" -l -c "nproc"
|
||||
OUTPUT_VARIABLE LOGICAL_PROCESSORS
|
||||
RESULT_VARIABLE PROCESS_RESULT
|
||||
ERROR_QUIET
|
||||
)
|
||||
if(PROCESS_RESULT AND NOT PROCESS_RESULT EQUAL 0)
|
||||
execute_process(
|
||||
COMMAND "${SHELL}" -l -c "sysctl -n hw.ncpu"
|
||||
OUTPUT_VARIABLE LOGICAL_PROCESSORS
|
||||
RESULT_VARIABLE PROCESS_RESULT
|
||||
ERROR_QUIET
|
||||
)
|
||||
endif()
|
||||
if(PROCESS_RESULT AND NOT PROCESS_RESULT EQUAL 0)
|
||||
execute_process(
|
||||
COMMAND "${SHELL}" -l -c "getconf _NPROCESSORS_ONLN"
|
||||
OUTPUT_VARIABLE LOGICAL_PROCESSORS
|
||||
RESULT_VARIABLE PROCESS_RESULT
|
||||
ERROR_QUIET
|
||||
)
|
||||
endif()
|
||||
if(PROCESS_RESULT AND NOT PROCESS_RESULT EQUAL 0)
|
||||
set(LOGICAL_PROCESSORS "1")
|
||||
endif()
|
||||
string(STRIP "${LOGICAL_PROCESSORS}" LOGICAL_PROCESSORS)
|
||||
set(LIBRAW_MAKE_FLAGS "${LIBRAW_MAKE_FLAGS} -j${LOGICAL_PROCESSORS}")
|
||||
|
||||
set(LIBRAW_MAKE_COMMAND "make")
|
||||
endif()
|
||||
|
||||
# Build commands.
|
||||
add_custom_command(
|
||||
OUTPUT "${LIBRAW_PHANTOM_FILE}" "${LIBRAW_LIB_DIR}/.libs/libraw_r.a"
|
||||
COMMAND cp -p -R "${CMAKE_CURRENT_SOURCE_DIR}/libraw" ..
|
||||
COMMAND "${SHELL}" -l -c "${LIBRAW_MAKE_COMMAND} ${LIBRAW_MAKE_FLAGS}"
|
||||
COMMENT "Building LibRaw"
|
||||
WORKING_DIRECTORY libraw
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Add a `make clean-libraw` command because there's no good way to automatically
|
||||
# clean the LibRaw build with `make`clean`.
|
||||
add_custom_target(
|
||||
clean-libraw
|
||||
COMMAND make clean
|
||||
COMMAND rm -rf lib
|
||||
WORKING_DIRECTORY libraw
|
||||
)
|
||||
|
@ -67,6 +67,7 @@ public:
|
||||
,getbithuff(this,ifp,zero_after_ff)
|
||||
,nikbithuff(ifp)
|
||||
{
|
||||
shrink=0;
|
||||
memset(&hbd, 0, sizeof(hbd));
|
||||
aber[0]=aber[1]=aber[2]=aber[3]=1;
|
||||
gamm[0]=0.45;gamm[1]=4.5;gamm[2]=gamm[3]=gamm[4]=gamm[5]=0;
|
||||
|
@ -44,6 +44,7 @@ const Settings* settings;
|
||||
|
||||
MyMutex* lcmsMutex = nullptr;
|
||||
MyMutex *fftwMutex = nullptr;
|
||||
MyMutex *librawMutex = nullptr;
|
||||
|
||||
int init (const Settings* s, const Glib::ustring& baseDir, const Glib::ustring& userSettingsDir, bool loadAll)
|
||||
{
|
||||
@ -120,6 +121,8 @@ int init (const Settings* s, const Glib::ustring& baseDir, const Glib::ustring&
|
||||
delete lcmsMutex;
|
||||
lcmsMutex = new MyMutex;
|
||||
fftwMutex = new MyMutex;
|
||||
delete librawMutex;
|
||||
librawMutex = new MyMutex;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,9 @@ unsigned DCraw::pana_bits_t::operator() (int nbits, unsigned *bytes)
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class pana_cs6_page_decoder
|
||||
{
|
||||
unsigned int pixelbuffer[14], lastoffset, maxoffset;
|
||||
@ -99,6 +102,8 @@ void pana_cs6_page_decoder::read_page()
|
||||
}
|
||||
#undef wbuffer
|
||||
|
||||
}
|
||||
|
||||
void DCraw::panasonic_load_raw()
|
||||
{
|
||||
int enc_blck_size = RT_pana_info.bpp == 12 ? 10 : 9;
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
* This file is part of RawTherapee.
|
||||
*
|
||||
* LibRaw integration adapted from ART.
|
||||
*
|
||||
* Created on: 20/nov/2010
|
||||
*/
|
||||
|
||||
@ -11,17 +13,24 @@
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include "image8.h"
|
||||
#include "rawimage.h"
|
||||
#include "settings.h"
|
||||
#include "camconst.h"
|
||||
#include "utils.h"
|
||||
#include "rtengine.h"
|
||||
#include "libraw/libraw/libraw.h"
|
||||
|
||||
namespace rtengine
|
||||
{
|
||||
|
||||
|
||||
extern MyMutex *librawMutex;
|
||||
|
||||
|
||||
RawImage::RawImage(const Glib::ustring &name)
|
||||
: data(nullptr)
|
||||
: DCraw()
|
||||
, data(nullptr)
|
||||
, prefilters(0)
|
||||
, filename(name)
|
||||
, rotate_deg(0)
|
||||
@ -29,9 +38,12 @@ RawImage::RawImage(const Glib::ustring &name)
|
||||
, allocation(nullptr)
|
||||
{
|
||||
memset(maximum_c4, 0, sizeof(maximum_c4));
|
||||
memset(white, 0, sizeof(white));
|
||||
RT_matrix_from_constant = ThreeValBool::X;
|
||||
RT_blacklevel_from_constant = ThreeValBool::X;
|
||||
RT_whitelevel_from_constant = ThreeValBool::X;
|
||||
memset(make, 0, sizeof(make));
|
||||
memset(model, 0, sizeof(model));
|
||||
}
|
||||
|
||||
RawImage::~RawImage()
|
||||
@ -41,7 +53,7 @@ RawImage::~RawImage()
|
||||
ifp = nullptr;
|
||||
}
|
||||
|
||||
if (image) {
|
||||
if (image && decoder == Decoder::DCRAW) {
|
||||
free(image);
|
||||
}
|
||||
|
||||
@ -66,6 +78,18 @@ RawImage::~RawImage()
|
||||
}
|
||||
}
|
||||
|
||||
void RawImage::pre_interpolate()
|
||||
{
|
||||
int w = width, h = height;
|
||||
if (decoder == Decoder::LIBRAW) {
|
||||
width = iwidth;
|
||||
height = iheight;
|
||||
}
|
||||
DCraw::pre_interpolate();
|
||||
width = w;
|
||||
height = h;
|
||||
}
|
||||
|
||||
eSensorType RawImage::getSensorType() const
|
||||
{
|
||||
if (isBayer()) {
|
||||
@ -467,7 +491,176 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
|
||||
// set the number of the frame to extract. If the number is larger then number of existing frames - 1, dcraw will handle that correctly
|
||||
|
||||
shot_select = imageNum;
|
||||
|
||||
libraw.reset(new LibRaw());
|
||||
int libraw_error = [&]() -> int {
|
||||
libraw->imgdata.params.use_camera_wb = 1;
|
||||
|
||||
int err = libraw->open_buffer(ifp->data, ifp->size);
|
||||
if (err == LIBRAW_FILE_UNSUPPORTED || err == LIBRAW_TOO_BIG) {
|
||||
// fallback to the internal one
|
||||
return err;
|
||||
} else if (err != LIBRAW_SUCCESS && strncmp(libraw->imgdata.idata.software, "make_arq", 8) == 0) {
|
||||
return err;
|
||||
} else if (err == LIBRAW_FILE_UNSUPPORTED && (strncmp(libraw->unpack_function_name(), "sony_arq_load_raw", 17) == 0 || strncmp(libraw->imgdata.idata.software, "HDRMerge", 8) == 0)) {
|
||||
return err;
|
||||
} else if (err != LIBRAW_SUCCESS) {
|
||||
decoder = Decoder::LIBRAW;
|
||||
return err;
|
||||
} else if (libraw->is_floating_point() && libraw->imgdata.idata.dng_version) {
|
||||
return err;
|
||||
}
|
||||
|
||||
auto &d = libraw->imgdata.idata;
|
||||
is_raw = d.raw_count;
|
||||
strncpy(make, d.normalized_make, sizeof(make)-1);
|
||||
make[sizeof(make)-1] = 0;
|
||||
strncpy(model, d.normalized_model, sizeof(model)-1);
|
||||
model[sizeof(model)-1] = 0;
|
||||
RT_software = d.software;
|
||||
dng_version = d.dng_version;
|
||||
filters = d.filters;
|
||||
is_foveon = d.is_foveon;
|
||||
colors = d.colors;
|
||||
tiff_bps = 0;
|
||||
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
for (int j = 0; j < 6; ++j) {
|
||||
xtrans[i][j] = d.xtrans[i][j];
|
||||
xtrans_abs[i][j] = d.xtrans_abs[i][j];
|
||||
}
|
||||
}
|
||||
auto &s = libraw->imgdata.sizes;
|
||||
raw_width = s.raw_width;
|
||||
raw_height = s.raw_height;
|
||||
width = s.width;
|
||||
height = s.height;
|
||||
top_margin = s.top_margin;
|
||||
left_margin = s.left_margin;
|
||||
iheight = s.iheight;
|
||||
iwidth = s.iwidth;
|
||||
flip = s.flip;
|
||||
|
||||
auto &o = libraw->imgdata.other;
|
||||
iso_speed = o.iso_speed;
|
||||
shutter = o.shutter;
|
||||
aperture = o.aperture;
|
||||
focal_len = o.focal_len;
|
||||
timestamp = o.timestamp;
|
||||
shot_order = o.shot_order;
|
||||
|
||||
auto &io = libraw->imgdata.rawdata.ioparams;
|
||||
shrink = io.shrink;
|
||||
zero_is_bad = io.zero_is_bad;
|
||||
fuji_width = io.fuji_width;
|
||||
raw_color = io.raw_color;
|
||||
mix_green = io.mix_green;
|
||||
|
||||
auto &cd = libraw->imgdata.color;
|
||||
black = cd.black;
|
||||
maximum = cd.maximum;
|
||||
tiff_bps = cd.raw_bps;
|
||||
|
||||
for (size_t i = 0; i < sizeof(cblack)/sizeof(unsigned); ++i) {
|
||||
cblack[i] = cd.cblack[i];
|
||||
}
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
cam_mul[i] = cd.cam_mul[i];
|
||||
pre_mul[i] = cd.pre_mul[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
cmatrix[i][j] = cd.cmatrix[i][j];
|
||||
rgb_cam[i][j] = cd.rgb_cam[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
white[i][j] = cd.white[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
mask[i][j] = s.mask[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
auto &mkn = libraw->imgdata.makernotes;
|
||||
|
||||
// if (!strcmp(make, "Panasonic") && mkn.panasonic.BlackLevelDim > 0) {
|
||||
// memset(cblack, 0, sizeof(cblack));
|
||||
// if (mkn.panasonic.BlackLevelDim >= 4) {
|
||||
// for (size_t i = 0; i < 4; ++i) {
|
||||
// cblack[i] = mkn.panasonic.BlackLevel[i];
|
||||
// }
|
||||
// black = 0;
|
||||
// } else {
|
||||
// black = mkn.panasonic.BlackLevel[0];
|
||||
// }
|
||||
// } else
|
||||
if (!strcmp(make, "Canon") && isBayer() && !dng_version) {
|
||||
if (mkn.canon.AverageBlackLevel) {
|
||||
memset(cblack, 0, sizeof(cblack));
|
||||
for (size_t i = 0; i < 4; ++i) {
|
||||
cblack[i] = mkn.canon.ChannelBlackLevel[i];
|
||||
}
|
||||
black = 0;
|
||||
}
|
||||
if (mkn.canon.SpecularWhiteLevel) {
|
||||
maximum = mkn.canon.SpecularWhiteLevel;
|
||||
} else if (mkn.canon.NormalWhiteLevel) {
|
||||
maximum = mkn.canon.NormalWhiteLevel;
|
||||
}
|
||||
}
|
||||
while (tiff_bps < 16 && (size_t(1) << size_t(tiff_bps)) < maximum) {
|
||||
++tiff_bps;
|
||||
}
|
||||
|
||||
if (dng_version) {
|
||||
RT_whitelevel_from_constant = ThreeValBool::F;
|
||||
RT_blacklevel_from_constant = ThreeValBool::F;
|
||||
if (!isBayer() && !isXtrans()) {
|
||||
RT_matrix_from_constant = ThreeValBool::F;
|
||||
}
|
||||
} else if (strcmp(make, "Panasonic") != 0) {
|
||||
RT_whitelevel_from_constant = ThreeValBool::T;
|
||||
RT_blacklevel_from_constant = ThreeValBool::T;
|
||||
}
|
||||
|
||||
if (is_foveon) {
|
||||
raw_width = width;
|
||||
raw_height = height;
|
||||
top_margin = 0;
|
||||
left_margin = 0;
|
||||
}
|
||||
|
||||
decoder = Decoder::LIBRAW;
|
||||
return err;
|
||||
}();
|
||||
|
||||
if (libraw_error && verbose) {
|
||||
printf("LibRaw could not load image.");
|
||||
if (decoder == Decoder::DCRAW) {
|
||||
printf(" Falling back to dcraw.");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (decoder == Decoder::LIBRAW) {
|
||||
if (libraw_error) {
|
||||
return libraw_error;
|
||||
}
|
||||
} else {
|
||||
libraw->recycle();
|
||||
}
|
||||
|
||||
if (decoder == Decoder::DCRAW) {
|
||||
identify();
|
||||
}
|
||||
|
||||
// in case dcraw didn't handle the above mentioned case...
|
||||
shot_select = std::min(shot_select, std::max(is_raw, 1u) - 1);
|
||||
|
||||
@ -482,7 +675,7 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (!strcmp(make, "Fujifilm") && raw_height * raw_width * 2u != raw_size) {
|
||||
if (decoder == Decoder::DCRAW && !strcmp(make, "Fujifilm") && raw_height * raw_width * 2u != raw_size) {
|
||||
if (raw_width * raw_height * 7u / 4u == raw_size) {
|
||||
load_raw = &RawImage::fuji_14bit_load_raw;
|
||||
} else {
|
||||
@ -514,6 +707,7 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
|
||||
iheight = height;
|
||||
iwidth = width;
|
||||
|
||||
if (decoder == Decoder::DCRAW) {
|
||||
if (filters || colors == 1) {
|
||||
raw_image = (ushort *) calloc ((static_cast<unsigned int>(raw_height) + 7u) * static_cast<unsigned int>(raw_width), 2);
|
||||
merror(raw_image, "main()");
|
||||
@ -537,6 +731,63 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
|
||||
// Load raw pixels data
|
||||
fseek(ifp, data_offset, SEEK_SET);
|
||||
(this->*load_raw)();
|
||||
} else if (decoder == Decoder::LIBRAW) {
|
||||
libraw->imgdata.rawparams.shot_select = shot_select;
|
||||
|
||||
int err = libraw->open_buffer(ifp->data, ifp->size);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
{
|
||||
#ifdef LIBRAW_USE_OPENMP
|
||||
MyMutex::MyLock lock(*librawMutex);
|
||||
#endif
|
||||
err = libraw->unpack();
|
||||
}
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
auto &rd = libraw->imgdata.rawdata;
|
||||
raw_image = rd.raw_image;
|
||||
if (rd.float_image) {
|
||||
float_raw_image = new float[raw_width * raw_height];
|
||||
for (int y = 0; y < raw_height; ++y) {
|
||||
for (int x = 0; x < raw_width; ++x) {
|
||||
size_t idx = y * raw_width + x;
|
||||
float_raw_image[idx] = rd.float_image[idx];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#ifdef LIBRAW_USE_OPENMP
|
||||
MyMutex::MyLock lock(*librawMutex);
|
||||
#endif
|
||||
float_raw_image = nullptr;
|
||||
err = libraw->raw2image();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
image = libraw->imgdata.image;
|
||||
}
|
||||
|
||||
// get our custom camera matrices, but don't mess with black/white levels yet
|
||||
// (if we have custom levels in json files, we will get them later)
|
||||
auto bl = RT_blacklevel_from_constant;
|
||||
auto wl = RT_whitelevel_from_constant;
|
||||
RT_blacklevel_from_constant = ThreeValBool::F;
|
||||
RT_whitelevel_from_constant = ThreeValBool::F;
|
||||
|
||||
adobe_coeff(make, model);
|
||||
|
||||
RT_blacklevel_from_constant = bl;
|
||||
RT_whitelevel_from_constant = wl;
|
||||
|
||||
if (libraw->imgdata.color.profile_length) {
|
||||
profile_length = libraw->imgdata.color.profile_length;
|
||||
profile_data = new char[profile_length];
|
||||
memcpy(profile_data, libraw->imgdata.color.profile, profile_length);
|
||||
}
|
||||
}
|
||||
|
||||
if (!float_raw_image) { // apply baseline exposure only for float DNGs
|
||||
RT_baseline_exposure = 0;
|
||||
@ -551,6 +802,10 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
|
||||
bool raw_crop_cc = false;
|
||||
int orig_raw_width = width;
|
||||
int orig_raw_height = height;
|
||||
// For raw crop when using LibRaw.
|
||||
int raw_top_margin = 0;
|
||||
int raw_left_margin = 0;
|
||||
bool adjust_margins = false;
|
||||
|
||||
if (raw_image) {
|
||||
orig_raw_width = raw_width;
|
||||
@ -561,6 +816,18 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
|
||||
int lm, tm, w, h;
|
||||
cc->get_rawCrop(raw_width, raw_height, lm, tm, w, h);
|
||||
|
||||
if ((w < 0 || h < 0) && decoder != Decoder::DCRAW) {
|
||||
raw_crop_cc = false;
|
||||
} else {
|
||||
// protect against DNG files that are already cropped
|
||||
if (int(raw_width) <= w+lm) {
|
||||
lm = max(int(raw_width) - w, 0);
|
||||
}
|
||||
if (int(raw_height) <= h+tm) {
|
||||
tm = max(int(raw_height) - h, 0);
|
||||
}
|
||||
|
||||
if (decoder == Decoder::DCRAW) {
|
||||
if (isXtrans()) {
|
||||
shiftXtransMatrix(6 - ((top_margin - tm) % 6), 6 - ((left_margin - lm) % 6));
|
||||
} else {
|
||||
@ -571,6 +838,32 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
|
||||
|
||||
left_margin = lm;
|
||||
top_margin = tm;
|
||||
} else {
|
||||
if (lm < left_margin) {
|
||||
lm = left_margin;
|
||||
}
|
||||
if (tm < top_margin) {
|
||||
tm = top_margin;
|
||||
}
|
||||
// make sure we do not rotate filters
|
||||
if (isXtrans()) {
|
||||
if ((tm - top_margin) % 6) {
|
||||
tm = top_margin;
|
||||
}
|
||||
if ((lm - left_margin) % 6) {
|
||||
lm = left_margin;
|
||||
}
|
||||
} else {
|
||||
if ((tm - top_margin) & 1) {
|
||||
tm = top_margin;
|
||||
}
|
||||
if ((lm - left_margin) & 1) {
|
||||
lm = left_margin;
|
||||
}
|
||||
}
|
||||
raw_left_margin = lm - left_margin;
|
||||
raw_top_margin = tm - top_margin;
|
||||
}
|
||||
|
||||
if (w < 0) {
|
||||
iwidth += w;
|
||||
@ -578,7 +871,12 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
|
||||
width += w;
|
||||
width -= left_margin;
|
||||
} else if (w > 0) {
|
||||
iwidth = width = min((int)width, w);
|
||||
width = min((int)width, w);
|
||||
if (decoder == Decoder::DCRAW) {
|
||||
iwidth = width;
|
||||
} else if (width > iwidth) {
|
||||
width = iwidth;
|
||||
}
|
||||
}
|
||||
|
||||
if (h < 0) {
|
||||
@ -587,7 +885,13 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
|
||||
height += h;
|
||||
height -= top_margin;
|
||||
} else if (h > 0) {
|
||||
iheight = height = min((int)height, h);
|
||||
height = min((int)height, h);
|
||||
if (decoder == Decoder::DCRAW) {
|
||||
iheight = height;
|
||||
} else if (height > iheight) {
|
||||
height = iheight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -597,11 +901,14 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
|
||||
}
|
||||
}
|
||||
|
||||
if (decoder == Decoder::DCRAW) {
|
||||
crop_masked_pixels();
|
||||
free(raw_image);
|
||||
}
|
||||
raw_image = nullptr;
|
||||
adjust_margins = !float_raw_image; //true;
|
||||
} else {
|
||||
if (get_maker() == "Sigma" && cc && cc->has_rawCrop(width, height)) { // foveon images
|
||||
if (decoder == Decoder::DCRAW && get_maker() == "Sigma" && cc && cc->has_rawCrop(width, height)) { // foveon images
|
||||
raw_crop_cc = true;
|
||||
int lm, tm, w, h;
|
||||
cc->get_rawCrop(width, height, lm, tm, w, h);
|
||||
@ -611,21 +918,27 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
|
||||
if (w < 0) {
|
||||
width += w;
|
||||
width -= left_margin;
|
||||
iwidth += w;
|
||||
iwidth -= left_margin;
|
||||
} else if (w > 0) {
|
||||
width = min((int)width, w);
|
||||
iwidth = width;
|
||||
}
|
||||
|
||||
if (h < 0) {
|
||||
height += h;
|
||||
height -= top_margin;
|
||||
iheight += h;
|
||||
iheight -= top_margin;
|
||||
} else if (h > 0) {
|
||||
height = min((int)height, h);
|
||||
iheight = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load embedded profile
|
||||
if (profile_length) {
|
||||
if (decoder == Decoder::DCRAW && profile_length) {
|
||||
profile_data = new char[profile_length];
|
||||
fseek(ifp, profile_offset, SEEK_SET);
|
||||
fread(profile_data, 1, profile_length, ifp);
|
||||
@ -690,23 +1003,30 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
|
||||
for (int c = 0; c < 4; c++) {
|
||||
if (static_cast<int>(cblack[c]) < black_c4[c]) {
|
||||
cblack[c] = black_c4[c];
|
||||
cblack[4] = cblack[5] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (settings->verbose) {
|
||||
const char *decoder_name = decoder == Decoder::DCRAW ? "dcraw" : decoder == Decoder::LIBRAW ? "libraw" : "unknown";
|
||||
if (cc) {
|
||||
printf("constants exists for \"%s %s\" in camconst.json\n", make, model);
|
||||
} else {
|
||||
printf("no constants in camconst.json exists for \"%s %s\" (relying only on dcraw defaults)\n", make, model);
|
||||
printf("no constants in camconst.json exists for \"%s %s\" (relying only on %s defaults)\n", make, model, decoder_name);
|
||||
}
|
||||
|
||||
printf("raw dimensions: %d x %d\n", orig_raw_width, orig_raw_height);
|
||||
printf("black levels: R:%d G1:%d B:%d G2:%d (%s)\n", get_cblack(0), get_cblack(1), get_cblack(2), get_cblack(3),
|
||||
black_from_cc ? "provided by camconst.json" : "provided by dcraw");
|
||||
printf("white levels: R:%d G1:%d B:%d G2:%d (%s)\n", get_white(0), get_white(1), get_white(2), get_white(3),
|
||||
white_from_cc ? "provided by camconst.json" : "provided by dcraw");
|
||||
printf("raw crop: %d %d %d %d (provided by %s)\n", left_margin, top_margin, iwidth, iheight, raw_crop_cc ? "camconst.json" : "dcraw");
|
||||
printf("color matrix provided by %s\n", (cc && cc->has_dcrawMatrix()) ? "camconst.json" : "dcraw");
|
||||
printf("black levels: R:%d G1:%d B:%d G2:%d (provided by %s)\n", get_cblack(0), get_cblack(1), get_cblack(2), get_cblack(3),
|
||||
black_from_cc ? "camconst.json" : decoder_name);
|
||||
printf("white levels: R:%d G1:%d B:%d G2:%d (provided by %s)\n", get_white(0), get_white(1), get_white(2), get_white(3),
|
||||
white_from_cc ? "camconst.json" : decoder_name);
|
||||
printf("raw crop: %d %d %d %d (provided by %s)\n", left_margin, top_margin, iwidth, iheight, raw_crop_cc ? "camconst.json" : decoder_name);
|
||||
printf("color matrix provided by %s\n", (cc && cc->has_dcrawMatrix()) ? "camconst.json" : decoder_name);
|
||||
}
|
||||
|
||||
if (adjust_margins) {
|
||||
top_margin = raw_top_margin;
|
||||
left_margin = raw_left_margin;
|
||||
}
|
||||
}
|
||||
|
||||
@ -779,7 +1099,7 @@ float** RawImage::compress_image(unsigned int frameNum, bool freeImage)
|
||||
|
||||
for (int row = 0; row < height; row++)
|
||||
for (int col = 0; col < width; col++) {
|
||||
this->data[row][col] = image[row * width + col][FC(row, col)];
|
||||
this->data[row][col] = image[(row + top_margin) * iwidth + col + left_margin][FC(row, col)];
|
||||
}
|
||||
} else if (isXtrans()) {
|
||||
#ifdef _OPENMP
|
||||
@ -788,7 +1108,7 @@ float** RawImage::compress_image(unsigned int frameNum, bool freeImage)
|
||||
|
||||
for (int row = 0; row < height; row++)
|
||||
for (int col = 0; col < width; col++) {
|
||||
this->data[row][col] = image[row * width + col][XTRANSFC(row, col)];
|
||||
this->data[row][col] = image[(row + top_margin) * iwidth + col + left_margin][XTRANSFC(row, col)];
|
||||
}
|
||||
} else if (colors == 1) {
|
||||
#ifdef _OPENMP
|
||||
@ -797,7 +1117,7 @@ float** RawImage::compress_image(unsigned int frameNum, bool freeImage)
|
||||
|
||||
for (int row = 0; row < height; row++)
|
||||
for (int col = 0; col < width; col++) {
|
||||
this->data[row][col] = image[row * width + col][0];
|
||||
this->data[row][col] = image[row * iwidth + col][0];
|
||||
}
|
||||
} else {
|
||||
if((get_maker() == "Sigma" || get_maker() == "Pentax" || get_maker() == "Sony") && dng_version) { // Hack to prevent sigma dng files and dng files from PixelShift2DNG from crashing
|
||||
@ -817,7 +1137,11 @@ float** RawImage::compress_image(unsigned int frameNum, bool freeImage)
|
||||
}
|
||||
|
||||
if (freeImage) {
|
||||
if (decoder == Decoder::DCRAW) {
|
||||
free(image); // we don't need this anymore
|
||||
} else if (decoder == Decoder::LIBRAW) {
|
||||
libraw->recycle();
|
||||
}
|
||||
image = nullptr;
|
||||
}
|
||||
|
||||
@ -872,6 +1196,89 @@ RawImage::get_thumbSwap() const
|
||||
return (order == 0x4949) == (ntohs(0x1234) == 0x1234);
|
||||
}
|
||||
|
||||
|
||||
bool RawImage::checkThumbOk() const
|
||||
{
|
||||
if (!is_supportedThumb()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (get_thumbOffset() >= get_file()->size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const ssize_t length =
|
||||
fdata (get_thumbOffset(), get_file())[1] != 0xD8 && is_ppmThumb()
|
||||
? get_thumbWidth() * get_thumbHeight() * (get_thumbBPS() / 8) * 3
|
||||
: get_thumbLength();
|
||||
|
||||
return get_thumbOffset() + length <= get_file()->size;
|
||||
}
|
||||
|
||||
|
||||
Image8 *RawImage::getThumbnail() const
|
||||
{
|
||||
if (decoder == Decoder::DCRAW) {
|
||||
if (!checkThumbOk()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Image8 *img = new Image8();
|
||||
img->setSampleFormat(IIOSF_UNSIGNED_CHAR);
|
||||
img->setSampleArrangement(IIOSA_CHUNKY);
|
||||
|
||||
const char *data = reinterpret_cast<const char *>(fdata(get_thumbOffset(), get_file()));
|
||||
|
||||
int err = 1;
|
||||
if ((unsigned char)data[1] == 0xd8) {
|
||||
err = img->loadJPEGFromMemory(data, get_thumbLength());
|
||||
} else if (is_ppmThumb()) {
|
||||
err = img->loadPPMFromMemory(data, get_thumbWidth(), get_thumbHeight(), get_thumbSwap(), get_thumbBPS());
|
||||
}
|
||||
|
||||
// did we succeed?
|
||||
if (err) {
|
||||
delete img;
|
||||
img = nullptr;
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
if (!ifp) {
|
||||
return nullptr;
|
||||
} else {
|
||||
int err = libraw->unpack_thumb();
|
||||
if (err) {
|
||||
return nullptr;
|
||||
}
|
||||
auto &t = libraw->imgdata.thumbnail;
|
||||
if (!t.thumb) {
|
||||
return nullptr;
|
||||
} else if (t.tformat != LIBRAW_THUMBNAIL_JPEG && t.tformat != LIBRAW_THUMBNAIL_BITMAP) {
|
||||
return nullptr;
|
||||
} else {
|
||||
Image8 *img = new Image8();
|
||||
img->setSampleFormat(IIOSF_UNSIGNED_CHAR);
|
||||
img->setSampleArrangement(IIOSA_CHUNKY);
|
||||
if (t.tformat == LIBRAW_THUMBNAIL_JPEG) {
|
||||
err = img->loadJPEGFromMemory(t.thumb, t.tlength);
|
||||
} else {
|
||||
err = img->loadPPMFromMemory(t.thumb, t.twidth, t.theight, false, 8);
|
||||
}
|
||||
if (err) {
|
||||
delete img;
|
||||
return nullptr;
|
||||
} else {
|
||||
return img;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
} //namespace rtengine
|
||||
|
||||
bool
|
||||
|
@ -21,14 +21,23 @@
|
||||
#include <ctime>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <glibmm/ustring.h>
|
||||
|
||||
#include "dcraw.h"
|
||||
#include "imageformat.h"
|
||||
|
||||
|
||||
class LibRaw;
|
||||
|
||||
|
||||
namespace rtengine
|
||||
{
|
||||
|
||||
|
||||
class Image8;
|
||||
|
||||
|
||||
class RawImage: public DCraw
|
||||
{
|
||||
public:
|
||||
@ -57,11 +66,18 @@ public:
|
||||
double getBaselineExposure() const { return RT_baseline_exposure; }
|
||||
|
||||
protected:
|
||||
enum class Decoder {
|
||||
DCRAW,
|
||||
LIBRAW,
|
||||
};
|
||||
|
||||
Glib::ustring filename; // complete filename
|
||||
int rotate_deg; // 0,90,180,270 degree of rotation: info taken by dcraw from exif
|
||||
char* profile_data; // Embedded ICC color profile
|
||||
float* allocation; // pointer to allocated memory
|
||||
int maximum_c4[4];
|
||||
Decoder decoder{Decoder::DCRAW};
|
||||
std::unique_ptr<LibRaw> libraw;
|
||||
bool isFoveon() const
|
||||
{
|
||||
return is_foveon;
|
||||
@ -261,10 +277,7 @@ public:
|
||||
|
||||
public:
|
||||
// dcraw functions
|
||||
void pre_interpolate()
|
||||
{
|
||||
DCraw::pre_interpolate();
|
||||
}
|
||||
void pre_interpolate();
|
||||
|
||||
public:
|
||||
bool ISRED(unsigned row, unsigned col) const
|
||||
@ -304,6 +317,11 @@ public:
|
||||
{
|
||||
return dng_version;
|
||||
}
|
||||
|
||||
public:
|
||||
bool checkThumbOk() const;
|
||||
Image8 *getThumbnail() const;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -495,32 +495,14 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, eSensorType
|
||||
|
||||
sensorType = ri->getSensorType();
|
||||
|
||||
Image8* img = new Image8 ();
|
||||
// No sample format detection occurred earlier, so we set them here,
|
||||
// as they are mandatory for the setScanline method
|
||||
img->setSampleFormat (IIOSF_UNSIGNED_CHAR);
|
||||
img->setSampleArrangement (IIOSA_CHUNKY);
|
||||
|
||||
int err = 1;
|
||||
|
||||
// See if it is something we support
|
||||
if (checkRawImageThumb (*ri)) {
|
||||
const char* data ((const char*)fdata (ri->get_thumbOffset(), ri->get_file()));
|
||||
|
||||
if ( (unsigned char)data[1] == 0xd8 ) {
|
||||
err = img->loadJPEGFromMemory (data, ri->get_thumbLength());
|
||||
} else if (ri->is_ppmThumb()) {
|
||||
err = img->loadPPMFromMemory (data, ri->get_thumbWidth(), ri->get_thumbHeight(), ri->get_thumbSwap(), ri->get_thumbBPS());
|
||||
}
|
||||
}
|
||||
Image8 *img = ri->getThumbnail();
|
||||
|
||||
// did we succeed?
|
||||
if ( err ) {
|
||||
if (!img) {
|
||||
if (settings->verbose) {
|
||||
std::cout << "Could not extract thumb from " << fname.c_str() << std::endl;
|
||||
}
|
||||
delete tpp;
|
||||
delete img;
|
||||
delete ri;
|
||||
return nullptr;
|
||||
}
|
||||
@ -627,6 +609,11 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, eSensorType &sens
|
||||
|
||||
int width = ri->get_width();
|
||||
int height = ri->get_height();
|
||||
int iwidth = ri->get_iwidth();
|
||||
int iheight = ri->get_iheight();
|
||||
int left_margin = ri->get_leftmargin();
|
||||
int top_margin = ri->get_topmargin();
|
||||
|
||||
rtengine::Thumbnail* tpp = new rtengine::Thumbnail;
|
||||
|
||||
tpp->isRaw = true;
|
||||
@ -717,19 +704,19 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, eSensorType &sens
|
||||
if (ri->getSensorType() == ST_BAYER) {
|
||||
// demosaicing! (sort of)
|
||||
for (int row = 1, y = 0; row < height - 1 && y < tmph; row += vskip, y++) {
|
||||
rofs = row * width;
|
||||
rofs = (row + top_margin) * iwidth;
|
||||
|
||||
for (int col = firstgreen, x = 0; col < width - 1 && x < tmpw; col += hskip, x++) {
|
||||
int ofs = rofs + col;
|
||||
int ofs = rofs + col + left_margin;
|
||||
int g = image[ofs][1];
|
||||
int r, b;
|
||||
|
||||
if (FISRED (filter, row, col + 1)) {
|
||||
r = (image[ofs + 1 ][0] + image[ofs - 1 ][0]) >> 1;
|
||||
b = (image[ofs + width][2] + image[ofs - width][2]) >> 1;
|
||||
b = (image[ofs + iwidth][2] + image[ofs - iwidth][2]) >> 1;
|
||||
} else {
|
||||
b = (image[ofs + 1 ][2] + image[ofs - 1 ][2]) >> 1;
|
||||
r = (image[ofs + width][0] + image[ofs - width][0]) >> 1;
|
||||
r = (image[ofs + iwidth][0] + image[ofs - iwidth][0]) >> 1;
|
||||
}
|
||||
|
||||
tmpImg->r (y, x) = r;
|
||||
@ -739,28 +726,28 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, eSensorType &sens
|
||||
}
|
||||
} else if (ri->get_colors() == 1) {
|
||||
for (int row = 1, y = 0; row < height - 1 && y < tmph; row += vskip, y++) {
|
||||
rofs = row * width;
|
||||
rofs = (row + top_margin) * iwidth;
|
||||
|
||||
for (int col = firstgreen, x = 0; col < width - 1 && x < tmpw; col
|
||||
+= hskip, x++) {
|
||||
int ofs = rofs + col;
|
||||
int ofs = rofs + col + left_margin;
|
||||
tmpImg->r (y, x) = tmpImg->g (y, x) = tmpImg->b (y, x) = image[ofs][0];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ri->getSensorType() == ST_FUJI_XTRANS) {
|
||||
for ( int row = 1, y = 0; row < height - 1 && y < tmph; row += vskip, y++) {
|
||||
rofs = row * width;
|
||||
rofs = (row + top_margin) * iwidth;
|
||||
|
||||
for ( int col = 1, x = 0; col < width - 1 && x < tmpw; col += hskip, x++ ) {
|
||||
int ofs = rofs + col;
|
||||
int ofs = rofs + col + left_margin;
|
||||
float sum[3] = {};
|
||||
int c;
|
||||
|
||||
for (int v = -1; v <= 1; v++) {
|
||||
for (int h = -1; h <= 1; h++) {
|
||||
c = ri->XTRANSFC (row + v, col + h);
|
||||
sum[c] += image[ofs + v * width + h][c];
|
||||
sum[c] += image[ofs + v * iwidth + h][c];
|
||||
}
|
||||
}
|
||||
|
||||
@ -788,11 +775,11 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, eSensorType &sens
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int iwidth = ri->get_iwidth();
|
||||
int iheight = ri->get_iheight();
|
||||
int left_margin = ri->get_leftmargin();
|
||||
// int iwidth = ri->get_iwidth();
|
||||
// int iheight = ri->get_iheight();
|
||||
// int left_margin = ri->get_leftmargin();
|
||||
firstgreen += left_margin;
|
||||
int top_margin = ri->get_topmargin();
|
||||
// int top_margin = ri->get_topmargin();
|
||||
int wmax = tmpw;
|
||||
int hmax = tmph;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user