fix utf-16 reading and make it work on android

This commit is contained in:
2019-02-10 20:55:26 +01:00
parent 1d6c26f2ba
commit 6e41263600
9 changed files with 95 additions and 26 deletions

View File

@@ -31,6 +31,7 @@ add_library(
../libs/poly2tri/poly2tri/sweep/cdt.cc ../libs/poly2tri/poly2tri/sweep/cdt.cc
../libs/poly2tri/poly2tri/sweep/sweep_context.cc ../libs/poly2tri/poly2tri/sweep/sweep_context.cc
../libs/poly2tri/poly2tri/sweep/sweep.cc ../libs/poly2tri/poly2tri/sweep/sweep.cc
../libs/fmt/src/format.cc
src/main/cpp/main.cpp src/main/cpp/main.cpp
../src/pch.cpp ../src/pch.cpp
../src/util.cpp ../src/util.cpp
@@ -91,6 +92,7 @@ add_library(
../src/node_usermanual.cpp ../src/node_usermanual.cpp
../src/node_viewport.cpp ../src/node_viewport.cpp
../src/node_scroll.cpp ../src/node_scroll.cpp
../src/abr.cpp
) )
target_include_directories(native-lib PRIVATE target_include_directories(native-lib PRIVATE
@@ -107,6 +109,8 @@ target_include_directories(native-lib PRIVATE
../libs/sqlite3 ../libs/sqlite3
../libs/nanort ../libs/nanort
../libs/native_app_glue ../libs/native_app_glue
../libs/hash-library
../libs/fmt/include
) )
# add lib dependencies # add lib dependencies

View File

@@ -94,7 +94,7 @@ public class MainActivity extends NativeActivity {
} }
// patterns // patterns
File patterns = new File(pano_dir.getAbsolutePath(), "brushes"); File patterns = new File(pano_dir.getAbsolutePath(), "patterns");
if (!patterns.exists()) if (!patterns.exists())
{ {
if (patterns.mkdirs()) if (patterns.mkdirs())

View File

@@ -1,5 +1,6 @@
#include "pch.h" #include "pch.h"
#include "abr.h" #include "abr.h"
#include "log.h"
bool ABR::section_desc() bool ABR::section_desc()
{ {
@@ -20,7 +21,11 @@ bool ABR::section_desc()
m_presets.push_back(desc); m_presets.push_back(desc);
} }
auto out = presets->str(0, ""); auto out = presets->str(0, "");
std::cout << out << '\n'; auto lines = split(out, '\n');
for (const auto& l : lines)
{
LOG("%s", l.c_str());
}
} }
return true; return true;
} }
@@ -63,7 +68,7 @@ bool ABR::section_patt()
auto image_mode = ru32(); auto image_mode = ru32();
if (!(image_mode == 1 || image_mode == 3)) if (!(image_mode == 1 || image_mode == 3))
{ {
printf("PATT: skip image mode %d\n", image_mode); LOG("PATT: skip image mode %d\n", image_mode);
skip(patt_length - 8); skip(patt_length - 8);
snap(); snap();
continue; continue;
@@ -83,7 +88,7 @@ bool ABR::section_patt()
int nc = std::min((int)vm->channels.size(), 3); int nc = std::min((int)vm->channels.size(), 3);
if (nc != image_mode) if (nc != image_mode)
{ {
printf("PATT: image_mode (%d) and number of channels (%d) not matching\n", LOG("PATT: image_mode (%d) and number of channels (%d) not matching\n",
image_mode, vm->channels.size()); image_mode, vm->channels.size());
} }
if (auto img = vm->image(true)) if (auto img = vm->image(true))
@@ -135,12 +140,13 @@ std::vector<std::shared_ptr<Brush>> ABR::compute_brushes(const std::string& path
//b->m_blend_mode = i.m_blend_mode; //b->m_blend_mode = i.m_blend_mode;
//b->m_name.resize(i.m_name_len); //b->m_name.resize(i.m_name_len);
//b->m_stencil_path.resize(i.m_stencil_path_len); //b->m_stencil_path.resize(i.m_stencil_path_len);
auto& tip_uid = wstr2str(samp->value<String>("sampledData")); auto tip_uid = wstr2str(samp->value<String>("sampledData"));
LOG("tip uid %d %s", tip_uid.size(), tip_uid.c_str());
b->m_brush_path = path + "/brushes/" + tip_uid + ".png"; b->m_brush_path = path + "/brushes/" + tip_uid + ".png";
b->m_brush_thumb_path = path + "/brushes/thumbs/" + tip_uid + ".png"; b->m_brush_thumb_path = path + "/brushes/thumbs/" + tip_uid + ".png";
if (auto patt = p->get<Descriptor>("Txtr")) if (auto patt = p->get<Descriptor>("Txtr"))
{ {
auto& patt_uid = wstr2str(patt->value<String>("Idnt")); auto patt_uid = wstr2str(patt->value<String>("Idnt"));
b->m_stencil_path = path + "/patterns/" + patt_uid + ".png"; b->m_stencil_path = path + "/patterns/" + patt_uid + ".png";
//b->m_brush_thumb_path = path + "/patterns/thumbs/" + patt_uid + ".png"; //b->m_brush_thumb_path = path + "/patterns/thumbs/" + patt_uid + ".png";
b->m_tip_stencil = p->value<UnitFloat>("textureDepth") * 0.01f; b->m_tip_stencil = p->value<UnitFloat>("textureDepth") * 0.01f;
@@ -179,7 +185,7 @@ std::shared_ptr<ABR::VMArray> ABR::parse_vmem()
auto compression = ru8(); // 1 = zip auto compression = ru8(); // 1 = zip
if (depth != 8) if (depth != 8)
{ {
printf("unsupported depth %d bits\n", depth); LOG("unsupported depth %d bits\n", depth);
skip(length - 23); skip(length - 23);
continue; continue;
} }
@@ -208,7 +214,7 @@ std::shared_ptr<ABR::VMArray> ABR::parse_vmem()
} }
else else
{ {
printf("unsupported compression mode %d\n", compression); LOG("unsupported compression mode %d\n", compression);
skip(length - 23); skip(length - 23);
continue; continue;
} }
@@ -257,7 +263,7 @@ std::shared_ptr<ABR::Descriptor> ABR::parse_objc()
if (!property) if (!property)
return nullptr; return nullptr;
if (ret->props.find(key) != ret->props.end()) if (ret->props.find(key) != ret->props.end())
printf("DUPLICATE prop %d\n", key.c_str()); LOG("DUPLICATE prop %d\n", key.c_str());
ret->props[key] = property; ret->props[key] = property;
} }
return ret; return ret;
@@ -336,7 +342,7 @@ bool ABR::open(const std::string& path)
init(asset.read_all(), asset.m_len, BinaryStream::ByteOrder::BigEndian); init(asset.read_all(), asset.m_len, BinaryStream::ByteOrder::BigEndian);
auto version_major = ru16(); auto version_major = ru16();
auto version_minor = ru16(); auto version_minor = ru16();
printf("ABR %d.%d\n", version_major, version_minor); LOG("ABR %d.%d\n", version_major, version_minor);
while (!eof()) while (!eof())
{ {
if (rstring(4) != "8BIM") if (rstring(4) != "8BIM")
@@ -356,7 +362,7 @@ bool ABR::open(const std::string& path)
} }
else else
{ {
printf("skip section %s\n", t.c_str()); LOG("skip section %s\n", t.c_str());
skip(align4(ru32())); skip(align4(ru32()));
} }
} }

