add ABR brushes and presets with properties and patterns
This commit is contained in:
155
src/abr.cpp
155
src/abr.cpp
@@ -4,15 +4,24 @@
|
||||
bool ABR::section_desc()
|
||||
{
|
||||
auto sz = align4(ru32());
|
||||
auto n1 = ri32(); // some integer
|
||||
auto s = rwstring(); // maybe a string
|
||||
auto n1 = ri32(); // some integer
|
||||
auto s = rwstring(); // maybe a string
|
||||
auto null = rkey_or_string();
|
||||
auto null_val = ri32(); // integer following the null
|
||||
auto name = rkey_or_string();
|
||||
auto list = rstring(4);
|
||||
auto list_val = call(list);
|
||||
auto out = list_val->str(0, "");
|
||||
std::cout << out;
|
||||
auto null_val = ri32(); // integer following the null
|
||||
|
||||
// presets list
|
||||
auto name = rkey_or_string(); // "Brsh"
|
||||
auto list = rstring(4); // "VlLs"
|
||||
if (auto presets = std::dynamic_pointer_cast<List>(call(list)))
|
||||
{
|
||||
for (auto const& pr : presets->items)
|
||||
{
|
||||
if (auto desc = std::dynamic_pointer_cast<Descriptor>(pr))
|
||||
m_presets.push_back(desc);
|
||||
}
|
||||
auto out = presets->str(0, "");
|
||||
std::cout << out << '\n';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -25,30 +34,16 @@ bool ABR::section_samp()
|
||||
{
|
||||
auto samp_size = ru32();
|
||||
auto uid = rpascal();
|
||||
printf("sample brush %s\n", uid.c_str());
|
||||
skip(4);
|
||||
auto image = parse_vmem();
|
||||
if (image->channels.size() >= 3)
|
||||
//printf("sample brush %s\n", uid.c_str());
|
||||
skip(4); // unknown bytes usually 00 01 00 00
|
||||
auto vm = parse_vmem();
|
||||
if (vm)
|
||||
{
|
||||
std::vector<glm::u8vec3> out((image->channels[0].depth >> 3) * image->rect.area());
|
||||
for (int ch = 0; ch < 3; ch++)
|
||||
if (auto img = vm->image(true))
|
||||
{
|
||||
auto const& raw = image->channels[ch].data;
|
||||
for (int i = 0; i < raw.size(); i++)
|
||||
out[i][ch] = raw[i];
|
||||
// TODO: check if uid already exists in map
|
||||
m_samples[uid] = img;
|
||||
}
|
||||
stbi_write_png(fmt::format("x64/out/{}.png", uid).c_str(),
|
||||
image->rect.width(), image->rect.height(), 3, out.data(), 0);
|
||||
}
|
||||
else if (image->channels.size() == 1)
|
||||
{
|
||||
stbi_write_png(fmt::format("x64/out/{}.png", uid).c_str(),
|
||||
image->rect.width(), image->rect.height(), 1,
|
||||
std::data(image->channels[0].data), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error cannot read image of %d channels\n", image->channels.size());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -68,7 +63,7 @@ bool ABR::section_patt()
|
||||
auto image_mode = ru32();
|
||||
if (!(image_mode == 1 || image_mode == 3))
|
||||
{
|
||||
printf("skip image mode %d\n", image_mode);
|
||||
printf("PATT: skip image mode %d\n", image_mode);
|
||||
skip(patt_length - 8);
|
||||
snap();
|
||||
continue;
|
||||
@@ -82,48 +77,94 @@ bool ABR::section_patt()
|
||||
// read(...);
|
||||
// no worries indexed is skipped anyway
|
||||
|
||||
auto image = parse_vmem();
|
||||
if (image_mode == 3)
|
||||
auto vm = parse_vmem();
|
||||
if (vm)
|
||||
{
|
||||
if (image->channels.size() >= 3)
|
||||
int nc = std::min((int)vm->channels.size(), 3);
|
||||
if (nc != image_mode)
|
||||
{
|
||||
std::vector<glm::u8vec3> out((image->channels[0].depth >> 3) * image->rect.area());
|
||||
for (int ch = 0; ch < 3; ch++)
|
||||
{
|
||||
auto const& raw = image->channels[ch].data;
|
||||
for (int i = 0; i < raw.size(); i++)
|
||||
out[i][ch] = raw[i];
|
||||
}
|
||||
stbi_write_png(fmt::format("x64/out/{}.png", uid).c_str(),
|
||||
image->rect.width(), image->rect.height(), 3, out.data(), 0);
|
||||
printf("PATT: image_mode (%d) and number of channels (%d) not matching\n",
|
||||
image_mode, vm->channels.size());
|
||||
}
|
||||
else
|
||||
if (auto img = vm->image(true))
|
||||
{
|
||||
printf("Error image mode is 3 but channels are only %d\n", image->channels.size());
|
||||
// TODO: check if uid already exists in map
|
||||
m_patterns[uid] = img;
|
||||
}
|
||||
}
|
||||
else if (image_mode == 1)
|
||||
{
|
||||
stbi_write_png(fmt::format("x64/out/{}.png", uid).c_str(),
|
||||
image->rect.width(), image->rect.height(), 1,
|
||||
std::data(image->channels[0].data), 0);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<ABR::Image> ABR::parse_vmem()
|
||||
std::vector<std::shared_ptr<Brush>> ABR::compute_brushes(const std::string& path)
|
||||
{
|
||||
std::vector<std::shared_ptr<Brush>> ret;
|
||||
for (auto const& p : m_presets)
|
||||
{
|
||||
auto samp = p->get<Descriptor>("Brsh");
|
||||
if (samp->class_id != "sampledBrush")
|
||||
continue;
|
||||
auto b = std::make_shared<Brush>();
|
||||
b->m_name = wstr2str(p->value<String>("Nm "));
|
||||
//b->m_tip_color = i.m_tip_color;
|
||||
b->m_tip_size = samp->value<UnitFloat>("Dmtr") / (800.f * 4.f);
|
||||
b->m_tip_spacing = samp->value<UnitFloat>("Spcn") * 0.01f;
|
||||
b->m_tip_flow = .25f;
|
||||
b->m_tip_opacity = 1.f;
|
||||
b->m_tip_angle = glm::radians(samp->value<UnitFloat>("Angl"));
|
||||
//b->m_tip_mix = i.m_tip_mix;
|
||||
//b->m_tip_stencil = i.m_tip_stencil;
|
||||
b->m_tip_wet = p->value<UnitFloat>("Wtdg");
|
||||
b->m_tip_noise = (float)samp->value<UnitFloat>("Nose");
|
||||
//b->m_tip_hue = i.m_tip_hue;
|
||||
//b->m_tip_sat = i.m_tip_sat;
|
||||
//b->m_tip_val = i.m_tip_val;
|
||||
//b->m_tip_angle_follow = i.m_tip_angle_follow;
|
||||
//b->m_tip_flow_pressure = i.m_tip_flow_pressure;
|
||||
//b->m_tip_size_pressure = i.m_tip_size_pressure;
|
||||
//b->m_tip_hue_pressure = i.m_tip_hue_pressure;
|
||||
//b->m_tip_sat_pressure = i.m_tip_sat_pressure;
|
||||
//b->m_tip_val_pressure = i.m_tip_val_pressure;
|
||||
//b->m_jitter_scale = i.m_jitter_scale;
|
||||
//b->m_jitter_angle = i.m_jitter_angle;
|
||||
//b->m_jitter_spread = i.m_jitter_spread;
|
||||
//b->m_jitter_flow = i.m_jitter_flow;
|
||||
//b->m_jitter_hue = i.m_jitter_hue;
|
||||
//b->m_jitter_sat = i.m_jitter_sat;
|
||||
//b->m_jitter_val = i.m_jitter_val;
|
||||
//b->m_blend_mode = i.m_blend_mode;
|
||||
//b->m_name.resize(i.m_name_len);
|
||||
//b->m_stencil_path.resize(i.m_stencil_path_len);
|
||||
auto& tip_uid = wstr2str(samp->value<String>("sampledData"));
|
||||
b->m_brush_path = path + "/brushes/" + tip_uid + ".png";
|
||||
b->m_brush_thumb_path = path + "/brushes/thumbs/" + tip_uid + ".png";
|
||||
if (auto patt = p->get<Descriptor>("Txtr"))
|
||||
{
|
||||
auto& patt_uid = wstr2str(patt->value<String>("Idnt"));
|
||||
b->m_stencil_path = path + "/patterns/" + patt_uid + ".png";
|
||||
//b->m_brush_thumb_path = path + "/patterns/thumbs/" + patt_uid + ".png";
|
||||
b->m_tip_stencil = p->value<UnitFloat>("textureDepth") * 0.01f;
|
||||
}
|
||||
ret.push_back(b);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::shared_ptr<ABR::VMArray> ABR::parse_vmem()
|
||||
{
|
||||
// Virtual Memory Array List
|
||||
auto vmem_version = ru32(); // = 3
|
||||
assert(vmem_version == 3);
|
||||
auto vmem_length = ru32();
|
||||
// TODO: check if at the end there's good data
|
||||
// check if the bounds are within the parent's size
|
||||
auto vmem_rect = rrect();
|
||||
auto vmem_channels = ru32();
|
||||
// The following is a virtual memory array,
|
||||
// repeated for the number of channels
|
||||
// + one for a user mask + one for a sheet mask.
|
||||
vmem_channels += 2; // user and sheet mask
|
||||
auto ret = std::make_shared<Image>(vmem_version, vmem_rect);
|
||||
auto ret = std::make_shared<VMArray>(vmem_version, vmem_rect);
|
||||
for (int ch = 0; ch < vmem_channels; ch++)
|
||||
{
|
||||
auto array_written = ru32(); // skip if 0
|
||||
@@ -200,14 +241,6 @@ std::shared_ptr<ABR::String> ABR::parse_text()
|
||||
return ret;
|
||||
}
|
||||
|
||||
//ABR::Type::Ref ABR::parse_prop()
|
||||
//{
|
||||
// auto name = rstring(4);
|
||||
// //printf("prop type %s\n", t.c_str());
|
||||
// if (!call(name))
|
||||
// return false;
|
||||
//}
|
||||
|
||||
std::shared_ptr<ABR::Descriptor> ABR::parse_objc()
|
||||
{
|
||||
auto ret = std::make_shared<Descriptor>();
|
||||
@@ -297,7 +330,6 @@ ABR::ABR()
|
||||
|
||||
bool ABR::open(const std::string& path)
|
||||
{
|
||||
m_parser_table[""] = std::bind(&ABR::parse_bool, this);
|
||||
Asset asset;
|
||||
if (asset.open(path.c_str()))
|
||||
{
|
||||
@@ -328,6 +360,7 @@ bool ABR::open(const std::string& path)
|
||||
skip(align4(ru32()));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user