uint32_t CXbtFile::GetImageHeight() const { CXBTFFrame frame; if (!GetFirstFrame(frame)) return false; return frame.GetHeight(); }
bool CTextureBundleXBT::ConvertFrameToTexture(const CStdString& name, CXBTFFrame& frame, CBaseTexture** ppTexture) { // found texture - allocate the necessary buffers squish::u8 *buffer = new squish::u8[(size_t)frame.GetPackedSize()]; if (buffer == NULL) { CLog::Log(LOGERROR, "Out of memory loading texture: %s (need %"PRIu64" bytes)", name.c_str(), frame.GetPackedSize()); return false; } // load the compressed texture if (!m_XBTFReader.Load(frame, buffer)) { CLog::Log(LOGERROR, "Error loading texture: %s", name.c_str()); delete[] buffer; return false; } // check if it's packed with lzo if (frame.IsPacked()) { // unpack squish::u8 *unpacked = new squish::u8[(size_t)frame.GetUnpackedSize()]; if (unpacked == NULL) { CLog::Log(LOGERROR, "Out of memory unpacking texture: %s (need %"PRIu64" bytes)", name.c_str(), frame.GetUnpackedSize()); delete[] buffer; return false; } lzo_uint s = (lzo_uint)frame.GetUnpackedSize(); if (lzo1x_decompress(buffer, (lzo_uint)frame.GetPackedSize(), unpacked, &s, NULL) != LZO_E_OK || s != frame.GetUnpackedSize()) { CLog::Log(LOGERROR, "Error loading texture: %s: Decompression error", name.c_str()); delete[] buffer; delete[] unpacked; return false; } delete[] buffer; buffer = unpacked; } // create an xbmc texture *ppTexture = new CTexture(); (*ppTexture)->LoadFromMemory(frame.GetWidth(), frame.GetHeight(), 0, frame.GetFormat(), buffer); delete[] buffer; return true; }
int createBundle(const std::string& InputDir, const std::string& OutputFile, double maxMSE, unsigned int flags, bool dupecheck) { CXBTFWriter writer(OutputFile); if (!writer.Create()) { fprintf(stderr, "Error creating file\n"); return 1; } map<string,unsigned int> hashes; vector<unsigned int> dupes; CreateSkeletonHeader(writer, InputDir); std::vector<CXBTFFile> files = writer.GetFiles(); dupes.resize(files.size()); if (!dupecheck) { for (unsigned int i=0;i<dupes.size();++i) dupes[i] = i; } for (size_t i = 0; i < files.size(); i++) { struct MD5Context ctx; MD5Init(&ctx); CXBTFFile& file = files[i]; std::string fullPath = InputDir; fullPath += file.GetPath(); std::string output = file.GetPath(); output = output.substr(0, 40); while (output.size() < 46) output += ' '; DecodedFrames frames; bool loaded = DecoderManager::LoadFile(fullPath, frames); if (!loaded) { fprintf(stderr, "...unable to load image %s\n", file.GetPath().c_str()); continue; } printf("%s\n", output.c_str()); bool skip=false; if (dupecheck) { for (unsigned int j = 0; j < frames.frameList.size(); j++) MD5Update(&ctx, (const uint8_t*)frames.frameList[j].rgbaImage.pixels, frames.frameList[j].rgbaImage.height * frames.frameList[j].rgbaImage.pitch); if (checkDupe(&ctx,hashes,dupes,i)) { printf("**** duplicate of %s\n", files[dupes[i]].GetPath().c_str()); file.GetFrames().insert(file.GetFrames().end(), files[dupes[i]].GetFrames().begin(), files[dupes[i]].GetFrames().end()); skip = true; } } if (!skip) { for (unsigned int j = 0; j < frames.frameList.size(); j++) { printf(" frame %4i (delay:%4i) ", j, frames.frameList[j].delay); CXBTFFrame frame = createXBTFFrame(frames.frameList[j].rgbaImage, writer, maxMSE, flags); frame.SetDuration(frames.frameList[j].delay); file.GetFrames().push_back(frame); printf("%s%c (%d,%d @ %" PRIu64 " bytes)\n", GetFormatString(frame.GetFormat()), frame.HasAlpha() ? ' ' : '*', frame.GetWidth(), frame.GetHeight(), frame.GetUnpackedSize()); } } DecoderManager::FreeDecodedFrames(frames); file.SetLoop(0); writer.UpdateFile(file); } if (!writer.UpdateHeader(dupes)) { fprintf(stderr, "Error writing header to file\n"); return 1; } if (!writer.Close()) { fprintf(stderr, "Error closing file\n"); return 1; } return 0; }
int createBundle(const std::string& InputDir, const std::string& OutputFile, double maxMSE, unsigned int flags, bool dupecheck) { map<string,unsigned int> hashes; vector<unsigned int> dupes; CXBTF xbtf; CreateSkeletonHeader(xbtf, InputDir); dupes.resize(xbtf.GetFiles().size()); if (!dupecheck) { for (unsigned int i=0;i<dupes.size();++i) dupes[i] = i; } CXBTFWriter writer(xbtf, OutputFile); if (!writer.Create()) { printf("Error creating file\n"); return 1; } std::vector<CXBTFFile>& files = xbtf.GetFiles(); for (size_t i = 0; i < files.size(); i++) { struct MD5Context ctx; MD5Init(&ctx); CXBTFFile& file = files[i]; std::string fullPath = InputDir; fullPath += file.GetPath(); std::string output = file.GetPath(); output = output.substr(0, 40); while (output.size() < 46) output += ' '; if (!IsGIF(fullPath.c_str())) { // Load the image SDL_Surface* image = IMG_Load(fullPath.c_str()); if (!image) { printf("...unable to load image %s\n", file.GetPath()); continue; } bool skip=false; printf("%s", output.c_str()); if (dupecheck) { MD5Update(&ctx,(const uint8_t*)image->pixels,image->h*image->pitch); if (checkDupe(&ctx,hashes,dupes,i)) { printf("**** duplicate of %s\n", files[dupes[i]].GetPath()); file.GetFrames().insert(file.GetFrames().end(), files[dupes[i]].GetFrames().begin(), files[dupes[i]].GetFrames().end()); skip = true; } } if (!skip) { CXBTFFrame frame = createXBTFFrame(image, writer, maxMSE, flags); printf("%s%c (%d,%d @ %"PRIu64" bytes)\n", GetFormatString(frame.GetFormat()), frame.HasAlpha() ? ' ' : '*', frame.GetWidth(), frame.GetHeight(), frame.GetUnpackedSize()); file.SetLoop(0); file.GetFrames().push_back(frame); } SDL_FreeSurface(image); } else { int gnAG = AG_LoadGIF(fullPath.c_str(), NULL, 0); AG_Frame* gpAG = new AG_Frame[gnAG]; AG_LoadGIF(fullPath.c_str(), gpAG, gnAG); printf("%s\n", output.c_str()); bool skip=false; if (dupecheck) { for (int j = 0; j < gnAG; j++) MD5Update(&ctx, (const uint8_t*)gpAG[j].surface->pixels, gpAG[j].surface->h * gpAG[j].surface->pitch); if (checkDupe(&ctx,hashes,dupes,i)) { printf("**** duplicate of %s\n", files[dupes[i]].GetPath()); file.GetFrames().insert(file.GetFrames().end(), files[dupes[i]].GetFrames().begin(), files[dupes[i]].GetFrames().end()); skip = true; } } if (!skip) { for (int j = 0; j < gnAG; j++) { printf(" frame %4i ", j); CXBTFFrame frame = createXBTFFrame(gpAG[j].surface, writer, maxMSE, flags); frame.SetDuration(gpAG[j].delay); file.GetFrames().push_back(frame); printf("%s%c (%d,%d @ %"PRIu64" bytes)\n", GetFormatString(frame.GetFormat()), frame.HasAlpha() ? ' ' : '*', frame.GetWidth(), frame.GetHeight(), frame.GetUnpackedSize()); } } AG_FreeSurfaces(gpAG, gnAG); delete [] gpAG; file.SetLoop(0); } } if (!writer.UpdateHeader(dupes)) { printf("Error writing header to file\n"); return 1; } if (!writer.Close()) { printf("Error closing file\n"); return 1; } return 0; }