Camconst support for multiple crops (#6473)
Adapted from ART Co-authored-by: Alberto Griggio <agriggio@users.noreply.github.com> * camconst: support for multiple image sizes in raw_crop and masked_areas * Clean up code after porting raw crop changes * fixed raw crop for Canon R6 reduced-resolution raws * Add Canon EOS R5 1.6 crop raw crop & masked areas
This commit is contained in:
parent
9fef79ede4
commit
d74524f2c5
@ -28,8 +28,6 @@ namespace rtengine
|
|||||||
CameraConst::CameraConst() : pdafOffset(0)
|
CameraConst::CameraConst() : pdafOffset(0)
|
||||||
{
|
{
|
||||||
memset(dcraw_matrix, 0, sizeof(dcraw_matrix));
|
memset(dcraw_matrix, 0, sizeof(dcraw_matrix));
|
||||||
memset(raw_crop, 0, sizeof(raw_crop));
|
|
||||||
memset(raw_mask, 0, sizeof(raw_mask));
|
|
||||||
white_max = 0;
|
white_max = 0;
|
||||||
globalGreenEquilibration = -1;
|
globalGreenEquilibration = -1;
|
||||||
}
|
}
|
||||||
@ -192,6 +190,68 @@ CameraConst* CameraConst::parseEntry(const void *cJSON_, const char *make_model)
|
|||||||
std::unique_ptr<CameraConst> cc(new CameraConst);
|
std::unique_ptr<CameraConst> cc(new CameraConst);
|
||||||
cc->make_model = make_model;
|
cc->make_model = make_model;
|
||||||
|
|
||||||
|
const auto get_raw_crop =
|
||||||
|
[](int w, int h, const cJSON *ji, CameraConst *cc) -> bool
|
||||||
|
{
|
||||||
|
std::array<int, 4> rc;
|
||||||
|
|
||||||
|
if (ji->type != cJSON_Array) {
|
||||||
|
//fprintf(stderr, "\"raw_crop\" must be an array\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0, ji = ji->child; i < 4 && ji != nullptr; i++, ji = ji->next) {
|
||||||
|
if (ji->type != cJSON_Number) {
|
||||||
|
//fprintf(stderr, "\"raw_crop\" array must contain numbers\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//cc->raw_crop[i] = ji->valueint;
|
||||||
|
rc[i] = ji->valueint;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i != 4 || ji != nullptr) {
|
||||||
|
//fprintf(stderr, "\"raw_crop\" must contain 4 numbers\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cc->raw_crop[std::make_pair(w, h)] = rc;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto get_masked_areas =
|
||||||
|
[](int w, int h, const cJSON *ji, CameraConst *cc) -> bool
|
||||||
|
{
|
||||||
|
std::array<std::array<int, 4>, 2> rm;
|
||||||
|
|
||||||
|
if (ji->type != cJSON_Array) {
|
||||||
|
//fprintf(stderr, "\"masked_areas\" must be an array\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0, ji = ji->child; i < 2 * 4 && ji != nullptr; i++, ji = ji->next) {
|
||||||
|
if (ji->type != cJSON_Number) {
|
||||||
|
//fprintf(stderr, "\"masked_areas\" array must contain numbers\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//cc->raw_mask[i / 4][i % 4] = ji->valueint;
|
||||||
|
rm[i / 4][i % 4] = ji->valueint;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i % 4 != 0) {
|
||||||
|
//fprintf(stderr, "\"masked_areas\" array length must be divisable by 4\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cc->raw_mask[std::make_pair(w, h)] = rm;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
const cJSON *ji = cJSON_GetObjectItem(js, "dcraw_matrix");
|
const cJSON *ji = cJSON_GetObjectItem(js, "dcraw_matrix");
|
||||||
|
|
||||||
if (ji) {
|
if (ji) {
|
||||||
@ -216,24 +276,32 @@ CameraConst* CameraConst::parseEntry(const void *cJSON_, const char *make_model)
|
|||||||
|
|
||||||
if (ji) {
|
if (ji) {
|
||||||
if (ji->type != cJSON_Array) {
|
if (ji->type != cJSON_Array) {
|
||||||
fprintf(stderr, "\"raw_crop\" must be an array\n");
|
fprintf(stderr, "invalid entry for raw_crop.\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
} else if (!get_raw_crop(0, 0, ji, cc.get())) {
|
||||||
|
cJSON *je;
|
||||||
int i;
|
cJSON_ArrayForEach(je, ji) {
|
||||||
|
if (!cJSON_IsObject(je)) {
|
||||||
for (i = 0, ji = ji->child; i < 4 && ji; i++, ji = ji->next) {
|
fprintf(stderr, "invalid entry for raw_crop.\n");
|
||||||
if (ji->type != cJSON_Number) {
|
return nullptr;
|
||||||
fprintf(stderr, "\"raw_crop\" array must contain numbers\n");
|
} else {
|
||||||
return nullptr;
|
auto js = cJSON_GetObjectItem(je, "frame");
|
||||||
|
if (!js || js->type != cJSON_Array ||
|
||||||
|
cJSON_GetArraySize(js) != 2 ||
|
||||||
|
!cJSON_IsNumber(cJSON_GetArrayItem(js, 0)) ||
|
||||||
|
!cJSON_IsNumber(cJSON_GetArrayItem(js, 1))) {
|
||||||
|
fprintf(stderr, "invalid entry for raw_crop.\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
int w = cJSON_GetArrayItem(js, 0)->valueint;
|
||||||
|
int h = cJSON_GetArrayItem(js, 1)->valueint;
|
||||||
|
js = cJSON_GetObjectItem(je, "crop");
|
||||||
|
if (!js || !get_raw_crop(w, h, js, cc.get())) {
|
||||||
|
fprintf(stderr, "invalid entry for raw_crop.\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cc->raw_crop[i] = ji->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i != 4 || ji) {
|
|
||||||
fprintf(stderr, "\"raw_crop\" must contain 4 numbers\n");
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,24 +309,32 @@ CameraConst* CameraConst::parseEntry(const void *cJSON_, const char *make_model)
|
|||||||
|
|
||||||
if (ji) {
|
if (ji) {
|
||||||
if (ji->type != cJSON_Array) {
|
if (ji->type != cJSON_Array) {
|
||||||
fprintf(stderr, "\"masked_areas\" must be an array\n");
|
fprintf(stderr, "invalid entry for masked_areas.\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
} else if (!get_masked_areas(0, 0, ji, cc.get())) {
|
||||||
|
cJSON *je;
|
||||||
int i;
|
cJSON_ArrayForEach(je, ji) {
|
||||||
|
if (!cJSON_IsObject(je)) {
|
||||||
for (i = 0, ji = ji->child; i < 2 * 4 && ji; i++, ji = ji->next) {
|
fprintf(stderr, "invalid entry for masked_areas.\n");
|
||||||
if (ji->type != cJSON_Number) {
|
return nullptr;
|
||||||
fprintf(stderr, "\"masked_areas\" array must contain numbers\n");
|
} else {
|
||||||
return nullptr;
|
auto js = cJSON_GetObjectItem(je, "frame");
|
||||||
|
if (!js || js->type != cJSON_Array ||
|
||||||
|
cJSON_GetArraySize(js) != 2 ||
|
||||||
|
!cJSON_IsNumber(cJSON_GetArrayItem(js, 0)) ||
|
||||||
|
!cJSON_IsNumber(cJSON_GetArrayItem(js, 1))) {
|
||||||
|
fprintf(stderr, "invalid entry for masked_areas.\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
int w = cJSON_GetArrayItem(js, 0)->valueint;
|
||||||
|
int h = cJSON_GetArrayItem(js, 1)->valueint;
|
||||||
|
js = cJSON_GetObjectItem(je, "areas");
|
||||||
|
if (!js || !get_masked_areas(w, h, js, cc.get())) {
|
||||||
|
fprintf(stderr, "invalid entry for masked_areas.\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cc->raw_mask[i / 4][i % 4] = ji->valueint;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i % 4 != 0) {
|
|
||||||
fprintf(stderr, "\"masked_areas\" array length must be divisible by 4\n");
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,29 +475,41 @@ void CameraConst::update_pdafOffset(int other)
|
|||||||
pdafOffset = other;
|
pdafOffset = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CameraConst::has_rawCrop() const
|
|
||||||
|
bool CameraConst::has_rawCrop(int raw_width, int raw_height) const
|
||||||
{
|
{
|
||||||
return raw_crop[0] != 0 || raw_crop[1] != 0 || raw_crop[2] != 0 || raw_crop[3] != 0;
|
return raw_crop.find(std::make_pair(raw_width, raw_height)) != raw_crop.end() || raw_crop.find(std::make_pair(0, 0)) != raw_crop.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraConst::get_rawCrop(int& left_margin, int& top_margin, int& width, int& height) const
|
|
||||||
|
void CameraConst::get_rawCrop(int raw_width, int raw_height, int &left_margin, int &top_margin, int &width, int &height) const
|
||||||
{
|
{
|
||||||
left_margin = raw_crop[0];
|
auto it = raw_crop.find(std::make_pair(raw_width, raw_height));
|
||||||
top_margin = raw_crop[1];
|
if (it == raw_crop.end()) {
|
||||||
width = raw_crop[2];
|
it = raw_crop.find(std::make_pair(0, 0));
|
||||||
height = raw_crop[3];
|
}
|
||||||
|
if (it != raw_crop.end()) {
|
||||||
|
left_margin = it->second[0];
|
||||||
|
top_margin = it->second[1];
|
||||||
|
width = it->second[2];
|
||||||
|
height = it->second[3];
|
||||||
|
} else {
|
||||||
|
left_margin = top_margin = width = height = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CameraConst::has_rawMask(int idx) const
|
|
||||||
|
bool CameraConst::has_rawMask(int raw_width, int raw_height, int idx) const
|
||||||
{
|
{
|
||||||
if (idx < 0 || idx > 1) {
|
if (idx < 0 || idx > 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (raw_mask[idx][0] | raw_mask[idx][1] | raw_mask[idx][2] | raw_mask[idx][3]) != 0;
|
return raw_mask.find(std::make_pair(raw_width, raw_height)) != raw_mask.end() || raw_mask.find(std::make_pair(0, 0)) != raw_mask.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraConst::get_rawMask(int idx, int& top, int& left, int& bottom, int& right) const
|
|
||||||
|
void CameraConst::get_rawMask(int raw_width, int raw_height, int idx, int &top, int &left, int &bottom, int &right) const
|
||||||
{
|
{
|
||||||
top = left = bottom = right = 0;
|
top = left = bottom = right = 0;
|
||||||
|
|
||||||
@ -429,10 +517,17 @@ void CameraConst::get_rawMask(int idx, int& top, int& left, int& bottom, int& ri
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
top = raw_mask[idx][0];
|
auto it = raw_mask.find(std::make_pair(raw_width, raw_height));
|
||||||
left = raw_mask[idx][1];
|
if (it == raw_mask.end()) {
|
||||||
bottom = raw_mask[idx][2];
|
it = raw_mask.find(std::make_pair(0, 0));
|
||||||
right = raw_mask[idx][3];
|
}
|
||||||
|
|
||||||
|
if (it != raw_mask.end()) {
|
||||||
|
top = it->second[idx][0];
|
||||||
|
left = it->second[idx][1];
|
||||||
|
bottom = it->second[idx][2];
|
||||||
|
right = it->second[idx][3];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraConst::update_Levels(const CameraConst *other)
|
void CameraConst::update_Levels(const CameraConst *other)
|
||||||
@ -464,9 +559,7 @@ void CameraConst::update_Crop(CameraConst *other)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (other->has_rawCrop()) {
|
raw_crop.insert(other->raw_crop.begin(), other->raw_crop.end());
|
||||||
other->get_rawCrop(raw_crop[0], raw_crop[1], raw_crop[2], raw_crop[3]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CameraConst::get_Levels(camera_const_levels & lvl, int bw, int iso, float fnumber) const
|
bool CameraConst::get_Levels(camera_const_levels & lvl, int bw, int iso, float fnumber) const
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
/*
|
/* -*- C++ -*-
|
||||||
|
*
|
||||||
* This file is part of RawTherapee.
|
* This file is part of RawTherapee.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <array>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -17,17 +19,17 @@ class ustring;
|
|||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
|
|
||||||
struct camera_const_levels {
|
|
||||||
int levels[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
class CameraConst final
|
class CameraConst final
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
struct camera_const_levels {
|
||||||
|
int levels[4];
|
||||||
|
};
|
||||||
|
|
||||||
std::string make_model;
|
std::string make_model;
|
||||||
short dcraw_matrix[12];
|
short dcraw_matrix[12];
|
||||||
int raw_crop[4];
|
std::map<std::pair<int, int>, std::array<int, 4>> raw_crop;
|
||||||
int raw_mask[2][4];
|
std::map<std::pair<int, int>, std::array<std::array<int, 4>, 2>> raw_mask;
|
||||||
int white_max;
|
int white_max;
|
||||||
std::map<int, camera_const_levels> mLevels[2];
|
std::map<int, camera_const_levels> mLevels[2];
|
||||||
std::map<float, float> mApertureScaling;
|
std::map<float, float> mApertureScaling;
|
||||||
@ -47,10 +49,10 @@ public:
|
|||||||
const short *get_dcrawMatrix(void) const;
|
const short *get_dcrawMatrix(void) const;
|
||||||
const std::vector<int>& get_pdafPattern() const;
|
const std::vector<int>& get_pdafPattern() const;
|
||||||
int get_pdafOffset() const {return pdafOffset;};
|
int get_pdafOffset() const {return pdafOffset;};
|
||||||
bool has_rawCrop(void) const;
|
bool has_rawCrop(int raw_width, int raw_height) const;
|
||||||
void get_rawCrop(int& left_margin, int& top_margin, int& width, int& height) const;
|
void get_rawCrop(int raw_width, int raw_height, int& left_margin, int& top_margin, int& width, int& height) const;
|
||||||
bool has_rawMask(int idx) const;
|
bool has_rawMask(int raw_width, int raw_height, int idx) const;
|
||||||
void get_rawMask(int idx, int& top, int& left, int& bottom, int& right) const;
|
void get_rawMask(int raw_width, int raw_height, int idx, int& top, int& left, int& bottom, int& right) const;
|
||||||
int get_BlackLevel(int idx, int iso_speed) const;
|
int get_BlackLevel(int idx, int iso_speed) const;
|
||||||
int get_WhiteLevel(int idx, int iso_speed, float fnumber) const;
|
int get_WhiteLevel(int idx, int iso_speed, float fnumber) const;
|
||||||
bool has_globalGreenEquilibration() const;
|
bool has_globalGreenEquilibration() const;
|
||||||
@ -77,4 +79,5 @@ public:
|
|||||||
const CameraConst *get(const char make[], const char model[]) const;
|
const CameraConst *get(const char make[], const char model[]) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace rtengine
|
||||||
|
|
||||||
|
@ -70,6 +70,14 @@ Examples:
|
|||||||
// cropped so the "negative number" way is not totally safe.
|
// cropped so the "negative number" way is not totally safe.
|
||||||
"raw_crop": [ 10, 20, 4000, 3000 ],
|
"raw_crop": [ 10, 20, 4000, 3000 ],
|
||||||
|
|
||||||
|
// multi-aspect support (added 2020-12-03)
|
||||||
|
// "frame" defines the full dimensions the crop applies to
|
||||||
|
// (with [0, 0] being the fallback crop if none of the other applies)
|
||||||
|
"raw_crop" : [
|
||||||
|
{ "frame" : [4100, 3050], "crop": [10, 20, 4050, 3020] },
|
||||||
|
{ "frame" : [0, 0], "crop": [10, 20, 4000, 3000] }
|
||||||
|
]
|
||||||
|
|
||||||
// Almost same as MaskedAreas DNG tag, used for black level measuring. Here up to two areas can be defined
|
// Almost same as MaskedAreas DNG tag, used for black level measuring. Here up to two areas can be defined
|
||||||
// by tetrads of numbers:
|
// by tetrads of numbers:
|
||||||
"masked_areas": [ 51, 2, 3804, 156, 51, 5794, 3804, 5792 ],
|
"masked_areas": [ 51, 2, 3804, 156, 51, 5794, 3804, 5792 ],
|
||||||
@ -84,6 +92,14 @@ Examples:
|
|||||||
// instead, to take care of possible light leaks from the light sensing area to the optically black (masked)
|
// instead, to take care of possible light leaks from the light sensing area to the optically black (masked)
|
||||||
// area or sensor imperfections at the outer borders.
|
// area or sensor imperfections at the outer borders.
|
||||||
|
|
||||||
|
// multi-aspect support (added 2020-12-03)
|
||||||
|
// "frame" defines the full dimensions the masked areas apply to
|
||||||
|
// (with [0, 0] being the fallback crop if none of the other applies)
|
||||||
|
"masked_areas" : [
|
||||||
|
{ "frame" : [4100, 3050], "areas": [10, 20, 4050, 3020] },
|
||||||
|
{ "frame" : [0, 0], "areas": [10, 20, 4000, 3000] }
|
||||||
|
]
|
||||||
|
|
||||||
// list of indices of the rows with on-sensor PDAF pixels, for cameras that have such features. The indices here form a pattern that is repeated for the whole height of the sensor. The values are relative to the "pdaf_offset" value (see below)
|
// list of indices of the rows with on-sensor PDAF pixels, for cameras that have such features. The indices here form a pattern that is repeated for the whole height of the sensor. The values are relative to the "pdaf_offset" value (see below)
|
||||||
"pdaf_pattern" : [ 0,12,36,54,72,90,114,126,144,162,180,204,216,240,252,270,294,306,324,342,366,384,396,414,432,450,474,492,504,522,540,564,576,594,606,630 ],
|
"pdaf_pattern" : [ 0,12,36,54,72,90,114,126,144,162,180,204,216,240,252,270,294,306,324,342,366,384,396,414,432,450,474,492,504,522,540,564,576,594,606,630 ],
|
||||||
// index of the first row of the PDAF pattern in the sensor (0 is the topmost row). Allowed to be negative for convenience (this means that the first repetition of the pattern doesn't start from the first row)
|
// index of the first row of the PDAF pattern in the sensor (0 is the topmost row). Allowed to be negative for convenience (this means that the first repetition of the pattern doesn't start from the first row)
|
||||||
@ -1216,16 +1232,28 @@ Camera constants:
|
|||||||
{ // Quality C
|
{ // Quality C
|
||||||
"make_model": "Canon EOS R5",
|
"make_model": "Canon EOS R5",
|
||||||
"dcraw_matrix" : [9766, -2953, -1254, -4276, 12116, 2433, -437, 1336, 5131],
|
"dcraw_matrix" : [9766, -2953, -1254, -4276, 12116, 2433, -437, 1336, 5131],
|
||||||
"raw_crop" : [ 128, 96, 8224, 5490 ],
|
"raw_crop" : [
|
||||||
"masked_areas" : [ 94, 20, 5578, 122 ],
|
{ "frame" : [ 8352, 5586 ], "crop" : [ 128, 96, 8224, 5490 ] },
|
||||||
|
{ "frame" : [ 5248, 3510 ], "crop" : [ 128, 96, 5120, 3382 ] }
|
||||||
|
],
|
||||||
|
"masked_areas" : [
|
||||||
|
{ "frame" : [ 8352, 5586 ], "areas": [ 94, 20, 5578, 122 ] },
|
||||||
|
{ "frame" : [ 5248, 3510 ], "areas": [ 94, 20, 3510, 122 ] }
|
||||||
|
],
|
||||||
"ranges" : { "white" : 16382 }
|
"ranges" : { "white" : 16382 }
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // Quality C
|
{ // Quality C
|
||||||
"make_model": "Canon EOS R6",
|
"make_model": "Canon EOS R6",
|
||||||
"dcraw_matrix" : [8293, -1611, -1132, -4759, 12710, 2275, -1013, 2415, 5508],
|
"dcraw_matrix" : [8293, -1611, -1132, -4759, 12710, 2275, -1013, 2415, 5508],
|
||||||
"raw_crop": [ 72, 38, 5496, 3670 ],
|
"raw_crop": [
|
||||||
"masked_areas" : [ 40, 10, 5534, 70 ],
|
{ "frame": [5568, 3708], "crop" : [ 72, 38, 5496, 3670 ] },
|
||||||
|
{ "frame": [3584, 2386], "crop" : [ 156, 108, 3404, 2270 ] }
|
||||||
|
],
|
||||||
|
"masked_areas" : [
|
||||||
|
{ "frame": [5568, 3708], "areas": [ 40, 10, 5534, 70 ] },
|
||||||
|
{ "frame": [3584, 2386], "areas": [ 40, 10, 2374, 110 ] }
|
||||||
|
],
|
||||||
"ranges" : { "white" : 16382 }
|
"ranges" : { "white" : 16382 }
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1381,7 +1409,11 @@ Camera constants:
|
|||||||
{ // Quality C
|
{ // Quality C
|
||||||
"make_model": [ "FUJIFILM GFX 100", "FUJIFILM GFX100S" ],
|
"make_model": [ "FUJIFILM GFX 100", "FUJIFILM GFX100S" ],
|
||||||
"dcraw_matrix" : [ 16212, -8423, -1583, -4336, 12583, 1937, -195, 726, 6199 ], // taken from ART
|
"dcraw_matrix" : [ 16212, -8423, -1583, -4336, 12583, 1937, -195, 726, 6199 ], // taken from ART
|
||||||
"raw_crop": [ 0, 2, 11664, 8734 ]
|
"raw_crop": [
|
||||||
|
// multi-aspect crop to account for 16-shot pixel shift images
|
||||||
|
{ "frame" : [11808, 8754], "crop" : [ 0, 2, 11664, 8734 ] },
|
||||||
|
{ "frame" : [23616, 17508], "crop" : [ 0, 4, 23328, 17468 ] }
|
||||||
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // Quality B
|
{ // Quality B
|
||||||
|
@ -548,11 +548,18 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
|
|||||||
|
|
||||||
CameraConstantsStore* ccs = CameraConstantsStore::getInstance();
|
CameraConstantsStore* ccs = CameraConstantsStore::getInstance();
|
||||||
const CameraConst *cc = ccs->get(make, model);
|
const CameraConst *cc = ccs->get(make, model);
|
||||||
|
bool raw_crop_cc = false;
|
||||||
|
int orig_raw_width = width;
|
||||||
|
int orig_raw_height = height;
|
||||||
|
|
||||||
if (raw_image) {
|
if (raw_image) {
|
||||||
if (cc && cc->has_rawCrop()) {
|
orig_raw_width = raw_width;
|
||||||
|
orig_raw_height = raw_height;
|
||||||
|
|
||||||
|
if (cc && cc->has_rawCrop(raw_width, raw_height)) {
|
||||||
|
raw_crop_cc = true;
|
||||||
int lm, tm, w, h;
|
int lm, tm, w, h;
|
||||||
cc->get_rawCrop(lm, tm, w, h);
|
cc->get_rawCrop(raw_width, raw_height, lm, tm, w, h);
|
||||||
|
|
||||||
if (isXtrans()) {
|
if (isXtrans()) {
|
||||||
shiftXtransMatrix(6 - ((top_margin - tm) % 6), 6 - ((left_margin - lm) % 6));
|
shiftXtransMatrix(6 - ((top_margin - tm) % 6), 6 - ((left_margin - lm) % 6));
|
||||||
@ -584,9 +591,9 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cc && cc->has_rawMask(0)) {
|
if (cc && cc->has_rawMask(orig_raw_width, orig_raw_height, 0)) {
|
||||||
for (int i = 0; i < 8 && cc->has_rawMask(i); i++) {
|
for (int i = 0; i < 2 && cc->has_rawMask(orig_raw_width, orig_raw_height, i); i++) {
|
||||||
cc->get_rawMask(i, mask[i][0], mask[i][1], mask[i][2], mask[i][3]);
|
cc->get_rawMask(orig_raw_width, orig_raw_height, i, mask[i][0], mask[i][1], mask[i][2], mask[i][3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -594,9 +601,10 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
|
|||||||
free(raw_image);
|
free(raw_image);
|
||||||
raw_image = nullptr;
|
raw_image = nullptr;
|
||||||
} else {
|
} else {
|
||||||
if (get_maker() == "Sigma" && cc && cc->has_rawCrop()) { // foveon images
|
if (get_maker() == "Sigma" && cc && cc->has_rawCrop(width, height)) { // foveon images
|
||||||
|
raw_crop_cc = true;
|
||||||
int lm, tm, w, h;
|
int lm, tm, w, h;
|
||||||
cc->get_rawCrop(lm, tm, w, h);
|
cc->get_rawCrop(width, height, lm, tm, w, h);
|
||||||
left_margin = lm;
|
left_margin = lm;
|
||||||
top_margin = tm;
|
top_margin = tm;
|
||||||
|
|
||||||
@ -692,11 +700,12 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
|
|||||||
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 dcraw defaults)\n", make, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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),
|
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");
|
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),
|
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");
|
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, (cc && cc->has_rawCrop()) ? "camconst.json" : "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("color matrix provided by %s\n", (cc && cc->has_dcrawMatrix()) ? "camconst.json" : "dcraw");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user