View File

@@ -5,6 +5,7 @@
#include "util.h" #include "util.h"
#include "image.h" #include "image.h"
#include "brush.h" #include "brush.h"
#include "log.h"
class BinaryStream class BinaryStream
{ {
@@ -19,7 +20,7 @@ public:
return bint.c[0] == 1 ? ByteOrder::BigEndian : ByteOrder::LittleEndian; return bint.c[0] == 1 ? ByteOrder::BigEndian : ByteOrder::LittleEndian;
} }
BinaryStream(const BinaryParam&) = delete; BinaryStream(const BinaryStream&) = delete;
BinaryStream() = default; BinaryStream() = default;
~BinaryStream() ~BinaryStream()
{ {
@@ -66,13 +67,17 @@ public:
std::wstring rwstring(size_t len) std::wstring rwstring(size_t len)
{ {
auto ptr = advance<char>(len * 2); auto ptr = advance<char>(len * 2);
for (int i = 0; i < len; i++) //for (int i = 0; i < len; i++)
std::swap(ptr[i * 2], ptr[i * 2 + 1]); // std::swap(ptr[i * 2], ptr[i * 2 + 1]);
// right trim trailing zeroes // right trim trailing zeroes
auto wptr = (wchar_t*)ptr; auto wptr = (uint16_t*)ptr;
for (int i = len - 1; i >= 0; i--) for (int i = len - 1; i >= 0; i--)
if (wptr[i] == 0) len--; if (wptr[i] == 0) len--;
return std::wstring(wptr, len);
// wide to UTF-16le
std::wstring_convert<std::codecvt_utf16<wchar_t, 0x10ffff>> converter;
return converter.from_bytes(ptr, ptr + len * 2);
} }
std::string rpascal() std::string rpascal()
{ {
@@ -168,7 +173,7 @@ protected:
return *reinterpret_cast<T*>(&y); return *reinterpret_cast<T*>(&y);
} }
#else #else
auto p = reinterpret_cast<uint16_t*>(&x); auto p = reinterpret_cast<uint8_t*>(&x);
if (sizeof(T) == 2) if (sizeof(T) == 2)
{ {
std::swap(p[0], p[1]); std::swap(p[0], p[1]);
@@ -347,7 +352,7 @@ class ABR : private BinaryStream
uint8_t compression; uint8_t compression;
std::vector<uint8_t> data; std::vector<uint8_t> data;
Channel() = default; Channel() = default;
Channel(uint32_t depth, const Rectangle& rect, uint8_t compression, std::vector<uint8_t>& data) : Channel(uint32_t depth, Rectangle rect, uint8_t compression, std::vector<uint8_t> data) :
depth(depth), rect(rect), compression(compression), data(std::move(data)) { } depth(depth), rect(rect), compression(compression), data(std::move(data)) { }
}; };
struct VMArray : public Type struct VMArray : public Type

View File

@@ -98,7 +98,7 @@ void App::pick_file(std::vector<std::string> types, std::function<void (std::str
callback(path); callback(path);
}); });
#elif __ANDROID__ #elif __ANDROID__
//android_pick_file(and_app, callback); android_pick_file(and_app, callback);
#elif _WIN32 #elif _WIN32
std::string filter = "Supported Files ("; std::string filter = "Supported Files (";
bool first_type = true; bool first_type = true;

