This page hosts a formal specification of WebP using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.
All C++11/STL code generated by Kaitai Struct depends on the Kaitai Struct runtime library for C++/STL. You must add this dependency to your project before you can parse or serialize any data.
For C++, the easiest way is to clone the runtime library sources and build them along with your project.
Using Kaitai Struct in C++/STL usually consists of 3 steps.
std::istream). One can open local file for that, or use existing std::string or char* buffer.
#include <fstream>
std::ifstream is("path/to/local/file.webp", std::ifstream::binary);
#include <sstream>
std::istringstream is(str);
#include <sstream>
const char buf[] = { ... };
std::string str(buf, sizeof buf);
std::istringstream is(str);
#include "kaitai/kaitaistream.h"
kaitai::kstream ks(&is);
webp_t data(&ks);
After that, one can get various attributes from the structure by invoking getter methods like:
data.magic() // => get magic
#pragma once
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
class webp_t;
#include "kaitai/kaitaistruct.h"
#include <stdint.h>
#include <memory>
#include <set>
#include <vector>
#if KAITAI_STRUCT_VERSION < 11000L
#error "Incompatible Kaitai Struct C++/STL API: version 0.11 or later is required"
#endif
/**
* \sa https://developers.google.com/speed/webp/docs/riff_container Source
*/
class webp_t : public kaitai::kstruct {
public:
class alph_t;
class anim_t;
class anmf_t;
class chunk_t;
class chunks_t;
class vp8_t;
class vp8l_t;
class vp8x_t;
class xmp_t;
enum chunk_names_t {
CHUNK_NAMES_XMP_VAR = 5262680,
CHUNK_NAMES_VP8 = 540561494,
CHUNK_NAMES_XMP = 542133592,
CHUNK_NAMES_EXIF = 1179211845,
CHUNK_NAMES_ANMF = 1179471425,
CHUNK_NAMES_ALPH = 1213221953,
CHUNK_NAMES_VP8L = 1278758998,
CHUNK_NAMES_FRGM = 1296519750,
CHUNK_NAMES_ANIM = 1296649793,
CHUNK_NAMES_ICCP = 1346585417,
CHUNK_NAMES_VP8X = 1480085590
};
static bool _is_defined_chunk_names_t(chunk_names_t v);
private:
static const std::set<chunk_names_t> _values_chunk_names_t;
public:
enum compression_method_t {
COMPRESSION_METHOD_NONE = 0,
COMPRESSION_METHOD_WEBP_LOSSLESS = 1
};
static bool _is_defined_compression_method_t(compression_method_t v);
private:
static const std::set<compression_method_t> _values_compression_method_t;
public:
enum filtering_method_t {
FILTERING_METHOD_NONE = 0,
FILTERING_METHOD_HORIZONTAL = 1,
FILTERING_METHOD_VERTICAL = 2,
FILTERING_METHOD_GRADIENT = 3
};
static bool _is_defined_filtering_method_t(filtering_method_t v);
private:
static const std::set<filtering_method_t> _values_filtering_method_t;
public:
enum preprocessing_t {
PREPROCESSING_NONE = 0,
PREPROCESSING_LEVEL_REDUCTION = 1
};
static bool _is_defined_preprocessing_t(preprocessing_t v);
private:
static const std::set<preprocessing_t> _values_preprocessing_t;
public:
webp_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, webp_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~webp_t();
class alph_t : public kaitai::kstruct {
public:
alph_t(kaitai::kstream* p__io, webp_t::chunk_t* p__parent = nullptr, webp_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~alph_t();
private:
uint64_t m_reserved;
preprocessing_t m_preprocessing;
filtering_method_t m_filtering;
compression_method_t m_compression;
std::string m_data;
webp_t* m__root;
webp_t::chunk_t* m__parent;
public:
uint64_t reserved() const { return m_reserved; }
preprocessing_t preprocessing() const { return m_preprocessing; }
filtering_method_t filtering() const { return m_filtering; }
compression_method_t compression() const { return m_compression; }
std::string data() const { return m_data; }
webp_t* _root() const { return m__root; }
webp_t::chunk_t* _parent() const { return m__parent; }
};
/**
* \sa https://developers.google.com/speed/webp/docs/riff_container#animation Source
*/
class anim_t : public kaitai::kstruct {
public:
class bg_color_t;
anim_t(kaitai::kstream* p__io, webp_t::chunk_t* p__parent = nullptr, webp_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~anim_t();
class bg_color_t : public kaitai::kstruct {
public:
bg_color_t(kaitai::kstream* p__io, webp_t::anim_t* p__parent = nullptr, webp_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~bg_color_t();
private:
uint8_t m_blue;
uint8_t m_green;
uint8_t m_red;
uint8_t m_alpha;
webp_t* m__root;
webp_t::anim_t* m__parent;
public:
uint8_t blue() const { return m_blue; }
uint8_t green() const { return m_green; }
uint8_t red() const { return m_red; }
uint8_t alpha() const { return m_alpha; }
webp_t* _root() const { return m__root; }
webp_t::anim_t* _parent() const { return m__parent; }
};
private:
std::unique_ptr<bg_color_t> m_background_color;
uint16_t m_loop_count;
webp_t* m__root;
webp_t::chunk_t* m__parent;
public:
bg_color_t* background_color() const { return m_background_color.get(); }
uint16_t loop_count() const { return m_loop_count; }
webp_t* _root() const { return m__root; }
webp_t::chunk_t* _parent() const { return m__parent; }
};
class anmf_t : public kaitai::kstruct {
public:
anmf_t(kaitai::kstream* p__io, webp_t::chunk_t* p__parent = nullptr, webp_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~anmf_t();
private:
bool f_frame_height;
int32_t m_frame_height;
public:
int32_t frame_height();
private:
bool f_frame_width;
int32_t m_frame_width;
public:
int32_t frame_width();
private:
bool f_frame_x;
int32_t m_frame_x;
public:
int32_t frame_x();
private:
bool f_frame_y;
int32_t m_frame_y;
public:
int32_t frame_y();
private:
uint64_t m_frame_x_div_2;
uint64_t m_frame_y_div_2;
uint64_t m_frame_width_minus_1;
uint64_t m_frame_height_minus_1;
uint64_t m_duration;
uint64_t m_reserved;
bool m_blending_method;
bool m_disposal_method;
std::string m_data;
webp_t* m__root;
webp_t::chunk_t* m__parent;
public:
uint64_t frame_x_div_2() const { return m_frame_x_div_2; }
uint64_t frame_y_div_2() const { return m_frame_y_div_2; }
uint64_t frame_width_minus_1() const { return m_frame_width_minus_1; }
uint64_t frame_height_minus_1() const { return m_frame_height_minus_1; }
uint64_t duration() const { return m_duration; }
uint64_t reserved() const { return m_reserved; }
bool blending_method() const { return m_blending_method; }
bool disposal_method() const { return m_disposal_method; }
std::string data() const { return m_data; }
webp_t* _root() const { return m__root; }
webp_t::chunk_t* _parent() const { return m__parent; }
};
class chunk_t : public kaitai::kstruct {
public:
chunk_t(kaitai::kstream* p__io, webp_t::chunks_t* p__parent = nullptr, webp_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~chunk_t();
private:
chunk_names_t m_name;
uint32_t m_len_data;
std::unique_ptr<kaitai::kstruct> m_data;
bool n_data;
public:
bool _is_null_data() { data(); return n_data; };
private:
std::string m_padding;
bool n_padding;
public:
bool _is_null_padding() { padding(); return n_padding; };
private:
webp_t* m__root;
webp_t::chunks_t* m__parent;
std::string m__raw_data;
std::unique_ptr<kaitai::kstream> m__io__raw_data;
public:
chunk_names_t name() const { return m_name; }
uint32_t len_data() const { return m_len_data; }
kaitai::kstruct* data() const { return m_data.get(); }
std::string padding() const { return m_padding; }
webp_t* _root() const { return m__root; }
webp_t::chunks_t* _parent() const { return m__parent; }
std::string _raw_data() const { return m__raw_data; }
kaitai::kstream* _io__raw_data() const { return m__io__raw_data.get(); }
};
class chunks_t : public kaitai::kstruct {
public:
chunks_t(kaitai::kstream* p__io, webp_t* p__parent = nullptr, webp_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~chunks_t();
private:
std::unique_ptr<std::vector<std::unique_ptr<chunk_t>>> m_chunks;
webp_t* m__root;
webp_t* m__parent;
public:
std::vector<std::unique_ptr<chunk_t>>* chunks() const { return m_chunks.get(); }
webp_t* _root() const { return m__root; }
webp_t* _parent() const { return m__parent; }
};
/**
* \sa https://www.rfc-editor.org/rfc/rfc6386#section-9.1 Source
*/
class vp8_t : public kaitai::kstruct {
public:
vp8_t(kaitai::kstream* p__io, webp_t::chunk_t* p__parent = nullptr, webp_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~vp8_t();
private:
bool m_frame_type;
uint64_t m_version;
bool m_show_frame;
uint64_t m_len_first_partition;
std::string m_start_code;
uint64_t m_width;
uint64_t m_horizontal_scale;
uint64_t m_height;
uint64_t m_vertical_scale;
std::string m_data;
webp_t* m__root;
webp_t::chunk_t* m__parent;
public:
bool frame_type() const { return m_frame_type; }
uint64_t version() const { return m_version; }
bool show_frame() const { return m_show_frame; }
uint64_t len_first_partition() const { return m_len_first_partition; }
std::string start_code() const { return m_start_code; }
uint64_t width() const { return m_width; }
uint64_t horizontal_scale() const { return m_horizontal_scale; }
uint64_t height() const { return m_height; }
uint64_t vertical_scale() const { return m_vertical_scale; }
std::string data() const { return m_data; }
webp_t* _root() const { return m__root; }
webp_t::chunk_t* _parent() const { return m__parent; }
};
/**
* \sa https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification Source
*/
class vp8l_t : public kaitai::kstruct {
public:
vp8l_t(kaitai::kstream* p__io, webp_t::chunk_t* p__parent = nullptr, webp_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~vp8l_t();
private:
bool f_image_height;
int32_t m_image_height;
public:
int32_t image_height();
private:
bool f_image_width;
int32_t m_image_width;
public:
int32_t image_width();
private:
uint8_t m_signature;
uint64_t m_image_width_minus_1;
uint64_t m_image_height_minus_1;
bool m_alpha_is_used;
uint64_t m_version_number;
std::string m_data;
webp_t* m__root;
webp_t::chunk_t* m__parent;
public:
uint8_t signature() const { return m_signature; }
uint64_t image_width_minus_1() const { return m_image_width_minus_1; }
uint64_t image_height_minus_1() const { return m_image_height_minus_1; }
/**
* A hint only - it should not impact decoding. It should be `false` when
* all alpha values are 255 in the picture, and `true` otherwise.
*/
bool alpha_is_used() const { return m_alpha_is_used; }
uint64_t version_number() const { return m_version_number; }
std::string data() const { return m_data; }
webp_t* _root() const { return m__root; }
webp_t::chunk_t* _parent() const { return m__parent; }
};
class vp8x_t : public kaitai::kstruct {
public:
vp8x_t(kaitai::kstream* p__io, webp_t::chunk_t* p__parent = nullptr, webp_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~vp8x_t();
private:
bool f_canvas_height;
int32_t m_canvas_height;
public:
int32_t canvas_height();
private:
bool f_canvas_width;
int32_t m_canvas_width;
public:
int32_t canvas_width();
private:
uint64_t m_reserved1;
bool m_icc_profile;
bool m_alpha;
bool m_exif;
bool m_xmp;
bool m_animation;
bool m_reserved2;
uint64_t m_reserved3;
uint64_t m_canvas_width_minus_1;
uint64_t m_canvas_height_minus_1;
webp_t* m__root;
webp_t::chunk_t* m__parent;
public:
uint64_t reserved1() const { return m_reserved1; }
bool icc_profile() const { return m_icc_profile; }
bool alpha() const { return m_alpha; }
bool exif() const { return m_exif; }
bool xmp() const { return m_xmp; }
bool animation() const { return m_animation; }
bool reserved2() const { return m_reserved2; }
uint64_t reserved3() const { return m_reserved3; }
uint64_t canvas_width_minus_1() const { return m_canvas_width_minus_1; }
uint64_t canvas_height_minus_1() const { return m_canvas_height_minus_1; }
webp_t* _root() const { return m__root; }
webp_t::chunk_t* _parent() const { return m__parent; }
};
class xmp_t : public kaitai::kstruct {
public:
xmp_t(kaitai::kstream* p__io, webp_t::chunk_t* p__parent = nullptr, webp_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~xmp_t();
private:
std::string m_data;
webp_t* m__root;
webp_t::chunk_t* m__parent;
public:
std::string data() const { return m_data; }
webp_t* _root() const { return m__root; }
webp_t::chunk_t* _parent() const { return m__parent; }
};
private:
std::string m_magic;
uint32_t m_len_data;
std::string m_webp;
std::unique_ptr<chunks_t> m_payload;
webp_t* m__root;
kaitai::kstruct* m__parent;
std::string m__raw_payload;
std::unique_ptr<kaitai::kstream> m__io__raw_payload;
public:
std::string magic() const { return m_magic; }
uint32_t len_data() const { return m_len_data; }
std::string webp() const { return m_webp; }
chunks_t* payload() const { return m_payload.get(); }
webp_t* _root() const { return m__root; }
kaitai::kstruct* _parent() const { return m__parent; }
std::string _raw_payload() const { return m__raw_payload; }
kaitai::kstream* _io__raw_payload() const { return m__io__raw_payload.get(); }
};
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
#include "webp.h"
#include "kaitai/exceptions.h"
const std::set<webp_t::chunk_names_t> webp_t::_values_chunk_names_t{
webp_t::CHUNK_NAMES_XMP_VAR,
webp_t::CHUNK_NAMES_VP8,
webp_t::CHUNK_NAMES_XMP,
webp_t::CHUNK_NAMES_EXIF,
webp_t::CHUNK_NAMES_ANMF,
webp_t::CHUNK_NAMES_ALPH,
webp_t::CHUNK_NAMES_VP8L,
webp_t::CHUNK_NAMES_FRGM,
webp_t::CHUNK_NAMES_ANIM,
webp_t::CHUNK_NAMES_ICCP,
webp_t::CHUNK_NAMES_VP8X,
};
bool webp_t::_is_defined_chunk_names_t(webp_t::chunk_names_t v) {
return webp_t::_values_chunk_names_t.find(v) != webp_t::_values_chunk_names_t.end();
}
const std::set<webp_t::compression_method_t> webp_t::_values_compression_method_t{
webp_t::COMPRESSION_METHOD_NONE,
webp_t::COMPRESSION_METHOD_WEBP_LOSSLESS,
};
bool webp_t::_is_defined_compression_method_t(webp_t::compression_method_t v) {
return webp_t::_values_compression_method_t.find(v) != webp_t::_values_compression_method_t.end();
}
const std::set<webp_t::filtering_method_t> webp_t::_values_filtering_method_t{
webp_t::FILTERING_METHOD_NONE,
webp_t::FILTERING_METHOD_HORIZONTAL,
webp_t::FILTERING_METHOD_VERTICAL,
webp_t::FILTERING_METHOD_GRADIENT,
};
bool webp_t::_is_defined_filtering_method_t(webp_t::filtering_method_t v) {
return webp_t::_values_filtering_method_t.find(v) != webp_t::_values_filtering_method_t.end();
}
const std::set<webp_t::preprocessing_t> webp_t::_values_preprocessing_t{
webp_t::PREPROCESSING_NONE,
webp_t::PREPROCESSING_LEVEL_REDUCTION,
};
bool webp_t::_is_defined_preprocessing_t(webp_t::preprocessing_t v) {
return webp_t::_values_preprocessing_t.find(v) != webp_t::_values_preprocessing_t.end();
}
webp_t::webp_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, webp_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root ? p__root : this;
m_payload = nullptr;
m__io__raw_payload = nullptr;
_read();
}
void webp_t::_read() {
m_magic = m__io->read_bytes(4);
if (!(m_magic == std::string("\x52\x49\x46\x46", 4))) {
throw kaitai::validation_not_equal_error<std::string>(std::string("\x52\x49\x46\x46", 4), m_magic, m__io, std::string("/seq/0"));
}
m_len_data = m__io->read_u4le();
m_webp = m__io->read_bytes(4);
if (!(m_webp == std::string("\x57\x45\x42\x50", 4))) {
throw kaitai::validation_not_equal_error<std::string>(std::string("\x57\x45\x42\x50", 4), m_webp, m__io, std::string("/seq/2"));
}
m__raw_payload = m__io->read_bytes(len_data() - 4);
m__io__raw_payload = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_payload));
m_payload = std::unique_ptr<chunks_t>(new chunks_t(m__io__raw_payload.get(), this, m__root));
}
webp_t::~webp_t() {
_clean_up();
}
void webp_t::_clean_up() {
}
webp_t::alph_t::alph_t(kaitai::kstream* p__io, webp_t::chunk_t* p__parent, webp_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void webp_t::alph_t::_read() {
m_reserved = m__io->read_bits_int_be(2);
if (!(m_reserved == 0)) {
throw kaitai::validation_not_equal_error<uint64_t>(0, m_reserved, m__io, std::string("/types/alph/seq/0"));
}
m_preprocessing = static_cast<webp_t::preprocessing_t>(m__io->read_bits_int_be(2));
if (!webp_t::_is_defined_preprocessing_t(m_preprocessing)) {
throw kaitai::validation_not_in_enum_error<webp_t::preprocessing_t>(m_preprocessing, m__io, std::string("/types/alph/seq/1"));
}
m_filtering = static_cast<webp_t::filtering_method_t>(m__io->read_bits_int_be(2));
m_compression = static_cast<webp_t::compression_method_t>(m__io->read_bits_int_be(2));
if (!webp_t::_is_defined_compression_method_t(m_compression)) {
throw kaitai::validation_not_in_enum_error<webp_t::compression_method_t>(m_compression, m__io, std::string("/types/alph/seq/3"));
}
m__io->align_to_byte();
m_data = m__io->read_bytes_full();
}
webp_t::alph_t::~alph_t() {
_clean_up();
}
void webp_t::alph_t::_clean_up() {
}
webp_t::anim_t::anim_t(kaitai::kstream* p__io, webp_t::chunk_t* p__parent, webp_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_background_color = nullptr;
_read();
}
void webp_t::anim_t::_read() {
m_background_color = std::unique_ptr<bg_color_t>(new bg_color_t(m__io, this, m__root));
m_loop_count = m__io->read_u2le();
}
webp_t::anim_t::~anim_t() {
_clean_up();
}
void webp_t::anim_t::_clean_up() {
}
webp_t::anim_t::bg_color_t::bg_color_t(kaitai::kstream* p__io, webp_t::anim_t* p__parent, webp_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void webp_t::anim_t::bg_color_t::_read() {
m_blue = m__io->read_u1();
m_green = m__io->read_u1();
m_red = m__io->read_u1();
m_alpha = m__io->read_u1();
}
webp_t::anim_t::bg_color_t::~bg_color_t() {
_clean_up();
}
void webp_t::anim_t::bg_color_t::_clean_up() {
}
webp_t::anmf_t::anmf_t(kaitai::kstream* p__io, webp_t::chunk_t* p__parent, webp_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
f_frame_height = false;
f_frame_width = false;
f_frame_x = false;
f_frame_y = false;
_read();
}
void webp_t::anmf_t::_read() {
m_frame_x_div_2 = m__io->read_bits_int_le(24);
m_frame_y_div_2 = m__io->read_bits_int_le(24);
m_frame_width_minus_1 = m__io->read_bits_int_le(24);
m_frame_height_minus_1 = m__io->read_bits_int_le(24);
m_duration = m__io->read_bits_int_le(24);
m_reserved = m__io->read_bits_int_be(6);
if (!(m_reserved == 0)) {
throw kaitai::validation_not_equal_error<uint64_t>(0, m_reserved, m__io, std::string("/types/anmf/seq/5"));
}
m_blending_method = m__io->read_bits_int_be(1);
m_disposal_method = m__io->read_bits_int_be(1);
m__io->align_to_byte();
m_data = m__io->read_bytes_full();
}
webp_t::anmf_t::~anmf_t() {
_clean_up();
}
void webp_t::anmf_t::_clean_up() {
}
int32_t webp_t::anmf_t::frame_height() {
if (f_frame_height)
return m_frame_height;
f_frame_height = true;
m_frame_height = frame_height_minus_1() + 1;
return m_frame_height;
}
int32_t webp_t::anmf_t::frame_width() {
if (f_frame_width)
return m_frame_width;
f_frame_width = true;
m_frame_width = frame_width_minus_1() + 1;
return m_frame_width;
}
int32_t webp_t::anmf_t::frame_x() {
if (f_frame_x)
return m_frame_x;
f_frame_x = true;
m_frame_x = frame_x_div_2() * 2;
return m_frame_x;
}
int32_t webp_t::anmf_t::frame_y() {
if (f_frame_y)
return m_frame_y;
f_frame_y = true;
m_frame_y = frame_y_div_2() * 2;
return m_frame_y;
}
webp_t::chunk_t::chunk_t(kaitai::kstream* p__io, webp_t::chunks_t* p__parent, webp_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m__io__raw_data = nullptr;
_read();
}
void webp_t::chunk_t::_read() {
m_name = static_cast<webp_t::chunk_names_t>(m__io->read_u4le());
if (!webp_t::_is_defined_chunk_names_t(m_name)) {
throw kaitai::validation_not_in_enum_error<webp_t::chunk_names_t>(m_name, m__io, std::string("/types/chunk/seq/0"));
}
m_len_data = m__io->read_u4le();
n_data = true;
switch (name()) {
case webp_t::CHUNK_NAMES_ALPH: {
n_data = false;
m__raw_data = m__io->read_bytes(len_data());
m__io__raw_data = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_data));
m_data = std::unique_ptr<alph_t>(new alph_t(m__io__raw_data.get(), this, m__root));
break;
}
case webp_t::CHUNK_NAMES_ANIM: {
n_data = false;
m__raw_data = m__io->read_bytes(len_data());
m__io__raw_data = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_data));
m_data = std::unique_ptr<anim_t>(new anim_t(m__io__raw_data.get(), this, m__root));
break;
}
case webp_t::CHUNK_NAMES_ANMF: {
n_data = false;
m__raw_data = m__io->read_bytes(len_data());
m__io__raw_data = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_data));
m_data = std::unique_ptr<anmf_t>(new anmf_t(m__io__raw_data.get(), this, m__root));
break;
}
case webp_t::CHUNK_NAMES_VP8: {
n_data = false;
m__raw_data = m__io->read_bytes(len_data());
m__io__raw_data = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_data));
m_data = std::unique_ptr<vp8_t>(new vp8_t(m__io__raw_data.get(), this, m__root));
break;
}
case webp_t::CHUNK_NAMES_VP8L: {
n_data = false;
m__raw_data = m__io->read_bytes(len_data());
m__io__raw_data = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_data));
m_data = std::unique_ptr<vp8l_t>(new vp8l_t(m__io__raw_data.get(), this, m__root));
break;
}
case webp_t::CHUNK_NAMES_VP8X: {
n_data = false;
m__raw_data = m__io->read_bytes(len_data());
m__io__raw_data = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_data));
m_data = std::unique_ptr<vp8x_t>(new vp8x_t(m__io__raw_data.get(), this, m__root));
break;
}
case webp_t::CHUNK_NAMES_XMP: {
n_data = false;
m__raw_data = m__io->read_bytes(len_data());
m__io__raw_data = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_data));
m_data = std::unique_ptr<xmp_t>(new xmp_t(m__io__raw_data.get(), this, m__root));
break;
}
case webp_t::CHUNK_NAMES_XMP_VAR: {
n_data = false;
m__raw_data = m__io->read_bytes(len_data());
m__io__raw_data = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_data));
m_data = std::unique_ptr<xmp_t>(new xmp_t(m__io__raw_data.get(), this, m__root));
break;
}
default: {
m__raw_data = m__io->read_bytes(len_data());
break;
}
}
n_padding = true;
if (kaitai::kstream::mod(len_data(), 2) != 0) {
n_padding = false;
m_padding = m__io->read_bytes(1);
if (!(m_padding == std::string("\x00", 1))) {
throw kaitai::validation_not_equal_error<std::string>(std::string("\x00", 1), m_padding, m__io, std::string("/types/chunk/seq/3"));
}
}
}
webp_t::chunk_t::~chunk_t() {
_clean_up();
}
void webp_t::chunk_t::_clean_up() {
if (!n_data) {
}
if (!n_padding) {
}
}
webp_t::chunks_t::chunks_t(kaitai::kstream* p__io, webp_t* p__parent, webp_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_chunks = nullptr;
_read();
}
void webp_t::chunks_t::_read() {
m_chunks = std::unique_ptr<std::vector<std::unique_ptr<chunk_t>>>(new std::vector<std::unique_ptr<chunk_t>>());
{
int i = 0;
while (!m__io->is_eof()) {
m_chunks->push_back(std::move(std::unique_ptr<chunk_t>(new chunk_t(m__io, this, m__root))));
i++;
}
}
}
webp_t::chunks_t::~chunks_t() {
_clean_up();
}
void webp_t::chunks_t::_clean_up() {
}
webp_t::vp8_t::vp8_t(kaitai::kstream* p__io, webp_t::chunk_t* p__parent, webp_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void webp_t::vp8_t::_read() {
m_frame_type = m__io->read_bits_int_le(1);
if (!(m_frame_type == false)) {
throw kaitai::validation_not_equal_error<bool>(false, m_frame_type, m__io, std::string("/types/vp8/seq/0"));
}
m_version = m__io->read_bits_int_le(3);
if (!(m_version <= 3)) {
throw kaitai::validation_greater_than_error<uint64_t>(3, m_version, m__io, std::string("/types/vp8/seq/1"));
}
m_show_frame = m__io->read_bits_int_le(1);
m_len_first_partition = m__io->read_bits_int_le(19);
m__io->align_to_byte();
m_start_code = m__io->read_bytes(3);
if (!(m_start_code == std::string("\x9D\x01\x2A", 3))) {
throw kaitai::validation_not_equal_error<std::string>(std::string("\x9D\x01\x2A", 3), m_start_code, m__io, std::string("/types/vp8/seq/4"));
}
m_width = m__io->read_bits_int_le(14);
m_horizontal_scale = m__io->read_bits_int_le(2);
m_height = m__io->read_bits_int_le(14);
m_vertical_scale = m__io->read_bits_int_le(2);
m__io->align_to_byte();
m_data = m__io->read_bytes_full();
}
webp_t::vp8_t::~vp8_t() {
_clean_up();
}
void webp_t::vp8_t::_clean_up() {
}
webp_t::vp8l_t::vp8l_t(kaitai::kstream* p__io, webp_t::chunk_t* p__parent, webp_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
f_image_height = false;
f_image_width = false;
_read();
}
void webp_t::vp8l_t::_read() {
m_signature = m__io->read_u1();
if (!(m_signature == 47)) {
throw kaitai::validation_not_equal_error<uint8_t>(47, m_signature, m__io, std::string("/types/vp8l/seq/0"));
}
m_image_width_minus_1 = m__io->read_bits_int_le(14);
m_image_height_minus_1 = m__io->read_bits_int_le(14);
m_alpha_is_used = m__io->read_bits_int_le(1);
m_version_number = m__io->read_bits_int_le(3);
if (!(m_version_number == 0)) {
throw kaitai::validation_not_equal_error<uint64_t>(0, m_version_number, m__io, std::string("/types/vp8l/seq/4"));
}
m__io->align_to_byte();
m_data = m__io->read_bytes_full();
}
webp_t::vp8l_t::~vp8l_t() {
_clean_up();
}
void webp_t::vp8l_t::_clean_up() {
}
int32_t webp_t::vp8l_t::image_height() {
if (f_image_height)
return m_image_height;
f_image_height = true;
m_image_height = image_height_minus_1() + 1;
return m_image_height;
}
int32_t webp_t::vp8l_t::image_width() {
if (f_image_width)
return m_image_width;
f_image_width = true;
m_image_width = image_width_minus_1() + 1;
return m_image_width;
}
webp_t::vp8x_t::vp8x_t(kaitai::kstream* p__io, webp_t::chunk_t* p__parent, webp_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
f_canvas_height = false;
f_canvas_width = false;
_read();
}
void webp_t::vp8x_t::_read() {
m_reserved1 = m__io->read_bits_int_be(2);
if (!(m_reserved1 == 0)) {
throw kaitai::validation_not_equal_error<uint64_t>(0, m_reserved1, m__io, std::string("/types/vp8x/seq/0"));
}
m_icc_profile = m__io->read_bits_int_be(1);
m_alpha = m__io->read_bits_int_be(1);
m_exif = m__io->read_bits_int_be(1);
m_xmp = m__io->read_bits_int_be(1);
m_animation = m__io->read_bits_int_be(1);
m_reserved2 = m__io->read_bits_int_be(1);
if (!(m_reserved2 == false)) {
throw kaitai::validation_not_equal_error<bool>(false, m_reserved2, m__io, std::string("/types/vp8x/seq/6"));
}
m_reserved3 = m__io->read_bits_int_be(24);
if (!(m_reserved3 == 0)) {
throw kaitai::validation_not_equal_error<uint64_t>(0, m_reserved3, m__io, std::string("/types/vp8x/seq/7"));
}
m_canvas_width_minus_1 = m__io->read_bits_int_le(24);
m_canvas_height_minus_1 = m__io->read_bits_int_le(24);
if (!(m_canvas_height_minus_1 <= 4294967295UL / canvas_width() - 1)) {
throw kaitai::validation_greater_than_error<uint64_t>(4294967295UL / canvas_width() - 1, m_canvas_height_minus_1, m__io, std::string("/types/vp8x/seq/9"));
}
}
webp_t::vp8x_t::~vp8x_t() {
_clean_up();
}
void webp_t::vp8x_t::_clean_up() {
}
int32_t webp_t::vp8x_t::canvas_height() {
if (f_canvas_height)
return m_canvas_height;
f_canvas_height = true;
m_canvas_height = canvas_height_minus_1() + 1;
return m_canvas_height;
}
int32_t webp_t::vp8x_t::canvas_width() {
if (f_canvas_width)
return m_canvas_width;
f_canvas_width = true;
m_canvas_width = canvas_width_minus_1() + 1;
return m_canvas_width;
}
webp_t::xmp_t::xmp_t(kaitai::kstream* p__io, webp_t::chunk_t* p__parent, webp_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void webp_t::xmp_t::_read() {
m_data = kaitai::kstream::bytes_to_str(m__io->read_bytes_full(), "UTF-8");
}
webp_t::xmp_t::~xmp_t() {
_clean_up();
}
void webp_t::xmp_t::_clean_up() {
}