1*ec63e07aSXin Li // Copyright 2022 Google LLC
2*ec63e07aSXin Li //
3*ec63e07aSXin Li // Licensed under the Apache License, Version 2.0 (the "License");
4*ec63e07aSXin Li // you may not use this file except in compliance with the License.
5*ec63e07aSXin Li // You may obtain a copy of the License at
6*ec63e07aSXin Li //
7*ec63e07aSXin Li // https://www.apache.org/licenses/LICENSE-2.0
8*ec63e07aSXin Li //
9*ec63e07aSXin Li // Unless required by applicable law or agreed to in writing, software
10*ec63e07aSXin Li // distributed under the License is distributed on an "AS IS" BASIS,
11*ec63e07aSXin Li // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*ec63e07aSXin Li // See the License for the specific language governing permissions and
13*ec63e07aSXin Li // limitations under the License.
14*ec63e07aSXin Li
15*ec63e07aSXin Li #include "contrib/libraw/utils/utils_libraw.h"
16*ec63e07aSXin Li
17*ec63e07aSXin Li #include "absl/strings/str_cat.h"
18*ec63e07aSXin Li #include "contrib/libraw/sandboxed.h"
19*ec63e07aSXin Li
InitLibRaw()20*ec63e07aSXin Li absl::Status LibRaw::InitLibRaw() {
21*ec63e07aSXin Li SAPI_ASSIGN_OR_RETURN(libraw_data_t * lr_data, api_.libraw_init(0));
22*ec63e07aSXin Li
23*ec63e07aSXin Li sapi_libraw_data_t_.SetRemote(lr_data);
24*ec63e07aSXin Li SAPI_RETURN_IF_ERROR(sandbox_->TransferFromSandboxee(&sapi_libraw_data_t_));
25*ec63e07aSXin Li
26*ec63e07aSXin Li return absl::OkStatus();
27*ec63e07aSXin Li }
28*ec63e07aSXin Li
~LibRaw()29*ec63e07aSXin Li LibRaw::~LibRaw() {
30*ec63e07aSXin Li if (sapi_libraw_data_t_.GetRemote() != nullptr) {
31*ec63e07aSXin Li api_.libraw_close(sapi_libraw_data_t_.PtrNone()).IgnoreError();
32*ec63e07aSXin Li }
33*ec63e07aSXin Li }
34*ec63e07aSXin Li
CheckIsInit()35*ec63e07aSXin Li absl::Status LibRaw::CheckIsInit() { return init_status_; }
36*ec63e07aSXin Li
IsInit()37*ec63e07aSXin Li bool LibRaw::IsInit() { return CheckIsInit().ok(); }
38*ec63e07aSXin Li
GetImgData()39*ec63e07aSXin Li libraw_data_t LibRaw::GetImgData() { return sapi_libraw_data_t_.data(); }
40*ec63e07aSXin Li
OpenFile()41*ec63e07aSXin Li absl::Status LibRaw::OpenFile() {
42*ec63e07aSXin Li SAPI_RETURN_IF_ERROR(CheckIsInit());
43*ec63e07aSXin Li
44*ec63e07aSXin Li sapi::v::CStr file_name(file_name_.c_str());
45*ec63e07aSXin Li
46*ec63e07aSXin Li SAPI_ASSIGN_OR_RETURN(int error_code,
47*ec63e07aSXin Li api_.libraw_open_file(sapi_libraw_data_t_.PtrAfter(),
48*ec63e07aSXin Li file_name.PtrBefore()));
49*ec63e07aSXin Li
50*ec63e07aSXin Li if (error_code != LIBRAW_SUCCESS) {
51*ec63e07aSXin Li return absl::UnavailableError(
52*ec63e07aSXin Li absl::string_view(std::to_string(error_code)));
53*ec63e07aSXin Li }
54*ec63e07aSXin Li
55*ec63e07aSXin Li return absl::OkStatus();
56*ec63e07aSXin Li }
57*ec63e07aSXin Li
Unpack()58*ec63e07aSXin Li absl::Status LibRaw::Unpack() {
59*ec63e07aSXin Li SAPI_RETURN_IF_ERROR(CheckIsInit());
60*ec63e07aSXin Li
61*ec63e07aSXin Li SAPI_ASSIGN_OR_RETURN(int error_code,
62*ec63e07aSXin Li api_.libraw_unpack(sapi_libraw_data_t_.PtrAfter()));
63*ec63e07aSXin Li if (error_code != LIBRAW_SUCCESS) {
64*ec63e07aSXin Li return absl::UnavailableError(
65*ec63e07aSXin Li absl::string_view(std::to_string(error_code)));
66*ec63e07aSXin Li }
67*ec63e07aSXin Li
68*ec63e07aSXin Li return absl::OkStatus();
69*ec63e07aSXin Li }
70*ec63e07aSXin Li
SubtractBlack()71*ec63e07aSXin Li absl::Status LibRaw::SubtractBlack() {
72*ec63e07aSXin Li SAPI_RETURN_IF_ERROR(CheckIsInit());
73*ec63e07aSXin Li
74*ec63e07aSXin Li return api_.libraw_subtract_black(sapi_libraw_data_t_.PtrAfter());
75*ec63e07aSXin Li }
76*ec63e07aSXin Li
GetCameraList()77*ec63e07aSXin Li absl::StatusOr<std::vector<char*>> LibRaw::GetCameraList() {
78*ec63e07aSXin Li SAPI_RETURN_IF_ERROR(CheckIsInit());
79*ec63e07aSXin Li
80*ec63e07aSXin Li int size;
81*ec63e07aSXin Li SAPI_ASSIGN_OR_RETURN(size, api_.libraw_cameraCount());
82*ec63e07aSXin Li
83*ec63e07aSXin Li std::vector<char*> buf(size);
84*ec63e07aSXin Li sapi::v::Array<char*> camera_list(buf.data(), buf.size());
85*ec63e07aSXin Li
86*ec63e07aSXin Li char** sapi_camera_list;
87*ec63e07aSXin Li SAPI_ASSIGN_OR_RETURN(sapi_camera_list, api_.libraw_cameraList());
88*ec63e07aSXin Li
89*ec63e07aSXin Li camera_list.SetRemote(sapi_camera_list);
90*ec63e07aSXin Li SAPI_RETURN_IF_ERROR(sandbox_->TransferFromSandboxee(&camera_list));
91*ec63e07aSXin Li
92*ec63e07aSXin Li return buf;
93*ec63e07aSXin Li }
94*ec63e07aSXin Li
COLOR(int row,int col)95*ec63e07aSXin Li absl::StatusOr<int> LibRaw::COLOR(int row, int col) {
96*ec63e07aSXin Li SAPI_RETURN_IF_ERROR(CheckIsInit());
97*ec63e07aSXin Li
98*ec63e07aSXin Li int color;
99*ec63e07aSXin Li SAPI_ASSIGN_OR_RETURN(
100*ec63e07aSXin Li color, api_.libraw_COLOR(sapi_libraw_data_t_.PtrNone(), row, col));
101*ec63e07aSXin Li
102*ec63e07aSXin Li return color;
103*ec63e07aSXin Li }
104*ec63e07aSXin Li
GetRawHeight()105*ec63e07aSXin Li absl::StatusOr<int> LibRaw::GetRawHeight() {
106*ec63e07aSXin Li SAPI_RETURN_IF_ERROR(CheckIsInit());
107*ec63e07aSXin Li
108*ec63e07aSXin Li ushort height;
109*ec63e07aSXin Li SAPI_ASSIGN_OR_RETURN(
110*ec63e07aSXin Li height, api_.libraw_get_raw_height(sapi_libraw_data_t_.PtrNone()));
111*ec63e07aSXin Li
112*ec63e07aSXin Li return height;
113*ec63e07aSXin Li }
114*ec63e07aSXin Li
GetRawWidth()115*ec63e07aSXin Li absl::StatusOr<int> LibRaw::GetRawWidth() {
116*ec63e07aSXin Li SAPI_RETURN_IF_ERROR(CheckIsInit());
117*ec63e07aSXin Li
118*ec63e07aSXin Li ushort width;
119*ec63e07aSXin Li SAPI_ASSIGN_OR_RETURN(
120*ec63e07aSXin Li width, api_.libraw_get_raw_width(sapi_libraw_data_t_.PtrNone()));
121*ec63e07aSXin Li
122*ec63e07aSXin Li return width;
123*ec63e07aSXin Li }
124*ec63e07aSXin Li
GetCBlack(int channel)125*ec63e07aSXin Li absl::StatusOr<unsigned int> LibRaw::GetCBlack(int channel) {
126*ec63e07aSXin Li SAPI_RETURN_IF_ERROR(CheckIsInit());
127*ec63e07aSXin Li
128*ec63e07aSXin Li if (channel < 0 || channel >= LIBRAW_CBLACK_SIZE) {
129*ec63e07aSXin Li return absl::OutOfRangeError(absl::StrCat(
130*ec63e07aSXin Li channel, " is out of range for array with size ", LIBRAW_CBLACK_SIZE));
131*ec63e07aSXin Li }
132*ec63e07aSXin Li
133*ec63e07aSXin Li return GetImgData().color.cblack[channel];
134*ec63e07aSXin Li
135*ec63e07aSXin Li ushort width;
136*ec63e07aSXin Li SAPI_ASSIGN_OR_RETURN(
137*ec63e07aSXin Li width, api_.libraw_get_raw_width(sapi_libraw_data_t_.PtrNone()));
138*ec63e07aSXin Li
139*ec63e07aSXin Li return width;
140*ec63e07aSXin Li }
141*ec63e07aSXin Li
GetColorCount()142*ec63e07aSXin Li int LibRaw::GetColorCount() { return GetImgData().idata.colors; }
143*ec63e07aSXin Li
RawData()144*ec63e07aSXin Li absl::StatusOr<std::vector<uint16_t>> LibRaw::RawData() {
145*ec63e07aSXin Li SAPI_RETURN_IF_ERROR(CheckIsInit());
146*ec63e07aSXin Li
147*ec63e07aSXin Li int raw_height;
148*ec63e07aSXin Li int raw_width;
149*ec63e07aSXin Li SAPI_ASSIGN_OR_RETURN(raw_height, GetRawHeight());
150*ec63e07aSXin Li SAPI_ASSIGN_OR_RETURN(raw_width, GetRawWidth());
151*ec63e07aSXin Li int size = raw_height * raw_width;
152*ec63e07aSXin Li std::vector<uint16_t> buf(size);
153*ec63e07aSXin Li sapi::v::Array<uint16_t> rawdata(buf.data(), buf.size());
154*ec63e07aSXin Li
155*ec63e07aSXin Li rawdata.SetRemote(sapi_libraw_data_t_.data().rawdata.raw_image);
156*ec63e07aSXin Li SAPI_RETURN_IF_ERROR(sandbox_->TransferFromSandboxee(&rawdata));
157*ec63e07aSXin Li
158*ec63e07aSXin Li return buf;
159*ec63e07aSXin Li }
160