Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
808 changes: 321 additions & 487 deletions Code/png_cicp_editor/Actions.cpp

Large diffs are not rendered by default.

149 changes: 56 additions & 93 deletions Code/png_cicp_editor/Actions.hpp
Original file line number Diff line number Diff line change
@@ -1,93 +1,56 @@
// Copyright 2025, The png_cicp_editor Contributors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef PNG_CICP_EDITOR_ACTIONS_HPP
#define PNG_CICP_EDITOR_ACTIONS_HPP

#include <string>

#include "CICP.hpp"

namespace PNG_CICP_Editor {

enum class Actions {
Version,
Help,
License,
Add,
Overwrite,
Remove,
};

struct VersionAction {
void operator()() const noexcept;
};

struct HelpAction {
void operator()() const noexcept;
};

struct LicenseAction {
void operator()() const noexcept;
};

struct AddAction {
explicit AddAction(CICP cicp, std::string file_path) noexcept;

void operator()() const noexcept;

CICP cicp_;
std::string file_path_;
};

struct OverwriteAction {
explicit OverwriteAction(CICP cicp, std::string file_path) noexcept;

void operator()() const noexcept;

CICP cicp_;
std::string file_path_;
};

struct RemoveAction {
explicit RemoveAction(std::string file_path) noexcept;

void operator()() const noexcept;

std::string file_path_;
};

struct Action {

explicit Action(VersionAction version) noexcept;
explicit Action(HelpAction help) noexcept;
explicit Action(LicenseAction license) noexcept;
explicit Action(AddAction add) noexcept;
explicit Action(OverwriteAction overwrite) noexcept;
explicit Action(RemoveAction remove) noexcept;

Action(const Action& rhs) noexcept;
Action(Action&& rhs) noexcept;

~Action() noexcept;

Action& operator =(const Action& rhs) noexcept;
Action& operator =(Action&& rhs) noexcept;

Actions action_type_;
union A {
VersionAction version_;
HelpAction help_;
LicenseAction license_;
AddAction add_;
OverwriteAction overwrite_;
RemoveAction remove_;

~A() noexcept;
} action_;
};

} // namespace PNG_CICP_Editor

#endif // #ifndef PNG_CICP_EDITOR_ACTIONS_HPP
// Copyright 2025, The png_cicp_editor Contributors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef PNG_CICP_EDITOR_ACTIONS_HPP
#define PNG_CICP_EDITOR_ACTIONS_HPP

#include <string>
#include <variant>

#include "CICP.hpp"

namespace PNG_CICP_Editor {

struct VersionAction {};

struct HelpAction {};

struct LicenseAction {};

struct AddAction {
explicit AddAction(CICP cicp, std::string file_path) noexcept;

CICP cicp_;
std::string file_path_;
};

struct OverwriteAction {
explicit OverwriteAction(CICP cicp, std::string file_path) noexcept;

CICP cicp_;
std::string file_path_;
};

struct RemoveAction {
explicit RemoveAction(std::string file_path) noexcept;

std::string file_path_;
};

using Action = std::variant<VersionAction, HelpAction, LicenseAction, AddAction, OverwriteAction, RemoveAction>;

struct ActionExecutor {

void operator()(const PNG_CICP_Editor::VersionAction& action) const noexcept;
void operator()(const PNG_CICP_Editor::HelpAction& action) const noexcept;
void operator()(const PNG_CICP_Editor::LicenseAction& action) const noexcept;
void operator()(const PNG_CICP_Editor::AddAction& action) const noexcept;
void operator()(const PNG_CICP_Editor::OverwriteAction& action) const noexcept;
void operator()(const PNG_CICP_Editor::RemoveAction& action) const noexcept;

};

} // namespace PNG_CICP_Editor

#endif // #ifndef PNG_CICP_EDITOR_ACTIONS_HPP
196 changes: 108 additions & 88 deletions Code/png_cicp_editor/CICPCreator.cpp
Original file line number Diff line number Diff line change
@@ -1,88 +1,108 @@
// Copyright 2025, The png_cicp_editor Contributors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "CICPCreator.hpp"

