blob: 2da3eee26c72a31b9a81452b2dbf1ff855be160d [file] [edit]
// 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_