Skip to content

Commit

Permalink
Major update in LytroDecoder to get all reading and decoding logic fr…
Browse files Browse the repository at this point in the history
…om LytroFile
  • Loading branch information
mtouzot committed Dec 3, 2023
1 parent 9ca41ef commit 90be3eb
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 64 deletions.
35 changes: 35 additions & 0 deletions include/lytroio/lytrostream/lytrodecoder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,39 @@

#include <fstream>
#include <lytroio/lytrostream/lytroelement.hpp>
#include <map>
#include <vector>

#define LYTRO_STEP 16
#define LYTRO_HEADER 8
#define LYTRO_VERSION 4
#define LYTRO_LENGTH 4
#define LYTRO_SHA1 45
#define LYTRO_SHA1_PADDING 35

namespace lytroio
{
class LytroDecoder
{
typedef std::map<std::string_view, LytroElement::LytroElementType>
LytroHeaderType_t;

public:
/**
* @brief Read all buffer to construct a pointer to a vector of LytroElement
*
* @return a pointer to a vector of LytroElement
*/
std::vector<LytroElement> *read (std::string data_buffer);

/**
* @brief Read the buffer from position indexed by pos to construct a
* LytroElement
*
* @return a LytroElement
*/
LytroElement read_next_element (std::string data_buffer, size_t &pos);

/**
* @brief Decode LytroElement data to human readable data
*
Expand Down Expand Up @@ -71,6 +98,14 @@ class LytroDecoder
* @return true if LytroElement's data contains png, false otherwire
*/
bool contains_png (std::string data, size_t &begin);

LytroHeaderType_t allowed_headers_
= { { "\x89\x4c\x46\x50\x0D\x0A\x1A\x0A",
LytroElement::LytroElementType::LFP },
{ "\x89\x4c\x46\x43\x0D\x0A\x1A\x0A",
LytroElement::LytroElementType::LFC },
{ "\x89\x4c\x46\x4D\x0D\x0A\x1A\x0A",
LytroElement::LytroElementType::LFM } };
};
} // namespace lytroio

Expand Down
49 changes: 49 additions & 0 deletions src/lytrostream/lytrodecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,55 @@ namespace lytroio
{
using json = nlohmann::json;

std::vector<LytroElement> *
LytroDecoder::read (std::string data_buffer)
{
std::vector<LytroElement> *elements = new std::vector<LytroElement> ();
size_t current_position = 0;

while (current_position < data_buffer.length ())
{
elements->push_back (read_next_element (data_buffer, current_position));
}
return elements;
}

LytroElement
LytroDecoder::read_next_element (std::string data_buffer, size_t &pos)
{
LytroElement element = LytroElement ();
std::string header_type = data_buffer.substr (pos, LYTRO_HEADER);
pos += LYTRO_HEADER;
element.set_type (allowed_headers_[header_type]);

// version
std::string version_str = data_buffer.substr (pos, LYTRO_VERSION);
int version = bitsToInt (&version_str[0], LYTRO_VERSION);
pos += LYTRO_VERSION;
element.set_version (version);

// lenght
std::string length_str = data_buffer.substr (pos, LYTRO_LENGTH);
int length = bitsToInt (&length_str[0], LYTRO_LENGTH);
pos += LYTRO_LENGTH;
element.set_length (length);

if (length > 0)
{
// SHA-1
std::string sha_str = data_buffer.substr (pos, LYTRO_SHA1);
pos += LYTRO_SHA1 + LYTRO_SHA1_PADDING;
element.set_sha (sha_str);

// data
std::string data_str = data_buffer.substr (pos, element.length ());
pos += length + missingBits (length, LYTRO_STEP);
element.set_data (data_str);
}

return element;
}

void
LytroDecoder::decode (LytroElement *element, int element_idx)
{
Expand Down
73 changes: 9 additions & 64 deletions src/lytrostream/lytrofile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ LytroFile::~LytroFile ()
bool
LytroFile::read ()
{
std::string_view lfp_header{ "\x89\x4c\x46\x50\x0D\x0A\x1A\x0A" };
std::string_view lfc_header{ "\x89\x4c\x46\x43\x0D\x0A\x1A\x0A" };
std::string_view lfm_header{ "\x89\x4c\x46\x4D\x0D\x0A\x1A\x0A" };

std::ifstream file (this->filename_,
std::ios::in | std::ios::binary | std::ios::ate);

Expand All @@ -34,67 +30,15 @@ LytroFile::read ()

int current_position = 0;
int len = file.tellg ();
std::string data_buffer_temp (len, ' ');

while (current_position < len)
{
file.seekg (current_position, std::ios::beg);
char data_buffer[LYTRO_HEADER];
if (!file.read (data_buffer, sizeof (data_buffer)))
return false;

unsigned int cmp_lfp = std::abs (lfp_header.compare (
0, lfp_header.length (), data_buffer, LYTRO_HEADER));
unsigned int cmp_lfc = std::abs (lfc_header.compare (
0, lfc_header.length (), data_buffer, LYTRO_HEADER));
unsigned int cmp_lfm = std::abs (lfm_header.compare (
0, lfm_header.length (), data_buffer, LYTRO_HEADER));
uint8_t type = ((cmp_lfp << 0) + (cmp_lfc << 1) + (cmp_lfm << 2));

if (cmp_lfp == 0 || cmp_lfm == 0 || cmp_lfc == 0)
{
LytroElement element = LytroElement (
static_cast<LytroElement::LytroElementType> (type));

current_position += LYTRO_HEADER;
file.seekg (current_position, std::ios::beg);
if (!file.read (data_buffer, sizeof (data_buffer)))
return false;

int version = bitsToInt (data_buffer, LYTRO_VERSION);
int length = bitsToInt (data_buffer, LYTRO_LENGTH, LYTRO_VERSION);
current_position += (LYTRO_VERSION + LYTRO_LENGTH);

element.set_version (version);
element.set_length (length);

if (length > 0)
{
file.seekg (current_position, std::ios::beg);
std::string sha (LYTRO_SHA1 * sizeof (char), ' ');
if (!file.read (&sha[0], LYTRO_SHA1 * sizeof (char)))
return false;

element.set_sha (sha);

current_position += LYTRO_SHA1 + LYTRO_SHA1_PADDING;

file.seekg (current_position, std::ios::beg);
size_t padded_length = length + missingBits (length, LYTRO_STEP);
std::string data (length * sizeof (char), ' ');
if (!file.read (&data[0], length * sizeof (char)))
return false;

current_position += padded_length;

element.set_data (data);
}
file.seekg (current_position, std::ios::beg);
file.read (&data_buffer_temp[0], len);
file.close ();

this->elements_->push_back (element);
}
}
this->elements_ = this->ldecoder_->read (data_buffer_temp);

file.close ();
return true;
return (this->elements_->front ().type () == "LFP");
}

void
Expand All @@ -105,10 +49,11 @@ LytroFile::decode ()
++iter_element)
{
std::cout << std::endl
<< "Decoding " << iter_element->type () << std::endl;
<< "Decoding [" << ++element_idx << "/"
<< this->elements_->size () << "] " << iter_element->type ()
<< std::endl;
this->ldecoder_->decode (&*iter_element, element_idx);
std::cout << std::endl;
element_idx++;
}
}
} // namespace lytroio

0 comments on commit 90be3eb

Please sign in to comment.