void PackToBin::PackPage(const std::string& filepath, const Page& page, const ee::TexturePacker& tp, bool compress) { #ifdef DEBUG_PACK_BIN std::vector<int> list0, list1; int tot_sz = 0; #endif // DEBUG_PACK_BIN int out_sz = 0; const std::vector<PackNode*>& nodes = page.GetNodes(); for (int i = 0, n = nodes.size(); i < n; ++i) { #ifdef DEBUG_PACK_BIN tot_sz += page.GetNodes()[i]->SizeOfPackToBin(); list0.push_back(tot_sz); #endif // DEBUG_PACK_BIN out_sz += nodes[i]->SizeOfPackToBin(); } uint8_t* buf = new uint8_t[out_sz]; uint8_t* ptr = buf; for (int i = 0, n = nodes.size(); i < n; ++i) { nodes[i]->PackToBin(&ptr, tp); #ifdef DEBUG_PACK_BIN list1.push_back(ptr - buf); #endif // DEBUG_PACK_BIN } assert(ptr - buf == out_sz); std::locale::global(std::locale("")); std::ofstream fout(filepath.c_str(), std::ios::binary); std::locale::global(std::locale("C")); if (compress) { uint8_t* dst = NULL; size_t dst_sz; erespacker::Lzma::Compress(&dst, &dst_sz, buf, out_sz); if (dst_sz > 0) { fout.write(reinterpret_cast<const char*>(&dst_sz), sizeof(dst_sz)); fout.write(reinterpret_cast<const char*>(dst), dst_sz); } } else { int32_t sz = -(int)out_sz; fout.write(reinterpret_cast<const char*>(&sz), sizeof(out_sz)); fout.write(reinterpret_cast<const char*>(buf), out_sz); } delete[] buf; fout.close(); }
void PackToBin::Pack(const std::string& filepath, const ee::TexturePacker& tp, bool compress, float scale) { std::set<int> ref_pkgs; uint32_t default_sym_id = 0xffffffff; const std::string default_sym_path = ee::ImageDataMgr::Instance()->GetDefaultSym(); if (!default_sym_path.empty()) { int pkg_id, node_id; PackIDMgr::Instance()->QueryID(default_sym_path, pkg_id, node_id, true); default_sym_id = simp::NodeID::ComposeID(pkg_id, node_id); } // src nodes std::vector<PackNode*> nodes; PackNodeFactory::Instance()->FetchAll(nodes); std::vector<PackNode*>::iterator itr = nodes.begin(); for ( ; itr != nodes.end(); ) { PackNode* node = *itr; if (!PackIDMgr::Instance()->IsCurrPkg(node)) { ref_pkgs.insert(node->GetPkgID()); itr = nodes.erase(itr); } else { if (default_sym_id != 0xffffffff && default_sym_id == node->GetID() && default_sym_path != node->GetFilepath()) { itr = nodes.erase(itr); } else { ++itr; } } } if (nodes.empty()) { return; } std::sort(nodes.begin(), nodes.end(), PackNodeCmp()); // to pages std::vector<Page*> pages; Page* page = new Page(simp::SIMP_PAGE_SIZE); int page_sz = ALIGN_4BYTE(simp::Page::Size()); for (int i = 0, n = nodes.size(); i < n; ++i) { PackNode* node = nodes[i]; int sz = node->SizeOfUnpackFromBin(); while (true) { // head sz int num; auto& page_nodes = page->GetNodes(); if (page_nodes.empty()) { num = 1; } else { num = node->GetID() - page_nodes[0]->GetID() + 1; } int align_n = ALIGN_4BYTE(num); int head_sz = sizeof(uint8_t) * align_n + // types simp::SIZEOF_POINTER * num; // nodes if (page_sz + head_sz + sz <= page->GetSize()) { page_sz += sz; page->Add(node); break; } if (page->NodeNum() > 0) { page->Condense(page_sz + head_sz); pages.push_back(page); page = new Page(simp::SIMP_PAGE_SIZE); page_sz = ALIGN_4BYTE(simp::Page::Size()); } else { page->Enlarge(); } } } if (page->NodeNum() > 0) { // head sz auto& page_nodes = page->GetNodes(); int num = page_nodes.back()->GetID() - page_nodes.front()->GetID() + 1; int align_n = ALIGN_4BYTE(num); int head_sz = sizeof(uint8_t) * align_n + // types simp::SIZEOF_POINTER * num; // nodes page->Condense(page_sz + head_sz); pages.push_back(page); } // pack index PageIndex(filepath + ".epe", pages, compress, scale, ref_pkgs); // pack pages for (int i = 0, n = pages.size(); i < n; ++i) { std::string path = filepath + "." + ee::StringHelper::ToString(i + 1) + ".epe"; PackPage(path, *pages[i], tp, compress); } }