blob: 8d3cd00e805b8597f9c234bdf9ebca32224c94c9 [file] [log] [blame]
Dichen Zhang85b37562022-10-11 11:08:28 -07001/*
2 * Copyright 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dichen Zhang72fd2b12022-11-01 06:11:50 +000017#include "image_io/xml/xml_writer.h"
18
Dichen Zhang85b37562022-10-11 11:08:28 -070019#include <jpegrecoverymap/recoverymap.h>
Dichen Zhang72fd2b12022-11-01 06:11:50 +000020#include <sstream>
21#include <string>
22
23using namespace std;
Dichen Zhang85b37562022-10-11 11:08:28 -070024
25namespace android::recoverymap {
26
Dichen Zhang72fd2b12022-11-01 06:11:50 +000027/*
28 * Helper function used for generating XMP metadata.
29 *
30 * @param prefix The prefix part of the name.
31 * @param suffix The suffix part of the name.
32 * @return A name of the form "prefix:suffix".
33 */
34string Name(const string &prefix, const string &suffix) {
35 std::stringstream ss;
36 ss << prefix << ":" << suffix;
37 return ss.str();
38}
39
Dichen Zhang6947d532022-10-22 02:16:21 +000040status_t RecoveryMap::encodeJPEGR(jr_uncompressed_ptr uncompressed_p010_image,
41 jr_uncompressed_ptr uncompressed_yuv_420_image,
42 void* dest) {
43 if (uncompressed_p010_image == nullptr
44 || uncompressed_yuv_420_image == nullptr
45 || dest == nullptr) {
46 return BAD_VALUE;
47 }
48
49 // TBD
50 return NO_ERROR;
51}
52
53status_t RecoveryMap::encodeJPEGR(jr_uncompressed_ptr uncompressed_p010_image,
54 jr_uncompressed_ptr uncompressed_yuv_420_image,
55 void* compressed_jpeg_image,
56 void* dest) {
57
58 if (uncompressed_p010_image == nullptr
59 || uncompressed_yuv_420_image == nullptr
60 || compressed_jpeg_image == nullptr
61 || dest == nullptr) {
62 return BAD_VALUE;
63 }
64
65 // TBD
66 return NO_ERROR;
67}
68
69status_t RecoveryMap::encodeJPEGR(jr_uncompressed_ptr uncompressed_p010_image,
70 void* compressed_jpeg_image,
71 void* dest) {
72 if (uncompressed_p010_image == nullptr
73 || compressed_jpeg_image == nullptr
74 || dest == nullptr) {
75 return BAD_VALUE;
76 }
77
78 // TBD
79 return NO_ERROR;
80}
81
82status_t RecoveryMap::decodeJPEGR(void* compressed_jpegr_image, jr_uncompressed_ptr dest) {
83 if (compressed_jpegr_image == nullptr || dest == nullptr) {
84 return BAD_VALUE;
85 }
86
87 // TBD
88 return NO_ERROR;
89}
90
91status_t RecoveryMap::decodeRecoveryMap(jr_compressed_ptr compressed_recovery_map,
92 jr_uncompressed_ptr dest) {
Dichen Zhang596a7562022-10-12 14:57:05 -070093 if (compressed_recovery_map == nullptr || dest == nullptr) {
Dichen Zhang6947d532022-10-22 02:16:21 +000094 return BAD_VALUE;
Dichen Zhang596a7562022-10-12 14:57:05 -070095 }
96
97 // TBD
Dichen Zhang6947d532022-10-22 02:16:21 +000098 return NO_ERROR;
Dichen Zhang596a7562022-10-12 14:57:05 -070099}
100
Dichen Zhang6947d532022-10-22 02:16:21 +0000101status_t RecoveryMap::encodeRecoveryMap(jr_uncompressed_ptr uncompressed_recovery_map,
102 jr_compressed_ptr dest) {
Dichen Zhang596a7562022-10-12 14:57:05 -0700103 if (uncompressed_recovery_map == nullptr || dest == nullptr) {
Dichen Zhang6947d532022-10-22 02:16:21 +0000104 return BAD_VALUE;
Dichen Zhang596a7562022-10-12 14:57:05 -0700105 }
106
107 // TBD
Dichen Zhang6947d532022-10-22 02:16:21 +0000108 return NO_ERROR;
Dichen Zhang596a7562022-10-12 14:57:05 -0700109}
110
Dichen Zhang6947d532022-10-22 02:16:21 +0000111status_t RecoveryMap::generateRecoveryMap(jr_uncompressed_ptr uncompressed_yuv_420_image,
112 jr_uncompressed_ptr uncompressed_p010_image,
113 jr_uncompressed_ptr dest) {
Dichen Zhang596a7562022-10-12 14:57:05 -0700114 if (uncompressed_yuv_420_image == nullptr
115 || uncompressed_p010_image == nullptr
116 || dest == nullptr) {
Dichen Zhang6947d532022-10-22 02:16:21 +0000117 return BAD_VALUE;
Dichen Zhang596a7562022-10-12 14:57:05 -0700118 }
119
120 // TBD
Dichen Zhang6947d532022-10-22 02:16:21 +0000121 return NO_ERROR;
Dichen Zhang596a7562022-10-12 14:57:05 -0700122}
123
Dichen Zhang6947d532022-10-22 02:16:21 +0000124status_t RecoveryMap::applyRecoveryMap(jr_uncompressed_ptr uncompressed_yuv_420_image,
125 jr_uncompressed_ptr uncompressed_recovery_map,
126 jr_uncompressed_ptr dest) {
Dichen Zhang596a7562022-10-12 14:57:05 -0700127 if (uncompressed_yuv_420_image == nullptr
128 || uncompressed_recovery_map == nullptr
129 || dest == nullptr) {
Dichen Zhang6947d532022-10-22 02:16:21 +0000130 return BAD_VALUE;
Dichen Zhang596a7562022-10-12 14:57:05 -0700131 }
132
133 // TBD
Dichen Zhang6947d532022-10-22 02:16:21 +0000134 return NO_ERROR;
Dichen Zhang596a7562022-10-12 14:57:05 -0700135}
136
Dichen Zhang6947d532022-10-22 02:16:21 +0000137status_t RecoveryMap::extractRecoveryMap(void* compressed_jpegr_image, jr_compressed_ptr dest) {
138 if (compressed_jpegr_image == nullptr || dest == nullptr) {
139 return BAD_VALUE;
Dichen Zhang85b37562022-10-11 11:08:28 -0700140 }
141
142 // TBD
Dichen Zhang6947d532022-10-22 02:16:21 +0000143 return NO_ERROR;
Dichen Zhang85b37562022-10-11 11:08:28 -0700144}
145
Dichen Zhang6947d532022-10-22 02:16:21 +0000146status_t RecoveryMap::appendRecoveryMap(void* compressed_jpeg_image,
147 jr_compressed_ptr compressed_recovery_map,
148 void* dest) {
149 if (compressed_jpeg_image == nullptr
150 || compressed_recovery_map == nullptr
151 || dest == nullptr) {
152 return BAD_VALUE;
Dichen Zhang85b37562022-10-11 11:08:28 -0700153 }
154
155 // TBD
Dichen Zhang6947d532022-10-22 02:16:21 +0000156 return NO_ERROR;
Dichen Zhang85b37562022-10-11 11:08:28 -0700157}
158
Dichen Zhang72fd2b12022-11-01 06:11:50 +0000159string RecoveryMap::generateXmp(int secondary_image_length, float hdr_ratio) {
160 const string kContainerPrefix = "GContainer";
161 const string kContainerUri = "http://ns.google.com/photos/1.0/container/";
162 const string kItemPrefix = "Item";
163 const string kRecoveryMap = "RecoveryMap";
164 const string kDirectory = "Directory";
165 const string kImageJpeg = "image/jpeg";
166 const string kItem = "Item";
167 const string kLength = "Length";
168 const string kMime = "Mime";
169 const string kPrimary = "Primary";
170 const string kSemantic = "Semantic";
171 const string kVersion = "Version";
172 const int kVersionValue = 1;
173
174 const string kConDir = Name(kContainerPrefix, kDirectory);
175 const string kContainerItem = Name(kContainerPrefix, kItem);
176 const string kItemLength = Name(kItemPrefix, kLength);
177 const string kItemMime = Name(kItemPrefix, kMime);
178 const string kItemSemantic = Name(kItemPrefix, kSemantic);
179
180 const vector<string> kConDirSeq({kConDir, string("rdf:Seq")});
181 const vector<string> kLiItem({string("rdf:li"), kContainerItem});
182
183 std::stringstream ss;
184 photos_editing_formats::image_io::XmlWriter writer(ss);
185 writer.StartWritingElement("x:xmpmeta");
186 writer.WriteXmlns("x", "adobe:ns:meta/");
187 writer.WriteAttributeNameAndValue("x:xmptk", "Adobe XMP Core 5.1.2");
188 writer.StartWritingElement("rdf:RDF");
189 writer.WriteXmlns("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
190 writer.StartWritingElement("rdf:Description");
191 writer.WriteXmlns(kContainerPrefix, kContainerUri);
192 writer.WriteElementAndContent(Name(kContainerPrefix, kVersion), kVersionValue);
193 writer.WriteElementAndContent(Name(kContainerPrefix, "HdrRatio"), hdr_ratio);
194 writer.StartWritingElements(kConDirSeq);
195 size_t item_depth = writer.StartWritingElements(kLiItem);
196 writer.WriteAttributeNameAndValue(kItemSemantic, kPrimary);
197 writer.WriteAttributeNameAndValue(kItemMime, kImageJpeg);
198 writer.FinishWritingElementsToDepth(item_depth);
199 writer.StartWritingElements(kLiItem);
200 writer.WriteAttributeNameAndValue(kItemSemantic, kRecoveryMap);
201 writer.WriteAttributeNameAndValue(kItemMime, kImageJpeg);
202 writer.WriteAttributeNameAndValue(kItemLength, secondary_image_length);
203 writer.FinishWriting();
204
205 return ss.str();
206}
207
Dichen Zhang85b37562022-10-11 11:08:28 -0700208} // namespace android::recoverymap