| // Copyright 2026 Google LLC | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // https://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| // | |
| #ifndef THIRD_PARTY_CREDENTIO_FORMATS_JPEG_HASHER_H_ | |
| #define THIRD_PARTY_CREDENTIO_FORMATS_JPEG_HASHER_H_ | |
| #include <cstdint> | |
| #include <optional> | |
| #include <vector> | |
| #include "absl/functional/function_ref.h" | |
| #include "absl/status/statusor.h" | |
| #include "absl/strings/str_format.h" | |
| #include "crypto/algorithms.h" | |
| #include "formats/byte_range.h" | |
| #include "formats/jpeg/reader.h" | |
| #include "proto/data_hash_assertion.pb.h" | |
| #include "proto/generator.pb.h" | |
| #include "proto/multi_asset_hash_assertion.pb.h" | |
| #include "riegeli/bytes/reader.h" | |
| namespace credentio { | |
| struct JpegInsertionPoint { | |
| uint16_t segment_id = 0; | |
| uint64_t offset = 0; | |
| friend bool operator==(const JpegInsertionPoint&, | |
| const JpegInsertionPoint&) = default; | |
| template <typename Sink> | |
| friend void AbslStringify(Sink& sink, const JpegInsertionPoint& point) { | |
| absl::Format(&sink, "JpegInsertionPoint{segment_id: %u, offset: %u}", | |
| point.segment_id, point.offset); | |
| } | |
| }; | |
| struct DigestJpegResult { | |
| HardBinding hard_binding; | |
| JpegInsertionPoint insertion_point; | |
| }; | |
| // Determines byte ranges within a given JPEG segment to be excluded from | |
| // hashing. Returned ByteRange offsets must be absolute file offsets within | |
| // [segment.offset, segment.offset + segment.length). | |
| using JpegExclusionProcessor = | |
| absl::FunctionRef<absl::StatusOr<std::vector<ByteRange>>( | |
| riegeli::Reader& reader, const JpegSegment& segment)>; | |
| // Digests the given JPEG image and returns a DigestJpegResult that can be | |
| // used to generate a C2PA manifest store. | |
| // | |
| // The result will contain a Data Hash Assertion, the offset at | |
| // which to inject the C2PA data, and the segment ID to use. If the asset | |
| // contains additional data beyond the initial JPEG's EOI tag it will also | |
| // contain a MultiAssetHashAssertion and a vector of Data Hash Assertions for | |
| // each found part of the file. | |
| // | |
| // Setting `generate_multi_asset_hash` to true will cause a multi-asset hash | |
| // assertion to be included if the input contains data after EOI. Non-JPEG | |
| // parts (e.g., an Android Motion Photo video) will be marked as optional. | |
| // | |
| // If `exclusion_processor` is provided, it is invoked for segments to identify | |
| // byte ranges to exclude from hashing. | |
| absl::StatusOr<DigestJpegResult> DigestJpeg( | |
| riegeli::Reader& input, HashAlgorithm alg, bool generate_multi_asset_hash, | |
| std::optional<JpegExclusionProcessor> exclusion_processor = std::nullopt); | |
| } // namespace credentio | |
| #endif // THIRD_PARTY_CREDENTIO_FORMATS_JPEG_HASHER_H_ |