Skip to content

Commit

Permalink
add deep id/manifest tools and docs
Browse files Browse the repository at this point in the history
Signed-off-by: Peter Hillman <[email protected]>
  • Loading branch information
peterhillman committed Dec 11, 2023
1 parent 9be75dc commit aed7f0d
Show file tree
Hide file tree
Showing 8 changed files with 1,794 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/bin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ if(OPENEXR_BUILD_TOOLS)
add_subdirectory( exrmultiview )
add_subdirectory( exrmultipart )
add_subdirectory( exrcheck )
add_subdirectory( exrmanifest )
endif()
14 changes: 14 additions & 0 deletions src/bin/exrmanifest/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) Contributors to the OpenEXR Project.

add_executable(exrmanifest main.cpp)
target_link_libraries(exrmanifest OpenEXR::OpenEXR)
set_target_properties(exrmanifest PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
if(OPENEXR_INSTALL_TOOLS)
install(TARGETS exrmanifest DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
if(WIN32 AND BUILD_SHARED_LIBS)
target_compile_definitions(exrmanifest PRIVATE OPENEXR_DLL)
endif()
210 changes: 210 additions & 0 deletions src/bin/exrmanifest/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@

//
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) Contributors to the OpenEXR Project.
//

//
// output all the idmanifest information found in the file as plain text
//

#include <ImfMisc.h>
#include <ImfMultiPartInputFile.h>
#include <ImfIDManifestAttribute.h>
#include <ImfStandardAttributes.h>

#include <iostream>
#include <vector>
#include <string>

using namespace OPENEXR_IMF_NAMESPACE;

using std::cerr;
using std::cout;
using std::endl;
using std::exception;
using std::max;
using std::ostream;
using std::set;
using std::string;
using std::to_string;
using std::vector;

size_t
dumpManifest (const IDManifest& mfst)
{

size_t uncompressedSize = 0;

for (size_t i = 0; i < mfst.size (); ++i)
{
const IDManifest::ChannelGroupManifest& m = mfst[i];
bool first = true;
if (i > 0) { cout << "\n\n"; }
cout << " channels : ";
for (set<string>::const_iterator s = m.getChannels ().begin ();
s != m.getChannels ().end ();
++s)
{
if (!first) { cout << ','; }
else { first = false; }

cout << *s;
uncompressedSize += s->size () + 1;
}

cout << "\n hashScheme: " << m.getHashScheme () << endl;
cout << " encoding : " << m.getEncodingScheme () << endl;
switch (m.getLifetime ())
{
case IDManifest::LIFETIME_FRAME:
cout << " lifetime : frame\n";
break;
case IDManifest::LIFETIME_SHOT:
cout << " lifetime : shot\n";
break;
case IDManifest::LIFETIME_STABLE:
cout << " lifetime : stable\n";
break;
}

//
// compute max field sizes
//
size_t maxNumLen = 0;
vector<size_t> componentLength (m.getComponents ().size ());
for (size_t c = 0; c < m.getComponents ().size (); ++c)
{
size_t componentSize = m.getComponents ()[c].size ();
uncompressedSize += componentSize + 1;
componentLength[c] = max (componentLength[c], componentSize);
}
for (IDManifest::ChannelGroupManifest::ConstIterator q = m.begin ();
q != m.end ();
++q)
{

size_t stringLen = to_string (q.id ()).size ();
uncompressedSize += stringLen;
maxNumLen = max (maxNumLen, stringLen);

for (size_t i = 0; i < q.text ().size (); i++)
{
uncompressedSize += q.text ()[i].size () + 1;
componentLength[i] =
max (componentLength[i], q.text ()[i].size ());
}
}

cout << " " << string (maxNumLen + 1, ' ');
for (size_t c = 0; c < m.getComponents ().size (); ++c)
{
string s = m.getComponents ()[c];
cout << s << string (componentLength[c] + 1 - s.size (), ' ');
}
cout << endl;
for (IDManifest::ChannelGroupManifest::ConstIterator q = m.begin ();
q != m.end ();
++q)
{
string id = to_string (q.id ());
cout << " " << id << string (maxNumLen + 1 - id.size (), ' ');
for (size_t i = 0; i < q.text ().size (); i++)
{
string s = q.text ()[i];
cout << s << string (componentLength[i] + 1 - s.size (), ' ');
}
cout << '\n';
}
}

return uncompressedSize;
}

void
printManifest (const char fileName[])
{

MultiPartInputFile in (fileName);
//
// extract objectID attribute
//

for (int part = 0; part < in.parts (); part++)
{
if (in.parts () > 1) { cout << fileName << " part " << part << ":\n"; }
if (hasIDManifest (in.header (part)))
{
const Imf::CompressedIDManifest& mfst =
idManifest (in.header (part));
size_t size = dumpManifest (mfst);
cout << "raw text size : " << size << endl;
cout << "uncompressed size: " << mfst._uncompressedDataSize << endl;
cout << "compressed size : " << mfst._compressedDataSize << endl;
}
else { cout << "no manifest found\n"; }
}
}

void
usageMessage (ostream& stream, const char* program_name, bool verbose = false)
{
stream << "Usage: " << program_name << " imagefile [imagefile ...]\n";

if (verbose)
stream
<< "\n"
"Read exr files and print the contents of the embedded manifest.\n"
"\n"
"Options:\n"
" -h, --help print this message\n"
" --version print version information\n"
"\n"
"Report bugs via https://github.com/AcademySoftwareFoundation/openexr/issues or email [email protected]\n"
"";
}

int
main (int argc, char* argv[])
{

if (argc < 2)
{
usageMessage (cerr, argv[0], false);
return -1;
}

for (int i = 1; i < argc; ++i)
{
if (!strcmp (argv[i], "-h") || !strcmp (argv[1], "--help"))
{
usageMessage (cout, "exrmanifest", true);
return 0;
}
else if (!strcmp (argv[i], "--version"))
{
const char* libraryVersion = getLibraryVersion ();

cout << "exrmanifest (OpenEXR) " << OPENEXR_VERSION_STRING;
if (strcmp (libraryVersion, OPENEXR_VERSION_STRING))
cout << "(OpenEXR version " << libraryVersion << ")";
cout << " https://openexr.com" << endl;
cout << "Copyright (c) Contributors to the OpenEXR Project" << endl;
cout << "License BSD-3-Clause" << endl;
return 0;
}
}

try
{
for (int i = 1; i < argc; ++i)
printManifest (argv[i]);
}
catch (const exception& e)
{
cerr << argv[0] << ": " << e.what () << endl;
return 1;
}

for (int i = 1; i < argc; ++i) {}
}
10 changes: 10 additions & 0 deletions src/examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ target_link_libraries(OpenEXRExamples OpenEXR::OpenEXR)
set_target_properties(OpenEXRExamples PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)

add_executable(deepidexample deepidexample.cpp)
target_link_libraries(deepidexample OpenEXR::OpenEXR)

add_executable(deepidselect deepidselect.cpp)
target_link_libraries(deepidselect OpenEXR::OpenEXR)




if(WIN32 AND BUILD_SHARED_LIBS)
target_compile_definitions(OpenEXRExamples PRIVATE OPENEXR_DLL)
endif()
Expand Down
Loading

0 comments on commit aed7f0d

Please sign in to comment.