libraw: data checking

This commit is contained in:
Piotr Bartman 2022-03-31 11:26:20 +02:00
parent 7fc66b2026
commit 1b1c085cfe
6 changed files with 109 additions and 52 deletions

View File

@ -65,6 +65,8 @@ add_sapi_library(
libraw_cameraCount libraw_cameraCount
libraw_COLOR libraw_COLOR
libraw_get_raw_height
libraw_get_raw_width
INPUTS INPUTS
"${CMAKE_BINARY_DIR}/raw.gen.h" "${CMAKE_BINARY_DIR}/raw.gen.h"

View File

@ -66,16 +66,18 @@ int main(int ac, char* av[]) {
LibRaw lr(&sandbox, av[1]); LibRaw lr(&sandbox, av[1]);
if (not lr.CheckIsInit().ok()) { if (not lr.CheckIsInit().ok()) {
std::cerr << "Unable init LibRaw"; std::cerr << "Unable init LibRaw";
std::cerr << lr.CheckIsInit().status();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
status = lr.OpenFile(); status = lr.OpenFile();
if (not status.ok()) { if (not status.ok()) {
std::cerr << "Unable to open file" << av[1] << "\n"; std::cerr << "Unable to open file" << av[1] << "\n";
std::cerr << status;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if ((lr.GetImgData().idata.colors == 1 and channel > 0) or (channel > 3)) { if ((lr.GetColorCount() == 1 and channel > 0) or (channel > 3)) {
std::cerr << "Incorrect CHANNEL specified:" << channel << "\n"; std::cerr << "Incorrect CHANNEL specified:" << channel << "\n";
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -83,66 +85,78 @@ int main(int ac, char* av[]) {
status = lr.Unpack(); status = lr.Unpack();
if (not status.ok()) { if (not status.ok()) {
std::cerr << "Unable to unpack file" << av[1] << "\n"; std::cerr << "Unable to unpack file" << av[1] << "\n";
std::cerr << status;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
status = lr.SubtractBlack(); status = lr.SubtractBlack();
if (not status.ok()) { if (not status.ok()) {
std::cerr << "Unable to subtract black level"; std::cerr << "Unable to subtract black level";
std::cerr << status;
// ok, but different output
} }
absl::StatusOr<std::vector<uint16_t>> rawdata = lr.RawData();
if (not rawdata.ok()) {
std::cerr << "Unable to get raw data\n";
std::cerr << rawdata.status();
return EXIT_FAILURE;
}
absl::StatusOr<ushort> raw_height = lr.GetRawHeight();
absl::StatusOr<ushort> raw_width = lr.GetRawWidth();
if (not raw_height.ok() or not raw_width.ok()) {
std::cerr << "Unable to get raw image sizes.";
return EXIT_FAILURE;
}
// header
std::cout << av[1] << "\t" << colstart << "-" << rowstart << "-" << width std::cout << av[1] << "\t" << colstart << "-" << rowstart << "-" << width
<< "x" << height << "\t" << "x" << height << "\t"
<< "channel: " << channel << "\n"; << "channel: " << channel << "\n";
std::cout << std::setw(6) << "R\\C"; std::cout << std::setw(6) << "R\\C";
for (int col = colstart; for (int col = colstart;
col < colstart + width and col < lr.GetImgData().sizes.raw_width; col < colstart + width and col < *raw_width;
col++) { col++) {
std::cout << std::setw(6) << col; std::cout << std::setw(6) << col;
} }
std::cout << "\n"; std::cout << "\n";
if (lr.GetImgData().rawdata.raw_image) { // dump raw to output
absl::StatusOr<std::vector<uint16_t>> rawdata = lr.RawData(); for (int row = rowstart;
if (not rawdata.ok()) { row < rowstart + height && row < *raw_height;
std::cerr << "Unable to get raw data\n"; row++) {
return EXIT_FAILURE; unsigned rcolors[48];
if (lr.GetColorCount() > 1) {
absl::StatusOr<int> color;
for (int c = 0; c < 48; c++) {
color = lr.COLOR(row, c);
if (color.ok()) rcolors[c] = *color;
}
} else {
memset(rcolors, 0, sizeof(rcolors));
} }
std::cout << std::setw(6) << row;
for (int row = rowstart; for (int col = colstart;
row < rowstart + height && row < lr.GetImgData().sizes.raw_height; col < colstart + width && col < *raw_width;
row++) { col++) {
unsigned rcolors[48]; int idx = row * lr.GetImgData().sizes.raw_pitch / 2 + col;
if (lr.GetImgData().idata.colors > 1) {
absl::StatusOr<int> color; if (rcolors[col % 48] == (unsigned)channel) {
for (int c = 0; c < 48; c++) { absl::StatusOr<int> cblack = lr.GetCBlack(channel);
color = lr.COLOR(row, c); if (not cblack.ok()) {
if (color.ok()) rcolors[c] = *color; std::cerr << "Unable to get cblack for channel " << channel;
std::cerr << cblack.status();
return EXIT_FAILURE;
} }
std::cout << std::setw(6)
<< subtract_bl((*rawdata).at(idx), *cblack);
} else { } else {
memset(rcolors, 0, sizeof(rcolors)); std::cout << " -";
} }
std::cout << std::setw(6) << row;
for (int col = colstart;
col < colstart + width && col < lr.GetImgData().sizes.raw_width;
col++) {
int idx = row * lr.GetImgData().sizes.raw_pitch / 2 + col;
if (rcolors[col % 48] == (unsigned)channel) {
std::cout << std::setw(6)
<< subtract_bl((*rawdata)[idx],
lr.GetImgData().color.cblack[channel]);
} else {
std::cout << " -";
}
}
std::cout << "\n";
} }
} else { std::cout << "\n";
std::cout
<< "Unsupported file data (e.g. floating point format), or incorrect "
"channel specified\n";
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;

View File

@ -31,21 +31,14 @@ class LibRawSapiSandbox : public LibRawSandbox {
std::unique_ptr<sandbox2::Policy> ModifyPolicy( std::unique_ptr<sandbox2::Policy> ModifyPolicy(
sandbox2::PolicyBuilder*) override { sandbox2::PolicyBuilder*) override {
return sandbox2::PolicyBuilder() return sandbox2::PolicyBuilder()
.AllowStaticStartup()
.AllowDynamicStartup() .AllowDynamicStartup()
.AllowTcMalloc()
.AllowSystemMalloc()
.AllowScudoMalloc()
.AllowOpen() .AllowOpen()
.AllowRead() .AllowRead()
.AllowWrite() .AllowWrite()
.AllowSystemMalloc() .AllowSystemMalloc()
.AllowExit() .AllowExit()
.AllowSafeFcntl()
.AllowSyscalls({__NR_recvmsg}) .AllowSyscalls({__NR_recvmsg})
.AddFile(file_name_, /*is_ro=*/true) .AddFile(file_name_, /*is_ro=*/true)
.AllowRestartableSequencesWithProcFiles(
sandbox2::PolicyBuilder::kAllowSlowFences) // hangs without it?
.BuildOrDie(); .BuildOrDie();
} }

View File

@ -97,10 +97,11 @@ TEST_P(LibRawTestFiles, TestSize) {
SAPI_ASSERT_OK(lr.OpenFile()); SAPI_ASSERT_OK(lr.OpenFile());
SAPI_ASSERT_OK(lr.Unpack()); SAPI_ASSERT_OK(lr.Unpack());
libraw_data_t lr_data = lr.GetImgData(); SAPI_ASSERT_OK_AND_ASSIGN(ushort raw_height, lr.GetRawHeight());
SAPI_ASSERT_OK_AND_ASSIGN(ushort raw_width, lr.GetRawWidth());
ASSERT_EQ(lr_data.sizes.raw_height, tv.raw_height); ASSERT_EQ(raw_height, tv.raw_height);
ASSERT_EQ(lr_data.sizes.raw_width, tv.raw_width); ASSERT_EQ(raw_width, tv.raw_width);
} }
TEST_P(LibRawTestFiles, TestCameraList) { TEST_P(LibRawTestFiles, TestCameraList) {

View File

@ -95,19 +95,63 @@ absl::StatusOr<int> LibRaw::COLOR(int row, int col) {
SAPI_RETURN_IF_ERROR(CheckIsInit()); SAPI_RETURN_IF_ERROR(CheckIsInit());
int color; int color;
SAPI_ASSIGN_OR_RETURN( SAPI_ASSIGN_OR_RETURN(
color, api_.libraw_COLOR(sapi_libraw_data_t_.PtrNone(), row, col)); color, api_.libraw_COLOR(sapi_libraw_data_t_.PtrNone(), row, col));
return color; return color;
} }
absl::StatusOr<ushort> LibRaw::GetRawHeight() {
SAPI_RETURN_IF_ERROR(CheckIsInit());
ushort height;
SAPI_ASSIGN_OR_RETURN(
height, api_.libraw_get_raw_height(sapi_libraw_data_t_.PtrNone()));
return height;
}
absl::StatusOr<ushort> LibRaw::GetRawWidth() {
SAPI_RETURN_IF_ERROR(CheckIsInit());
ushort width;
SAPI_ASSIGN_OR_RETURN(
width, api_.libraw_get_raw_width(sapi_libraw_data_t_.PtrNone()));
return width;
}
absl::StatusOr<unsigned> LibRaw::GetCBlack(int channel) {
SAPI_RETURN_IF_ERROR(CheckIsInit());
if (channel < 0 or channel >= LIBRAW_CBLACK_SIZE) {
return absl::OutOfRangeError(
absl::string_view(std::to_string(channel)
+ " is out of range for array with size "
+ std::to_string(LIBRAW_CBLACK_SIZE)));
}
return GetImgData().color.cblack[channel];
ushort width;
SAPI_ASSIGN_OR_RETURN(
width, api_.libraw_get_raw_width(sapi_libraw_data_t_.PtrNone()));
return width;
}
int LibRaw::GetColorCount() {
return GetImgData().idata.colors;
}
absl::StatusOr<std::vector<uint16_t>> LibRaw::RawData() { absl::StatusOr<std::vector<uint16_t>> LibRaw::RawData() {
SAPI_RETURN_IF_ERROR(CheckIsInit()); SAPI_RETURN_IF_ERROR(CheckIsInit());
int size = sapi_libraw_data_t_.data().sizes.raw_height * ushort raw_height;
sapi_libraw_data_t_.data().sizes.raw_width; ushort raw_width;
SAPI_ASSIGN_OR_RETURN(raw_height, GetRawHeight());
SAPI_ASSIGN_OR_RETURN(raw_width, GetRawWidth());
unsigned size = raw_height * raw_width;
std::vector<uint16_t> buf(size); std::vector<uint16_t> buf(size);
sapi::v::Array<uint16_t> rawdata(buf.data(), buf.size()); sapi::v::Array<uint16_t> rawdata(buf.data(), buf.size());

View File

@ -60,6 +60,10 @@ class LibRaw {
absl::Status SubtractBlack(); absl::Status SubtractBlack();
absl::StatusOr<std::vector<char*>> GetCameraList(); absl::StatusOr<std::vector<char*>> GetCameraList();
absl::StatusOr<int> COLOR(int row, int col); absl::StatusOr<int> COLOR(int row, int col);
absl::StatusOr<ushort> GetRawHeight();
absl::StatusOr<ushort> GetRawWidth();
absl::StatusOr<unsigned> GetCBlack(int channel);
int GetColorCount();
private: private:
absl::Status InitLibRaw(); absl::Status InitLibRaw();
@ -70,7 +74,6 @@ class LibRaw {
std::string file_name_; std::string file_name_;
public:
sapi::v::Struct<libraw_data_t> sapi_libraw_data_t_; sapi::v::Struct<libraw_data_t> sapi_libraw_data_t_;
}; };