View File

@@ -139,13 +139,25 @@ bool Asset::open(const char* path)
m_current_path = path; m_current_path = path;
std::string file_path = path; std::string file_path = path;
#ifdef __ANDROID__ #ifdef __ANDROID__
if (!(m_asset = AAssetManager_open(m_am, path, AASSET_MODE_RANDOM))) if (is_asset(path))
{ {
LOG("AAssetManager_open failed %s", path); if (!(m_asset = AAssetManager_open(m_am, path, AASSET_MODE_RANDOM)))
return false; {
LOG("AAssetManager_open failed %s", path);
return false;
}
}
else
{
if (!(m_fp = fopen(file_path.c_str(), "rb")))
{
LOG("asset open errno = %d, %s", errno, path);
return false;
}
fseek(m_fp, 0, SEEK_END);
m_len = (int)ftell(m_fp);
fseek(m_fp, 0, SEEK_SET);
} }
m_len = (int)AAsset_getLength(m_asset);
m_data = (uint8_t*)AAsset_getBuffer(m_asset);
#else #else
#ifdef __APPLE__ #ifdef __APPLE__
NSString* bundle_path = [[NSBundle mainBundle] resourcePath]; NSString* bundle_path = [[NSBundle mainBundle] resourcePath];
@@ -168,6 +180,24 @@ bool Asset::open(const char* path)
glm::uint8_t* Asset::read_all() glm::uint8_t* Asset::read_all()
{ {
#ifdef __ANDROID__ #ifdef __ANDROID__
if (!m_data)
{
if (is_asset(m_current_path))
{
m_len = (int)AAsset_getLength(m_asset);
m_data = (uint8_t*)AAsset_getBuffer(m_asset);
}
else
{
m_data = new uint8_t[m_len];
if (m_len != fread(m_data, 1, m_len, m_fp))
{
LOG("ASSET READ FAILED for %s", m_current_path.c_str());
delete[] m_data;
m_data = nullptr;
}
}
}
return m_data; return m_data;
#else #else
if (!m_data) if (!m_data)

View File

@@ -286,7 +286,11 @@ bool Brush::load()
{ {
m_tip_texture = std::make_shared<Texture2D>(); m_tip_texture = std::make_shared<Texture2D>();
if (!m_tip_texture->load(m_brush_path)) if (!m_tip_texture->load(m_brush_path))
{
LOG("failed to load %s", m_brush_path.c_str());
m_tip_texture = nullptr;
return false; return false;
}
m_tip_texture->create_mipmaps(); m_tip_texture->create_mipmaps();
m_tip_texture->auto_destroy = true; m_tip_texture->auto_destroy = true;
} }
@@ -294,7 +298,12 @@ bool Brush::load()
{ {
m_stencil_texture = std::make_shared<Texture2D>(); m_stencil_texture = std::make_shared<Texture2D>();
if (!m_stencil_texture->load(m_stencil_path)) if (!m_stencil_texture->load(m_stencil_path))
{
LOG("failed to load %s", m_stencil_path.c_str());
m_tip_texture = nullptr;
m_stencil_texture = nullptr;
return false; return false;
}
m_stencil_texture->create_mipmaps(); m_stencil_texture->create_mipmaps();
m_stencil_texture->auto_destroy = true; m_stencil_texture->auto_destroy = true;
} }

View File

@@ -41,7 +41,10 @@ bool Image::load_file(std::string filename)
bool Image::save(const std::string& path) bool Image::save(const std::string& path)
{ {
return stbi_write_png(path.c_str(), width, height, comp, data(), 0); bool ret = stbi_write_png(path.c_str(), width, height, comp, data(), 0);
if (!ret)
LOG("failed Image::save %s", path.c_str());
return ret;
} }
void Image::flip() void Image::flip()

View File

@@ -65,7 +65,14 @@ void NodePanelBrush::init()
if (str_iequals(ext, "abr")) if (str_iequals(ext, "abr"))
{ {
ABR abr; ABR abr;
abr.open(path); LOG("ABR detected");
if (!abr.open(path))
{
LOG("ABR read failed");
return;
}
for (const auto& samp : abr.m_samples) for (const auto& samp : abr.m_samples)
{ {
std::string path_high = App::I.data_path + "/brushes/" + samp.first + ".png"; std::string path_high = App::I.data_path + "/brushes/" + samp.first + ".png";
@@ -101,8 +108,13 @@ void NodePanelBrush::init()
for (const auto& pr : brushes) for (const auto& pr : brushes)
{ {
auto presets = App::I.stroke->m_presets_popup; auto presets = App::I.stroke->m_presets_popup;
async_start();
if (pr->load()) if (pr->load())
{
LOG("add preset %s", pr->m_name.c_str());
presets->add_brush(pr); presets->add_brush(pr);
}
async_end();
} }
//save(); //save();
} }