namespace {

// TODO: This implementation is ripped directly from the example CRC implementation in the spec:
// https://w3c.github.io/png/#samplecrc
// Surely, there is a better way for this use case.
unsigned long crc_table[256];
int crc_table_computed = 0;

void make_crc_table() noexcept {
unsigned long c;
int n, k;

for (n = 0; n < 256; n++) {
c = (unsigned long)n;
for (k = 0; k < 8; k++) {
if (c & 1) {
c = 0xedb88320L ^ (c >> 1);
}
else {
c = c >> 1;
}
}
crc_table[n] = c;
}
crc_table_computed = 1;
}

unsigned long update_crc(unsigned long crc, char* buf, int len) noexcept {
unsigned long c = crc;
int n;

if (!crc_table_computed) {
make_crc_table();
}

for (n = 0; n < len; n++) {
c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
}

return c;
}

unsigned long crc(char* buf, int len) noexcept {
return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL;
}

} // anonymous namespace

namespace PNG_CICP_Editor {

std::array<char, 16> create_cicp_buffer(const CICP& cicp) noexcept {
std::array<char, 16> buffer;

// length
buffer[0] = 0;
buffer[1] = 0;
buffer[2] = 0;
buffer[3] = 4;

// chunk type
buffer[4] = 'c';
buffer[5] = 'I';
buffer[6] = 'C';
buffer[7] = 'P';

// chunk data
buffer[8] = cicp.color_primaries_;
buffer[9] = cicp.transfer_function_;
buffer[10] = cicp.matrix_coefficients_;
buffer[11] = cicp.video_full_range_flag_;

// crc
unsigned long calculated_crc = crc(&buffer[4], 8);
buffer[12] = static_cast<char>(calculated_crc >> 24);
buffer[13] = static_cast<char>(calculated_crc >> 16);
buffer[14] = static_cast<char>(calculated_crc >> 8);
buffer[15] = static_cast<char>(calculated_crc >> 0);

return buffer;
}

} // namespace PNG_CICP_Editor
// Copyright 2025, The png_cicp_editor Contributors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "CICPCreator.hpp"

namespace {

// TODO: This implementation is ripped directly from the example CRC implementation in the spec:
// https://w3c.github.io/png/#samplecrc
// Surely, there is a better way for this use case.
unsigned long crc_table[256];
int crc_table_computed = 0;

void make_crc_table() noexcept {
unsigned long c;
int n, k;

for (n = 0; n < 256; n++) {
c = (unsigned long)n;
for (k = 0; k < 8; k++) {
if (c & 1) {
c = 0xedb88320L ^ (c >> 1);
}
else {
c = c >> 1;
}
}
crc_table[n] = c;
}
crc_table_computed = 1;
}

unsigned long update_crc(unsigned long crc, char* buf, int len) noexcept {
unsigned long c = crc;
int n;

if (!crc_table_computed) {
make_crc_table();
}

for (n = 0; n < len; n++) {
c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
}

return c;
}

unsigned long crc(char* buf, int len) noexcept {
return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL;
}

// https://www.youtube.com/watch?v=m7PVZixO35c
unsigned computer_crc32(unsigned char* data, int length, int* zerop) noexcept {
uint32_t crc = 0xffffffff;
const uint32_t polynomial = 0xedb88320;

int zeroes = 0;
int i, j;
for (i = 0; i < length; i++) {
crc ^= data[i];
for (j = 0; j < 8; j++) {
// Do it without branching, use boolean operations to xor with the
// polynomial or zero depending on whether last bit is set
//zeroes += (1-(crc & 1));
crc = (crc >> 1) ^ ((0-(crc & 1)) & polynomial);
}
}
*zerop = zeroes;
return crc;
}

} // anonymous namespace

namespace PNG_CICP_Editor {

std::array<char, 16> create_cicp_buffer(const CICP& cicp) noexcept {
std::array<char, 16> buffer;

// length
buffer[0] = 0;
buffer[1] = 0;
buffer[2] = 0;
buffer[3] = 4;

// chunk type
buffer[4] = 'c';
buffer[5] = 'I';
buffer[6] = 'C';
buffer[7] = 'P';

// chunk data
buffer[8] = cicp.color_primaries_;
buffer[9] = cicp.transfer_function_;
buffer[10] = cicp.matrix_coefficients_;
buffer[11] = cicp.video_full_range_flag_;

// crc
unsigned long calculated_crc = crc(&buffer[4], 8);
buffer[12] = static_cast<char>(calculated_crc >> 24);
buffer[13] = static_cast<char>(calculated_crc >> 16);
buffer[14] = static_cast<char>(calculated_crc >> 8);
buffer[15] = static_cast<char>(calculated_crc >> 0);

return buffer;
}

} // namespace PNG_CICP_Editor
Loading
Loading